vue3 blocks tree does not "reload" when changing the data - javascript

I am looking for a organization chart plugin for vue 3 and I have found only this one
https://github.com/megafetis/vue3-blocks-tree
The issue that I have is when changing the ref treeData variable the chart is not loading the new structure.
I want to dynamic load the chart. When fetch the data the chart to loads the new data and display it.
Here is the codesandbox example:
https://codesandbox.io/s/flamboyant-gwen-o8vp9?file=/src/App.vue
When press the Add ... the treeData reference variable should load the new data and the chart to display it ... but it doesn't.
Any ideas ?
Should I reload the component on every fetch ?

Try to use documented way make treeData reactive.
Replace ref to reactive for treeDate definition.
Change parts of treeData on onAddData instead replacing all object.
Full changed example:
import { reactive } from "vue";
import VueBlocksTree from "vue3-blocks-tree";
import "vue3-blocks-tree/dist/vue3-blocks-tree.css";
export default {
name: "Diagram",
components: { VueBlocksTree },
setup() {
let treeData = reactive({
label: "root",
children: [
{ label: "child 1" },
{ label: "child 2" },
{
label: "subparent 1",
children: [
{ label: "subchild 1" },
{
label: "subchild 2",
children: [{ label: "subchild 11" }, { label: "subchild 22" }],
},
],
},
],
});
// let treeData = ref({});
const onAddData = () => {
Object.assign(treeData, { label: "Test", children: [{ label: "Test 1" }, { label: "Test 2" }] });
};
return {
treeData,
onAddData,
};
},
};
UPD: Change code on onAddData by adding Object.assign.

Related

How can I modify and extend properties of an object located in useState Array?

I'm a react.js beginner, searching for methods to alter my data structure. For example, I want to push new objects into the children-array or remove them by key.
What is the appropriate way to do that?
const [treeData, setTreeData] = useState([
{
title: "parent 1",
key: "0-0",
icon: <UserAddOutlined />,
children: [
{
title: "parent 1-0",
key: "0-0-0",
icon: <UserAddOutlined />,
children: [
{
title: "leaf",
key: "0-0-0-0",
icon: <UserAddOutlined />,
},
{
title: "leaf",
key: "0-0-0-1",
icon: <UserAddOutlined />,
},
],
},
{
title: "parent 1-1",
key: "0-0-1",
icon: <UserAddOutlined />,
children: [
{
title: "sss",
key: "0-0-1-0",
icon: <UserAddOutlined />,
},
],
},
],
},
]);
So you should not update the state directly. It is not allowed.
Maybe where you are receiving data from, suppose via api and the data is response.payload.data etc.
So in your case use the setTreeData(response.payload.data) method to add stuff in it.
Now if you want to update certain value (remove or update using index etc). Obviously you will have to have index somehow.
So for deleting say you will have some click and against that a handler for it
removeItem(e) {
item_to_remove = e.target..... etc // to get the item's reference for matching
setTreeData(treeData.filter(items => item.<someproperty> != item_to_remove))
// In your case could also be targetting children maybe
// setTreeData(treeData.Children.filter(items => item.<someproperty> != item_to_remove))
}
I would say maybe handle childrens' array inside another useState variable (childrenTreeData maybe). But you will have to look it's feasibility too. Just an idea after seeing your data
JUST for INFO
This is something similar I did for updating prices inside each cards in my project
const getCurrentPrice = useCallback(() => { // <======= maybe you do not need this
const updatedTilesData = tilesData.map((tile: any) => {
return {
...tile, // <======= get everything here and then update the price below for item
currentPrice: calculateDNCurrentPrice(
tile.startingPrice,
tile.dnTimestamp
),
};
});
setTilesData(updatedTilesData);
}, [tilesData]);

Nested set tree view data structure using with recursing and traversal techniques in MongoDB or JavaScript

