I have this stackblitz : Tree View
The tree is not building as expected; I want to have something like :
Manager
Sub liste
Manager 1
Manager 2
Manager 3
Can you take a look and give some advices please ?
const TREE_DATA = {
idManager: 1,
label: "Manager",
descendants:
{
idManager: 2,
label: "Sub liste",
descendants: [
{
idManager: 3,
label: "Manager 1"
},
{
idManager: 4,
label: "Manager 2"
},
{
idManager: 5,
label: "Manager 3"
}
]
}
};
Change your TREE_DATA structure
Related
I would like to generate a tree from the following object:
configuration:
{
name: "General",
icon: "general",
children: [
{
name: "Line 1",
icon: "line",
children: [
{
name: "Area 1",
icon: "area",
children: [
{ name: "Y", icon: "x" },
{ name: "Z", icon: "z" },
],
},
{ name: "Area 2", icon: "line" },
],
},
{
name: "Line 2,
icon: "line",
children: [{ name: "Area 3", icon: "area" }],
},
],
},
In html I have my own custom element:
<my-details>
<div slot="summary"><my-icon name="${icon}"></my-icon> ${name}</div>
${this.children} // ???
</my-details>`;
so I created the function:
createHierarchy() {
if (configuration?.length > 0) {
const details = _configuration.map(({ name, icon }) => {
return ` <my-details>
<div slot="summary"><my-icon name="${icon}"></my-icon> ${name}</div>
${this.children}
</my-details>`;
});
hierarchyContainer.innerHTML = details?.join("");
}
}
but I don't know how to convert this structure in a loop or map to a tree, each element of the hierarchy should be a my-details element and have a name as a slot and in the middle it should have children
the structure should look like this:
hierarchy tree
What you are looking for is a recursive function. Which is a function that calls itself.
It should end up looking something like this:
function parseNode(node) {
let html = `<my-details>
<div slot="summary">
<my-icon name="${node.icon}"></my-icon>
${node.name}.
</div>`;
if(node.children) {
node.children.forEach(childNode => {
html += parseNode(childNode);
})
;}
html += '</my-details>';
return html;
}
parseNode(configuration);
This example turns your entire configuration into an html string (or it should it is untested). You can output to your document/component.
Note that it relies on all nodes having a name and an icon and a possible "children" has to be an array.
I currently have an array of items that looks a bit like this: I want to group the items by category lookup, with the slight problem that category lookup is potentially an array, such that Parent Item 2 would be listed twice (once in My Cat) and once in something else) I tried using https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/groupBy but it doesn't seem to be able to handle this?
[
{
"tool_id": "4-19de-454673d9-9ef5-4545",
"somekey" : "Parent Item 2"
"categoryLookup": [
{
"category_name": "New Item",
}
]
},
{
"tool_id": "be7ea707-19de-43d9-9ef1-d4a3ff79f77a",
"somekey" : "Parent Item"
"categoryLookup": [
{
"category_name": "My Cat",
},
{
"category_name": "Something Else",
}
]
}
]
The final result would look something like:
[
{
New Item: [
{...contains 4-19de-454673d9-9ef5-4545 }
],
My Cat: [
{...contains be7ea707-19de-43d9-9ef1-d4a3ff79f77a}
],
Something Else: [
{... contain be7ea707-19de-43d9-9ef1-d4a3ff79f77a}
]
}
]
You can iterate over the original array and create the final one:
var data = [{
"tool_id": "4-19de-454673d9-9ef5-4545",
"somekey": "Parent Item 2",
"categoryLookup": [{
"category_name": "New Item",
}]
},
{
"tool_id": "be7ea707-19de-43d9-9ef1-d4a3ff79f77a",
"somekey": "Parent Item",
"categoryLookup": [{
"category_name": "My Cat",
},
{
"category_name": "Something Else",
}
]
}
];
function groupByCategory(data) {
const res = {};
data.forEach(item => {
item.categoryLookup.forEach(category => {
const name = category.category_name;
res[name] ??= [];
res[name].push({
item: item.tool_id //or all the properties you want
});
});
});
return res;
}
console.log( groupByCategory(data) );
Suppose i have a array like this:
const HeaderData = [
{
header: {
title: "How you'll benefit",
detail:
"We create this goals to help you recover from your recent surgery. Slowly increase your physical strength is an important part of recovery. With this plan, you will be back to normal in no time. You got this!",
},
xyz: {
title: "dsdsdas",
},
},
{
mainData: [
{
detail: "4/1/2021",
},
{
detail: "Jennifer. 0",
},
{
detail: "4/1/2021",
},
{
detail: "In progress",
},
],
},
{
activity: [
// title
{
activity1: "Take the stairs",
activity2: "5 Sets of Sit-Ups",
activity3: "3 sets of Push-Up",
activity4: "Weight-lifting",
},
// notSatisfied
{
activity1: 5,
activity2: 3,
activity3: 7,
activity4: 3
},
//neutral
{
activity1: 0,
activity2: 2,
activity3: 2,
activity4: 3,
},
//satisfied
{
activity1: 2,
activity2: 5,
activity3: 1,
activity4: 0,
},
],
},
]
I only know how to get data in a child if they have same name, for example in my array is activity1 or title, using map() because it have the same name, but problem is , they very confusing and easy to misunderstand ,if i want to get all data in a child , how can i do that. For example, if i change above array to this
const HeaderData = [
{
header: {
title: "How you'll benefit",
detail:
"We create this goals to help you recover from your recent surgery. Slowly increase your physical strength is an important part of recovery. With this plan, you will be back to normal in no time. You got this!",
},
xyz: {
title: "dsdsdas",
},
},
{
mainData: [
{
title: "Created On",
detail: "4/1/2021",
},
{
title: "Created By",
detail: "Jennifer. 0",
},
{
title: "Started",
detail: "4/1/2021",
},
{
title: "Completed",
detail: "In progress",
},
],
},
{
activityName: [
{
title: "Take the stairs",
notSatisfied: 5,
neutral: 0,
satisfied: 2,
},
{
title: "5 Sets of Sit-Ups",
notSatisfied: 3,
neutral: 2,
satisfied: 5,
},
{
title: "3 sets of Push-Up",
notSatisfied: 7,
neutral: 3,
satisfied: 1,
},
{
title: "Weight-lifting",
notSatisfied: 3,
neutral: 2,
satisfied: 0,
},
],
},
]
It much more clear now, in my opinion but now i'm stuck, i don't khow how to get data from first elemet from mainData
{
title: "Take the stairs",
notSatisfied: 5,
neutral: 0,
satisfied: 2,
},
If i want to get ALL this data at once through map(), how can i do that? I only know if they have the same name
Please help, thank a lot
Hoping this is what you are looking for:
HeaderData.map(elem => {if(elem.activityName){console.log(elem.activityName[0])}})
I have a datastructure of the form
node: { "name": "root";
"children": [ node ]; }
there is another example at the bottom of the question.
Now I would like to remove all nodes above a specified one and only keep the remaining sub-tree.
So for example, given the tree T
A
/ \
B C
/ \
D E
the function getTree(T, 'C') should return
C
/ \
D E
Question: is there an easy way to implement this?
function getTree(json, node) {
var tree = JSON.parse(json);
/* QUESTION: how do I remove everything not below the node with name===node here?
}
PS: larger example:
var tree = [
{
text: "Parent 1",
nodes: [
{
text: "Child 1",
nodes: [
{
text: "Grandchild 1"
},
{
text: "Grandchild 2"
}
]
},
{
text: "Child 2"
}
]
},
{
text: "Parent 2"
},
{
text: "Parent 3"
},
{
text: "Parent 4"
},
{
text: "Parent 5"
}
];
Edit: good point: I should have mentioned that the node names are unique.
You could iterate the array and look if the node has the wanted text or if the nested nodes have a found.
const
getTree = (tree, text) => {
let result;
tree.some(node => result = node.text === text
? node
: getTree(node.nodes || [], text)
);
return result;
},
tree = [{ text: "Parent 1", nodes: [{ text: "Child 1", nodes: [{ text: "Grandchild 1" }, { text: "Grandchild 2" }] }, { text: "Child 2" }] }, { text: "Parent 2" }, { text: "Parent 3" }, { text: "Parent 4" }, { text: "Parent 5" }];
console.log(getTree(tree, "Grandchild 1"));
console.log(getTree(tree, "Parent 1"));
.as-console-wrapper { max-height: 100% !important; top: 0; }
First Array
const firstArray = [
{
"value": "306",
"label": "All"
},
{
"value": "316",
"label": "Tips"
},
{
"value": "315",
"label": "News"
},
{
"value": "32",
"label": "Jobs"
}]
Second Array
const secondArray = [
{
name: "name",
description: "desc",
image: "path_image",
culture: [{
name: "name",
value: "32"
}]
},
{
name: "name",
description: "desc",
image: "path_image",
culture: [{
name: "name",
value: "32"
}]
}];
Trying to filter my firstArray with only keeping the object with the value corresponding to 32.
Still learning Javascript and it's in a React Native Project. They changed some info of the API and it was working when I only had : culture":"32"
Code :
let newOrigin = [...new Set(this.state.secondArray.map(product => product.culture))],
visibleOrigin = firstArray.filter(item => newOrigin.includes(item.value));
this.setState({ displayOrigin: visibleOrigin });
How to get the value inside the array culture.
Any advice, any help ? Thank you.
So. I found a solution to my issue. Here's the code :
_nameFunction = () => {
let filteredSecondArray = [...new Set(this.state.secondArray.map(o => o.culture[0].value))];
this.setState({
firstArray: this.state.firstArray.filter(item => filteredSecondArray.includes(item.value))
})
}