Hey I'm trying to implement nested drag&drop within re-order sequencesin my MERN app. I working to find ideal approach for mongodb data model and implement to Lexicographic order or linked lists for infinite sub folders. I used Model Tree Structures in this link but every node have limitless children for that require recursion and recursive functions or currying. Documentations not clear enough for make do that.
I want show all tree once and not sohuld appear after than click to arrow icon.There is my doodles for front side generation that working with only one depth such like graph nodes. Maybe Modified Preorder Tree Traversal implementation examples you have for this scenario.
const tree = data => { // immutable array
let ascendants = data.filter(d=>d.parent==null)
let descandants = data.filter(d=>d.parent)
**strong text**
let form = []
ascendants.map(a=>{
let node1 = {...a}; /// copying
let node1Children = [];
descandants.map(b=>{
let node2 = {...b};
if(node1._id == b.parent){
node1Children.push(node2)
}
})
node1.children = node1Children;
form.push(node1);
})
return form;
}
I cant take result with using $graphLookup because list format is not what i want.Could you give me some mongodb playground or grouping aggregate solutions? Below json examples shown my expecting results. I can do before but hardcode is unapropriate and performless. Is comparing good way?
[
// mongo database
{_id:123, title:'Books', slug:'books', parent:null },
{_id:124, title:'Programming', slug:'programming', parent:null },
{_id:125, title:'JavaScript', slug:'javascript', parent:'programming' },
{_id:126, title:'C++',slug:'cpp', parent:'programming' },
{_id:127, title:'React', slug:'react', parent:'javascript' },
{_id:128, title:'Redux', slug:'redux', parent:'react' },
{_id:129, title:'Toolkit', parent:'redux' },
{_id:130, title:'Saga', parent:'redux' },
{_id:131, title:'Nodejs', parent:'programming' },
{_id:132, title:'Databases', slug:'databases' },
{_id:133, title:'MongoDB', parent:'databases' },
]
[
// what i want
{ title: "Books"},
{ title: "Programming", parent:"computer-science", children: [
{ title: "JavaScript", children: [
{ title: "React", children: [
{ title: "Redux", children: [
{ title: "Saga" },
{ title: "Thunk" },
{ title: "Mobx" },
{ title: "Observable" },
{ title: "Context" },
{ title: "GraphQL" },
{ title: "Toolkit", children:[
{ title: "typescript" },
{ title: "slices", children:[
{ title: "createAsyncThunk" },
{ title: "createSlice" },
] },
] },
] },
{ title: "Nextjs" },
]},
{ title: "Vue", },
{ title: "angular", },
]},
{ title: "C++", },
{ title: "NodeJS", },
] },
{ title: "MongoDB", parent: "databases"},
]
You could create a Map to key your objects by slug. The values per key will be the result objects for parent objects. Include an entry for null, which will collect the top-level elements.
Then iterate the data again to populate children arrays -- when that property does not exist yet, create it on the fly. Finally output the top-level elements.
function makeTree(data) {
let children = []; // Top-level elements
let map = new Map(data.map(({title, slug}) => [slug, { title }]))
.set(null, {children});
for (let {slug, parent, title} of data) {
(map.get(parent || null).children ??= [])
.push(slug ? map.get(slug) : {title});
}
return children;
}
// Your mongodb data:
const data = [{_id:123, title:'Books', slug:'books', parent:null },{_id:124, title:'Programming', slug:'programming', parent:null },{_id:125, title:'JavaScript', slug:'javascript', parent:'programming' },{_id:126, title:'C++',slug:'cpp', parent:'programming' },{_id:127, title:'React', slug:'react', parent:'javascript' },{_id:128, title:'Redux', slug:'redux', parent:'react' },{_id:129, title:'Toolkit', parent:'redux' },{_id:130, title:'Saga', parent:'redux' },{_id:131, title:'Nodejs', parent:'programming' },{_id:132, title:'Databases', slug:'databases' },{_id:133, title:'MongoDB', parent:'databases' }];
console.log(makeTree(data));

Language object prop to pass in the react component

I have created a demo using a tutorial that i have found.
This is the demo => https://codesandbox.io/s/strange-monad-otv0g?file=/src/language.js
In App.js the sidebar is receiving the array of objects as props, it all works fine
const sidebaritems = [
{
name: "first",
label: "First",
items: [
{ name: "sublink2", label: "SubLink 1" },
{ name: "sublink3", label: "SubLink 2" }
]
},
"divider",
{
name: "second",
label: "Second",
items: [
{ name: "subLink 1", label: "SubLink 1" },
{ name: "subLink 2", label: "SubLink 2" }
]
},
"divider",
{
name: "third",
label: "Third"
}
];
<SideBar items={sidebaritems} />
I want now to use an external data language file that i import where i have other translations and also sidebaritems to pass, so i have created language.js and imported in the App.js
import dataForTexts from "./language.js";
My question is, how can i pass from language.js the same sidebaritems in my sidebar component in app.js
You need a named import to import your dataForTexts . So change your import statement as
import { dataForTexts } from "./language.js";
Now pass the sidebaritems as
<SideBar items={dataForTexts.sidebaritems} />
As I understand it you need this. As items, you just need to pass your data from language.js (dataForTexts)

React component not redraw when when props are updated

Quick info to describe the context.
I am working to a tree component that receives as prop this kind of data model:
workfolder: [{
label: "test",
folders: [
{ label: "label 1", id: 1 },
{ label: "label 2", id: 2 },
{ label: "label 3", id: 3 }
]
}];
All data are stored in a Redux store.
The initial value is:
state: { workfolder: [] }
On mount i fetch for default values and merge the results to workfolder in the reducer and i get my tree drawn.
return {
...state,
workfolder: results
}
When i click on one of the labels ( label 3 ) i fetch again for the sub-folders using the id and i get:
[{ label: "label 5", id: 5 },{ label: "label 5", id: 5 }]
At this point in the reducer i use a library to loop deep into the state till i find the property matching the id of the element i clicked ( label 3 in this case ) and want to merge the sub-folders into a new folder attribute.
let newState = JSON.parse(JSON.stringify(state.workfolder));
deepForEach( newState, (value, key, subject, path) => {
const isParentFolder = value === action.payload.parent;
const hasNotFolders = !subject.folders;
if( isParentFolder && hasNotFolders ) {
subject.folders = action.payload.node
}
} );
then i merge the new state in the store:
return {
...state,
workfolder: newState
}
Following this way i get the store updated, but the component won't redraw.
NOTE: this is a dummy example. In real life i have to deal with a multi level nested object having only the id and a string containing the path of the attribute i want to modify in the store.
The example that i found in the redux documentation shows how to do that writing statically the merge...

How to change the image to text for Treantjs collapsible tree view?

I have to draw a representation of data using collapsible tree structure, i am using below example link for my purpose :
http://fperucic.github.io/treant-js/examples/collapsable/
But the problem i am facing is the above link had images at every node, i want to replace it with text which when i am doing it is generating the tree with correct branches but the text is not appearing.I am using my json like this:
{
"name":"sourcetable",
"children":[{"name":"MARD"},{"name":"MARD"},{"name":"MARD"},{"name":"MARD"}]
}
It comes something like this:
Let me know how i can show the name labels on the collapsible tree.
I think you are missing a bit:
nodeStructure: {
text: { name: "Parent node" },
children: [
{
text: { name: "First child" }
},
{
text: { name: "Second child" }
}
]
}
Taken from here:
http://fperucic.github.io/treant-js/
var simple_chart_config = {
chart: {
container: "#OrganiseChart-simple"
},
nodeStructure: {
text: { name: "Parent node" },
children: [
{
text: { name: "First child" }
},
{
[enter image description here][1]text: { name: "Second child" }
}
]
}
};
Demo Link:
https://fperucic.github.io/treant-js/examples/super-simple

Categories