# How to display Tree diagram at dashboard

**URL:** <https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511>\
**Category:** Dashboard\
**Created:** [23 August 2018 13:37 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511 "2018-08-23T13:37:40Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![natanel](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@natanel](https://discourse.nodered.org/u/natanel)\
**Post date:** [23 August 2018 13:37 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/1 "2018-08-23T13:37:40Z")

</div>

Hi is there any package there for display Tree diagram at dashboard  
some thing like this  
each node get : color, name, parents

![tree%20diagram](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/a/a581c12e39f44341e33b565fac602ccea97b6ad9.jpeg)

thanks

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [23 August 2018 15:38 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/2 "2018-08-23T15:38:57Z")

</div>

> [@natanel](#):
>
> Tree diagram

Answer in stackoverflow: [javascript - How to recursively toggle nodes in a d3.js tree diagram - Stack Overflow](https://stackoverflow.com/questions/23864115/how-to-recursively-toggle-nodes-in-a-d3-js-tree-diagram)

---

<div class="post-metadata">

**Author:** ![natanel](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@natanel](https://discourse.nodered.org/u/natanel)\
**Post date:** [23 August 2018 16:27 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/3 "2018-08-23T16:27:04Z")

</div>

so, I got the tree as node template (will modify it's input to be dynamic later)

[tree.txt](https://discourse.nodered.org/uploads/short-url/olJZoK7tQAtmWvsUQGuDfdIjSlP.txt) (6.7 KB)

but it is out of my "map" group  
how do I change it?

Alos, how can I modify the layout so I can do map under discovery,  
centered and not the auto way it is done?

 ![flow](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/8/8cfa658fa97361e3575e2ce00df81dd009102737.jpeg)

 ![dashboard](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/7/7ddfcdca31ac6d862824ab31413a80c2af06e165.jpeg)

thakns

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [23 August 2018 17:06 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/4 "2018-08-23T17:06:47Z")

</div>

Modify the line that appends the SVG element to use the id of your TAB/group. For instance: tab name = D3 and group name = G1, it will be:

```auto
var svg = d3.select("#D3_G1").append("svg")

```

Result:

 ![r-01](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/a/a15190086f1f72777a5e9d8bf06bf21ec98c42d3.png)

Looks like in you case it should be:

```auto
var svg = d3.select("#Layout_map").append("svg")

```

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [23 August 2018 17:35 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/5 "2018-08-23T17:35:18Z")

</div>

> [@natanel](#):
>
> so, I got the tree as node template (will modify it's input to be dynamic later)

Love to see this when you get dynamic data added!

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [23 August 2018 17:52 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/6 "2018-08-23T17:52:34Z")

</div>

Very odd side issue. i put your flow on a tab and it showed up fine on the 'Map' tab. I then added a pie chart on the same tab, but pointing to another UI tab and the Tree shows up on both the 'Map' and the tab (Home in this case) the chart is assigned to. Not only that but it has depth to the lines

 ![44%20PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/c/c160e95908d09e307cf5febf0e725db478c91c00.png)

@Andrel any thoughts?

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [23 August 2018 18:26 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/7 "2018-08-23T18:26:04Z")

</div>

Hi @zenofmud, did you modify this line of code from the original code ?

```auto
var svg = d3.select("body").append("svg")

```

How it look like now for you ?

---

<div class="post-metadata">

**Author:** ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)\
**Post date:** [23 August 2018 18:33 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/8 "2018-08-23T18:33:30Z")

</div>

Paul, you need to turn off the css "fill" styling for your `<path>` elements -- check the Dev Console, and you can see the inherited style that needs to be overridden.

You can see the same effect in the editor links when i turn off the `fill: none;` style...  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/6/61c2a671451da22b9bcd53afeb4dfbce7c33d6ec.png)

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [23 August 2018 19:08 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/9 "2018-08-23T19:08:08Z")

</div>

@andrel

> [@Andrei](#):
>
> var svg = d3.select("body").append("svg")

when I change that to:  
`var svg = d3.select("#Layout_map").append("svg")`  
nothing shows

@shrickus - it looks fine on the original tab, it just when I went to the tab with the pie chart that I saw that image.

All I've dont is used the flow that @natanel provided with no changes other than putting it in a flow-tab that has a pie chart. Here is the flow(s) showing the issue:

```auto
[{"id":"8d9e58f5.85f7c","type":"ui_chart","z":"120f82c.f796cfd","name":"","group":"e22ca977.f549b","order":0,"width":0,"height":0,"label":"chart","chartType":"pie","legend":"false","xformat":"HH:mm:ss","interpolate":"linear","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1F77B4","#AEC7E8","#FF7F0E","#2CA02C","#98DF8A","#D62728","#FF9896","#9467BD","#C5B0D5"],"useOldStyle":false,"x":550,"y":260,"wires":[[],[]]},{"id":"fa234288.e1773","type":"inject","z":"120f82c.f796cfd","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":260,"wires":[["f6913e72.3b51c","d4bb304a.4f50f8","9aefcaac.f2028"]]},{"id":"f6913e72.3b51c","type":"change","z":"120f82c.f796cfd","name":"Series 1 - 15","rules":[{"t":"set","p":"payload","pt":"msg","to":"15","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 1","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":200,"wires":[["8d9e58f5.85f7c"]]},{"id":"d4bb304a.4f50f8","type":"change","z":"120f82c.f796cfd","name":"Series 2 - 10","rules":[{"t":"set","p":"payload","pt":"msg","to":"10","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 2","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":240,"wires":[["8d9e58f5.85f7c"]]},{"id":"9aefcaac.f2028","type":"change","z":"120f82c.f796cfd","name":"Series 3 - 12","rules":[{"t":"set","p":"payload","pt":"msg","to":"12","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 3","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":280,"wires":[["8d9e58f5.85f7c"]]},{"id":"e9fa2773.b23058","type":"change","z":"120f82c.f796cfd","name":"Series 4 - 13","rules":[{"t":"set","p":"payload","pt":"msg","to":"13","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 4","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":320,"wires":[["8d9e58f5.85f7c"]]},{"id":"434e660f.1c7248","type":"change","z":"120f82c.f796cfd","name":"Series 5 - 8","rules":[{"t":"set","p":"payload","pt":"msg","to":"8","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 4","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":360,"wires":[["8d9e58f5.85f7c"]]},{"id":"2c92a40.d6fb95c","type":"change","z":"120f82c.f796cfd","name":"Series 6 - 17","rules":[{"t":"set","p":"payload","pt":"msg","to":"17","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 8","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":400,"wires":[["8d9e58f5.85f7c"]]},{"id":"b291f4d9.9d0738","type":"change","z":"120f82c.f796cfd","name":"Series 7 - 23","rules":[{"t":"set","p":"payload","pt":"msg","to":"23","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 7","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":440,"wires":[["8d9e58f5.85f7c"]]},{"id":"906fafb9.5c1c78","type":"change","z":"120f82c.f796cfd","name":"Series 8 - 1","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 8","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":480,"wires":[["8d9e58f5.85f7c"]]},{"id":"b71e5fbc.ddacd","type":"change","z":"120f82c.f796cfd","name":"Series9 - 1","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"num"},{"t":"set","p":"topic","pt":"msg","to":"series 9","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":310,"y":520,"wires":[["8d9e58f5.85f7c"]]},{"id":"5109e224.555dac","type":"ui_template","z":"120f82c.f796cfd","group":"4d52119.21ac4f","name":"map matrix","order":0,"width":"0","height":"0","format":"<style>\t\n\t.node {\n\t\tcursor: pointer;\n\t}\n\n\t.node circle {\n\t fill: #fff;\n\t stroke: steelblue;\n\t stroke-width: 3px;\n\t}\n\n\t.node text {\n\t font: 12px sans-serif;\n\t fill: #fff;\n\t}\n\n\t.link {\n\t fill: none;\n\t stroke: #ccc;\n\t stroke-width: 2px;\n\t}\n</style>\n\t\n<script>\nvar treeData = [\n {\n \"name\": \"Top Level\",\n \"parent\": \"null\",\n \"status\": \"red\",\n \"children\": [\n {\n \"name\": \"Level 2-A\",\n \"parent\": \"Top Level\",\n \"status\": \"red\",\n \"children\": [\n {\n \"name\": \"Legolas\",\n \"status\": \"red\",\n \"parent\": \"Level 2-A\"\n },\n {\n \"name\": \"Finegal\",\n \"status\": \"green\",\n \"parent\": \"Level 2-A\"\n }\n]\n },\n {\n \"name\": \"Level 2-B\",\n \"status\": \"red\",\n \"parent\": \"Top Level\",\n \"children\": [\n {\n \"name\": \"Durin\",\n \"status\": \"red\",\n \"parent\": \"Level 2-B\",\n\t\t\t\"children\": [\n\t\t\t {\n\t\t\t\t\"name\": \"Frodo\",\n\t\t\t\t\"status\": \"green\",\n\t\t\t\t\"parent\": \"Durin\"\n\t\t\t },\n\t\t\t {\n\t\t\t\t\"name\": \"Bilbo\",\n\t\t\t\t\"status\": \"red\",\n\t\t\t\t\"parent\": \"Durin\"\n\t\t\t }\n\t\t\t] \n },\n {\n \"name\": \"Balin\",\n \"status\": \"green\",\n \"parent\": \"Level 2-B\",\n\t\t\t\"children\": [\n\t\t\t {\n\t\t\t\t\"name\": \"Merry\",\n\t\t\t\t\"status\": \"green\",\n\t\t\t\t\"parent\": \"Balin\"\n\t\t\t },\n\t\t\t {\n\t\t\t\t\"name\": \"Pipen\",\n\t\t\t\t\"status\": \"green\",\n\t\t\t\t\"parent\": \"Balin\"\n\t\t\t }\n\t\t\t] \n }\n ]\n },\n {\n \"name\": \"Level 2-C\",\n \"parent\": \"Top Level\",\n \"status\": \"green\",\n \"children\": [\n {\n \"name\": \"Gandalf\",\n \"status\": \"green\",\n \"parent\": \"Level 2-C\"\n },\n {\n \"name\": \"Sauruman\",\n \"status\": \"green\",\n \"parent\": \"Level 2-C\"\n }\n]\n },\n ]\n }\n];\n\n\n// **************Generate the tree diagram\t***************** \nvar margin = {top: 20, right: 120, bottom: 20, left: 120},\n\twidth = 960 - margin.right - margin.left,\n\theight = 500 - margin.top - margin.bottom;\n\t\nvar i = 0,\n\tduration = 750,\n\troot;\n\nvar tree = d3.layout.tree()\n\t.size([height, width]);\n\nvar diagonal = d3.svg.diagonal()\n\t.projection(function(d) { return [d.y, d.x]; });\n\nvar svg = d3.select(\"body\").append(\"svg\")\n\t.attr(\"width\", width + margin.right + margin.left)\n\t.attr(\"height\", height + margin.top + margin.bottom)\n .append(\"g\")\n\t.attr(\"transform\", \"translate(\" + margin.left + \",\" \n\t + margin.top + \")\");\n\nroot = treeData[0];\nroot.x0 = height / 2;\nroot.y0 = 0;\n\nfunction toggleAll(d) {\n if (d.children) {\n if (d.status == \"green\") {\n d._children = d.children;\n d._children.forEach(toggleAll);\n d.children = null;\n }\n }\n}\n\nroot.children.forEach(toggleAll);\n \nupdate(root);\n\nd3.select(self.frameElement).style(\"height\", \"500px\");\n\nfunction update(source) {\n\n // Compute the new tree layout.\n var nodes = tree.nodes(root).reverse(),\n\t links = tree.links(nodes);\n\n // Normalize for fixed-depth.\n nodes.forEach(function(d) { d.y = d.depth * 180; });\n\n // Update the nodesÖ\n var node = svg.selectAll(\"g.node\")\n\t .data(nodes, function(d) { return d.id || (d.id = ++i); });\n\n // Enter any new nodes at the parent's previous position.\n var nodeEnter = node.enter().append(\"g\")\n\t .attr(\"class\", \"node\")\n\t .attr(\"transform\", function(d) { \n\t\t return \"translate(\" + source.y0 + \",\" + source.x0 + \")\"; })\n\t .on(\"click\", click);\n\n nodeEnter.append(\"circle\")\n\t .attr(\"r\", 1e-6)\n\t .style(\"fill\", function(d) { return d.status; });\n\n nodeEnter.append(\"text\")\n\t .attr(\"x\", function(d) { \n\t\t return d.children || d._children ? -13 : 13; })\n\t .attr(\"dy\", \".35em\")\n\t .attr(\"text-anchor\", function(d) { \n\t\t return d.children || d._children ? \"end\" : \"start\"; })\n\t .text(function(d) { return d.name; })\n\t .style(\"fill-opacity\", 1e-6);\n\n // Transition nodes to their new position.\n var nodeUpdate = node.transition()\n\t .duration(duration)\n\t .attr(\"transform\", function(d) { \n\t\t return \"translate(\" + d.y + \",\" + d.x + \")\"; });\n\n nodeUpdate.select(\"circle\")\n\t .attr(\"r\", 10)\n\t .style(\"fill\", function(d) { return d.status; });\n\n nodeUpdate.select(\"text\")\n\t .style(\"fill-opacity\", 1);\n\n // Transition exiting nodes to the parent's new position.\n var nodeExit = node.exit().transition()\n\t .duration(duration)\n\t .attr(\"transform\", function(d) { \n\t\t return \"translate(\" + source.y + \",\" + source.x + \")\"; })\n\t .remove();\n\n nodeExit.select(\"circle\")\n\t .attr(\"r\", 1e-6);\n\n nodeExit.select(\"text\")\n\t .style(\"fill-opacity\", 1e-6);\n\n // Update the linksÖ\n var link = svg.selectAll(\"path.link\")\n\t .data(links, function(d) { return d.target.id; });\n\n // Enter any new links at the parent's previous position.\n link.enter().insert(\"path\", \"g\")\n\t .attr(\"class\", \"link\")\n\t .attr(\"d\", function(d) {\n\t\tvar o = {x: source.x0, y: source.y0};\n\t\treturn diagonal({source: o, target: o});\n\t });\n\n // Transition links to their new position.\n link.transition()\n\t .duration(duration)\n\t .attr(\"d\", diagonal);\n\n // Transition exiting nodes to the parent's new position.\n link.exit().transition()\n\t .duration(duration)\n\t .attr(\"d\", function(d) {\n\t\tvar o = {x: source.x, y: source.y};\n\t\treturn diagonal({source: o, target: o});\n\t })\n\t .remove();\n\n // Stash the old positions for transition.\n nodes.forEach(function(d) {\n\td.x0 = d.x;\n\td.y0 = d.y;\n });\n}\n\n// Toggle children on click.\nfunction click(d) {\n console.log(d);\n if (d.children) {\n\td._children = d.children;\n\td.children = null;\n } else {\n\td.children = d._children;\n\td._children = null;\n }\n update(d);\n}\n</script>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":430,"y":80,"wires":[[]]},{"id":"e22ca977.f549b","type":"ui_group","z":"","name":"Josh plants gauges","tab":"2a9bbfc9.fe1488","order":1,"disp":true,"width":"12","collapse":false},{"id":"4d52119.21ac4f","type":"ui_group","z":"","name":"map","tab":"a95a2ef.0cc6a5","order":2,"disp":true,"width":"6","collapse":false},{"id":"2a9bbfc9.fe1488","type":"ui_tab","z":"","name":"Home","icon":"dashboard","order":1},{"id":"a95a2ef.0cc6a5","type":"ui_tab","z":"","name":"Map","icon":"dashboard","order":2}]

```

Import it and deploy then go to the UI and look at the MAPS tab - the 'tree' will be there and look fine. Now go to the 'Home' tab and you will see a pie chart and the tree with the expanded curve/lines.

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [23 August 2018 19:56 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/10 "2018-08-23T19:56:19Z")

</div>

Some more weirdness.My ui has three tabs Home, Maps and Hal. Wen I first of in this is what Home looks like:  
 ![43%20PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/8/86a786a29acd450efe578381b1d40a2587f41ed9.png)  
Next I go to the Maps tab and it looks like this:

 ![56%20PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/3/301b7ab8b478704a15502121e9edaaadde7a5cd9.png)  
Then I go back to the Home tab and this is what I see:  
 ![09%20PM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/a/a0f8c7b5dbc53c4792934c8ccccf00a6fd228d23.png)

Me thinks that something is bumping into something else...

---

<div class="post-metadata">

**Author:** ![natanel](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@natanel](https://discourse.nodered.org/u/natanel)\
**Post date:** [23 August 2018 22:35 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/11 "2018-08-23T22:35:52Z")

</div>

Hi zenofmud

I did the send data to map

- manage to arrange the tree struct
- did not manage the map template node to read it

as being new , this is probably some syntax error

can you take a look and suggest  
[tree.txt](https://discourse.nodered.org/uploads/short-url/1K64nutHqcu0L0XBEWO7IuapxdH.txt) (9.9 KB)

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [23 August 2018 22:40 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/12 "2018-08-23T22:40:55Z")

</div>

> [@zenofmud](#):
>
> Some more weirdness.My ui has three tabs Home, Maps and Hal.

Hi Paul,

Your code needs to be patched to reflect the tab and group name you have in place.

Instead of

```auto
var svg = d3.select("body").append("svg")

```

Use line below:

```auto
var svg = d3.select("#Map_map").append("svg")

```

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [24 August 2018 00:22 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/13 "2018-08-24T00:22:12Z")

</div>

> [@Andrei](#):
>
> #Map\_map

Ahhh, much better!! I see now, the "body" caused it to be displayed on any tab! I will file this away for future reference!

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [24 August 2018 00:28 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/14 "2018-08-24T00:28:23Z")

</div>

> [@natanel](#):
>
> this is probably some syntax error

This is not the issue that is preventing you from displaying the tree in the dashboard but anyway it is better to change your code.

In some places you declare and use a variable named "node". It happens that "node" is already a declared object in Node-RED so better to not use it.

```auto
// arrange tree
while( treeData[treeData.length-1].zone !== 0 )
{
    var node = treeData.pop();
    
    // find and add as children to parent
    var i = FindParent(treeData,node);

    if( i != -1)
        treeData[i].children.push(node);
}

```

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [24 August 2018 02:23 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/15 "2018-08-24T02:23:52Z")

</div>

> [@natanel](#):
>
> did not manage the map template node to read it

Apparently your function node is generating a valid data structure (msg.payload.treeData).

However, I was not able to use it inside the ui\_template node. I need to revise how to use the msg object properties inside the ui\_template.

When using a variable declared directly inside the ui\_template it works perfectly.

 ![node-red-05](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/f/f46dc37aa9163dc3f52adb154764a0003c09e75e.gif)

Flow:

```auto
[{"id":"a9a2ce4f.e328f","type":"tab","label":"Flow 9","disabled":false,"info":""},{"id":"d211e6ca.04c818","type":"function","z":"a9a2ce4f.e328f","name":"prepare map data","func":"// data to read from cordinator eeprom\nvar numBonded = 4;\nvar numDiscovered = 3;\n//\t\t\t\t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\nvar nodesBonded = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0];\nvar nodesDiscovered = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0];\nvar vrnArray = \t\t [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 0, 0];\nvar nodesZone = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0];\nvar nodesParent = \t [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0];\n\nvar treeData = [\n\t{\n\t\t\"name\": \"Cordinator\",\n\t\t\"parent\": \"null\",\n\t\t\"status\": \"orange\",\n\t\t\"zone\": 0,\n\t\t\"children\": []\n\t}\n];\n\nvar index = 0;\nwhile( numBonded )\n{\n index++;\n\tif( nodesBonded[index] == 1)\n\t{\n\t\tvar parent = \"\";\n\t\tvar status = \"\";\n\t\t\n\t\t// orphan\n\t\tif( nodesDiscovered[index] === 0 )\n\t\t{\n\t\t\tparent = \"null\";\n\t\t\tstatus = \"red\";\n\t\t}\n\t\t// first children\n\t\telse if( nodesParent[index] === 0 )\n\t\t{\n\t\t\tparent = \"Cordinator\";\n\t\t\tstatus = \"green\";\n\t\t}\n\t\t// other children\n\t\telse\n\t\t{\n\t\t\tparent = \"ID \" + vrnArray.indexOf(nodesParent[index]).toString() + \", VRN \" + nodesParent[index].toString();\n\t\t\tstatus = \"green\";\n\t\t}\n\t\t\n\t\ttreeData.push( \n\t\t{\n\t\t\t\"name\": \"ID \" + index.toString() + \", VRN \" + vrnArray[index].toString(),\n\t\t\t\"parent\": parent,\n\t\t\t\"status\": status,\n\t\t\t\"zone\": nodesZone[index],\n\t\t\t\"children\": []\n\t\t} );\n\t\tnumBonded--;\n\t}\n}\n\n// sort array by zone\ntreeData.sort(function(a,b) {return (a.zone > b.zone) ? 1 : ((b.zone > a.zone) ? -1 : 0);} );\n\n// arrange tree\nwhile( treeData[treeData.length-1].zone !== 0 )\n{\n var node = treeData.pop();\n \n // find and add as children to parent\n var i = FindParent(treeData,node);\n\n if( i != -1)\n treeData[i].children.push(node);\n}\n\nglobal.set(\"treeData\", treeData);\nmsg.payload={\"treeData\": treeData };\n\nreturn msg;\n\nfunction FindParent(treeData, node) {\n for( var i = treeData.length-1 ; i >= 0 ; i--)\n {\n var n = node.parent.localeCompare(treeData[i].name);\n if((treeData[i].zone === (node.zone)-1) && (n===0))\n return i;\n }\n return -1;\n}","outputs":1,"noerr":0,"x":330,"y":220,"wires":[["2c76fb3c.525134","bdcefd26.67fc7"]]},{"id":"4e9c142a.63189c","type":"inject","z":"a9a2ce4f.e328f","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":220,"wires":[["d211e6ca.04c818"]]},{"id":"7b976e82.e2bb7","type":"debug","z":"a9a2ce4f.e328f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":690,"y":220,"wires":[]},{"id":"2c76fb3c.525134","type":"debug","z":"a9a2ce4f.e328f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":530,"y":160,"wires":[]},{"id":"bdcefd26.67fc7","type":"ui_template","z":"a9a2ce4f.e328f","group":"6a8123c4.16a83c","name":"","order":0,"width":"0","height":"0","format":"<!DOCTYPE html>\n\n<html>\n\n<head>\n<style>\t\n\t.node {\n\t\tcursor: pointer;\n\t}\n\n\t.node circle {\n\t fill: #fff;\n\t stroke: steelblue;\n\t stroke-width: 3px;\n\t}\n\n\t.node text {\n\t font: 12px sans-serif;\n\t fill: #fff;\n\t}\n\n\t.link {\n\t fill: none;\n\t stroke: #ccc;\n\t stroke-width: 2px;\n\t}\n</style>\n</head>\n\n<body>\n\n\n<script src=\"//d3js.org/d3.v3.js\"></script>\t\n<script>\nvar treeData = [\n {\n \"name\": \"Top Level\",\n \"parent\": \"null\",\n \"status\": \"red\",\n \"children\": [\n {\n \"name\": \"Level 2-A\",\n \"parent\": \"Top Level\",\n \"status\": \"red\",\n \"children\": [\n {\n \"name\": \"Legolas\",\n \"status\": \"red\",\n \"parent\": \"Level 2-A\"\n },\n {\n \"name\": \"Finegal\",\n \"status\": \"green\",\n \"parent\": \"Level 2-A\"\n }\n]\n },\n {\n \"name\": \"Level 2-B\",\n \"status\": \"red\",\n \"parent\": \"Top Level\",\n \"children\": [\n {\n \"name\": \"Durin\",\n \"status\": \"red\",\n \"parent\": \"Level 2-B\",\n \"children\": [\n {\n \"name\": \"Frodo\",\n \"status\": \"green\",\n \"parent\": \"Durin\"\n },\n {\n \"name\": \"Bilbo\",\n \"status\": \"red\",\n \"parent\": \"Durin\"\n }\n]\n },\n {\n \"name\": \"Balin\",\n \"status\": \"green\",\n \"parent\": \"Level 2-B\",\n \"children\": [\n {\n \"name\": \"Merry\",\n \"status\": \"green\",\n \"parent\": \"Balin\"\n },\n {\n \"name\": \"Pipen\",\n \"status\": \"green\",\n \"parent\": \"Balin\"\n }\n]\n }\n ]\n },\n {\n \"name\": \"Level 2-C\",\n \"parent\": \"Top Level\",\n \"status\": \"green\",\n \"children\": [\n {\n \"name\": \"Gandalf\",\n \"status\": \"green\",\n \"parent\": \"Level 2-C\"\n },\n {\n \"name\": \"Sauruman\",\n \"status\": \"green\",\n \"parent\": \"Level 2-C\"\n }\n]\n }\n ]\n }\n ];\n\n\n// **************Generate the tree diagram\t***************** \nvar margin = {top: 20, right: 120, bottom: 20, left: 120},\n\twidth = 960 - margin.right - margin.left,\n\theight = 500 - margin.top - margin.bottom;\n\t\nvar i = 0,\n\tduration = 750,\n\troot;\n\nvar tree = d3.layout.tree()\n\t.size([height, width]);\n\nvar diagonal = d3.svg.diagonal()\n\t.projection(function(d) { return [d.y, d.x]; });\n\nvar svg = d3.select(\"#Layout_map\").append(\"svg\")\n\t.attr(\"width\", width + margin.right + margin.left)\n\t.attr(\"height\", height + margin.top + margin.bottom)\n .append(\"g\")\n\t.attr(\"transform\", \"translate(\" + margin.left + \",\" \n\t + margin.top + \")\");\n\nroot = treeData[0];\nroot.x0 = height / 2;\nroot.y0 = 0;\n\nfunction toggleAll(d) {\n if (d.children) {\n if (d.status == \"green\") {\n d._children = d.children;\n d._children.forEach(toggleAll);\n d.children = null;\n }\n }\n}\n\nroot.children.forEach(toggleAll);\n \nupdate(root);\n\nd3.select(self.frameElement).style(\"height\", \"500px\");\n\nfunction update(source) {\n\n // Compute the new tree layout.\n var nodes = tree.nodes(root).reverse(),\n\t links = tree.links(nodes);\n\n // Normalize for fixed-depth.\n nodes.forEach(function(d) { d.y = d.depth * 180; });\n\n // Update the nodes…\n var node2 = svg.selectAll(\"g.node\")\n\t .data(nodes, function(d) { return d.id || (d.id = ++i); });\n\n // Enter any new nodes at the parent's previous position.\n var nodeEnter = node2.enter().append(\"g\")\n\t .attr(\"class\", \"node\")\n\t .attr(\"transform\", function(d) { \n\t\t return \"translate(\" + source.y0 + \",\" + source.x0 + \")\"; })\n\t .on(\"click\", click);\n\n nodeEnter.append(\"circle\")\n\t .attr(\"r\", 1e-6)\n\t .style(\"fill\", function(d) { return d.status; });\n\n nodeEnter.append(\"text\")\n\t .attr(\"x\", function(d) { \n\t\t return d.children || d._children ? -13 : 13; })\n\t .attr(\"dy\", \".35em\")\n\t .attr(\"text-anchor\", function(d) { \n\t\t return d.children || d._children ? \"end\" : \"start\"; })\n\t .text(function(d) { return d.name; })\n\t .style(\"fill-opacity\", 1e-6);\n\n // Transition nodes to their new position.\n var nodeUpdate = node2.transition()\n\t .duration(duration)\n\t .attr(\"transform\", function(d) { \n\t\t return \"translate(\" + d.y + \",\" + d.x + \")\"; });\n\n nodeUpdate.select(\"circle\")\n\t .attr(\"r\", 10)\n\t .style(\"fill\", function(d) { return d.status; });\n\n nodeUpdate.select(\"text\")\n\t .style(\"fill-opacity\", 1);\n\n // Transition exiting nodes to the parent's new position.\n var nodeExit = node2.exit().transition()\n\t .duration(duration)\n\t .attr(\"transform\", function(d) { \n\t\t return \"translate(\" + source.y + \",\" + source.x + \")\"; })\n\t .remove();\n\n nodeExit.select(\"circle\")\n\t .attr(\"r\", 1e-6);\n\n nodeExit.select(\"text\")\n\t .style(\"fill-opacity\", 1e-6);\n\n // Update the links…\n var link = svg.selectAll(\"path.link\")\n\t .data(links, function(d) { return d.target.id; });\n\n // Enter any new links at the parent's previous position.\n link.enter().insert(\"path\", \"g\")\n\t .attr(\"class\", \"link\")\n\t .attr(\"d\", function(d) {\n\t\tvar o = {x: source.x0, y: source.y0};\n\t\treturn diagonal({source: o, target: o});\n\t });\n\n // Transition links to their new position.\n link.transition()\n\t .duration(duration)\n\t .attr(\"d\", diagonal);\n\n // Transition exiting nodes to the parent's new position.\n link.exit().transition()\n\t .duration(duration)\n\t .attr(\"d\", function(d) {\n\t\tvar o = {x: source.x, y: source.y};\n\t\treturn diagonal({source: o, target: o});\n\t })\n\t .remove();\n\n // Stash the old positions for transition.\n nodes.forEach(function(d) {\n\td.x0 = d.x;\n\td.y0 = d.y;\n });\n}\n\n// Toggle children on click.\nfunction click(d) {\n console.log(d);\n if (d.children) {\n\td._children = d.children;\n\td.children = null;\n } else {\n\td.children = d._children;\n\td._children = null;\n }\n update(d);\n}\n</script>\n\n</body>\n\n</html>","storeOutMessages":false,"fwdInMessages":true,"templateScope":"local","x":520,"y":220,"wires":[["7b976e82.e2bb7"]]},{"id":"6a8123c4.16a83c","type":"ui_group","z":"","name":"map","tab":"4361b344.61bc2c","order":2,"disp":false,"width":"16","collapse":false},{"id":"4361b344.61bc2c","type":"ui_tab","z":"","name":"Layout","icon":"dashboard","order":2}]

```

---

<div class="post-metadata">

**Author:** ![natanel](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@natanel](https://discourse.nodered.org/u/natanel)\
**Post date:** [24 August 2018 08:20 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/16 "2018-08-24T08:20:36Z")

</div>

almost there

able to update by msg.payload  
but

- trees are just added , did not find the correct place to erase old tree  
meaning where to put: d3.select("svg").remove();
- the tree is not fully unfolded, only first level, second level need click on circle

Flow:  
[tree.txt](https://discourse.nodered.org/uploads/short-url/ibFHmVzpvGju521DE2G3YRd7QZe.txt) (8.5 KB)

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [24 August 2018 14:27 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/17 "2018-08-24T14:27:50Z")

</div>

Hi guys,

Very interesting stuff !

@natanel: will you make this afterwards available on [flows.nodered.org](http://flows.nodered.org), so it could be used as a generic usable component?

Kind regards,  
Bart

---

<div class="post-metadata">

**Author:** ![natanel](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@natanel](https://discourse.nodered.org/u/natanel)\
**Post date:** [24 August 2018 15:50 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/18 "2018-08-24T15:50:35Z")

</div>

Hi Bart

first thanks  
few points

1. it is not my code I download it from (Andrei found it)  
https://stackoverflow.com/questions/23864115/how-to-recursively-toggle-nodes-in-a-d3-js-tree-diagram
2. just modify it to be able to put it in node red template and that it will be able to get input as msg
3. also built function node to pass information from my mesh network eeprom data to tree requested json
4. I am so green in this node-red and javascript ( I am real time C++ programmer), so I can be very little help in this time  
(even though I built IOT mesh network to MQTT, node-red, android application which I an quit proud of it)
5. so fill free to make this available where ever you think, I will use any fix/helps that a community can give

any way my suggestion  
this tree is very specific to the example data (found in link)

1. add ability to auto scale group size as function of zone/ add scrolling abilities
2. need to clear old tree on new msg, did not worked for me
3. add multi trees on same group
4. tree options from up/down/left/right

just send me a link so I can benefit from any improvement

---

<div class="post-metadata">

**Author:** ![natanel](https://avatars.discourse-cdn.com/v4/letter/n/e99b99/32.png) [@natanel](https://discourse.nodered.org/u/natanel)\
**Post date:** [24 August 2018 19:54 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/19 "2018-08-24T19:54:40Z")

</div>

Hi

finally got something  
that I can do and I am pleased

[tree.txt](https://discourse.nodered.org/uploads/short-url/pcGnorB3nCQ9JrYua9XmFHtpxEm.txt) (13.2 KB)

1. added computeSvgSizeFromData, which do exactly that "compute Svg Size From Data"
2. finally found how to erase old data on new data arriving

not sure my clear method is correct, but it's working

> // clear  
> d3.select("#Layout\_map\_SVG").remove();

still will be nice to have

1. add scrolling bar abilities
2. tree options from up/down/left/right
3. correct way to pass to the SVG element to use the id of the TAB/group,  
getting it from the node properties of the template node

Andrei - as before, your help is gold  
zenofmud - you can see the code you asked in the attachment  
Bart - fill free to progress this node, I can use the community help

BR  
Natanel

---

<div class="post-metadata">

**Author:** ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)\
**Post date:** [25 August 2018 06:09 UTC](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511/20 "2018-08-25T06:09:16Z")

</div>

> [@natanel](#):
>
> - trees are just added , did not find the correct place to erase old tree  
> meaning where to put: d3.select("svg").remove();
> - the tree is not fully unfolded, only first level, second level need click on circle

Hello @natanel,

I am lagging behind as only now I could have a look on this post.

Looks like you already solved both issues but let me provide my thoughts

I would rather find a way to add the SVG element only once, at the startup, so there will be no need to add a statement to remove the SVG element later on. This can be achieved by moving a few lines of code outside the function(scope) block. I did it and, apparently, it is working all right.

In regards to expand all the tree nodes at the startup. As far as I could understand the function toggleAll(d) will check the color of the node and expand or not. In order to always expand at the startup, I modified the color to one not used (black). It worked.

Here is the modified flow in case you want to use some of these ideas:

```auto
[{"id":"f889d991.03a9d8","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"dd4f4542.e90b08","type":"ui_template","z":"f889d991.03a9d8","group":"4ccda03f.4a457","name":"map matrix","order":0,"width":"6","height":"1","format":"<style>\t\n\t.node {\n\t\tcursor: pointer;\n\t}\n\n\t.node circle {\n\t fill: #fff;\n\t stroke: steelblue;\n\t stroke-width: 3px;\n\t}\n\n\t.node text {\n\t font: 12px sans-serif;\n\t fill: #fff;\n\t}\n\n\t.link {\n\t fill: none;\n\t stroke: #ccc;\n\t stroke-width: 2px;\n\t}\n</style>\n\n<script>\n // **************Generate the tree diagram\t***************** \n var margin = { top: 20, right: 120, bottom: 20, left: 120 },\n width = 960 - margin.right - margin.left,\n height = 500 - margin.top - margin.bottom;\n \n var svg = d3.select(\"#Layout_map\").append(\"svg\")\n .attr(\"width\", width + margin.right + margin.left)\n .attr(\"height\", height + margin.top + margin.bottom)\n .append(\"g\")\n .attr(\"transform\", \"translate(\" + margin.left + \",\"\n + margin.top + \")\");\n \n</script>\n\n\n<script>\n(function (scope) {\n //console.dir(scope);\n scope.$watch('msg', function (msg) {\n //console.dir(msg);\n\n var treeData = msg.payload.treeData;\n\n\n var i = 0,\n duration = 750,\n root;\n\n var tree = d3.layout.tree()\n .size([height, width]);\n\n var diagonal = d3.svg.diagonal()\n .projection(function (d) { return [d.y, d.x]; });\n\n\n\n root = treeData[0];\n root.x0 = height / 2;\n root.y0 = 0;\n\n function toggleAll(d) {\n if (d.children) {\n if (d.status == \"black\") {\n d._children = d.children;\n d._children.forEach(toggleAll);\n d.children = null;\n }\n }\n }\n\n root.children.forEach(toggleAll);\n\n update(root);\n\n //root = treeData[1];\n //root.x0 = 2* ( height / 3 );\n //root.y0 = 0;\n //root.children.forEach(toggleAll);\n //update(root);\n\n d3.select(self.frameElement).style(\"height\", \"500px\");\n\n function update(source) {\n\n // Compute the new tree layout.\n var nodes = tree.nodes(root).reverse(),\n links = tree.links(nodes);\n\n // Normalize for fixed-depth.\n nodes.forEach(function (d) { d.y = d.depth * 180; });\n\n // Update the nodes…\n var node2 = svg.selectAll(\"g.node\")\n .data(nodes, function (d) { return d.id || (d.id = ++i); });\n\n // Enter any new nodes at the parent's previous position.\n var nodeEnter = node2.enter().append(\"g\")\n .attr(\"class\", \"node\")\n .attr(\"transform\", function (d) {\n return \"translate(\" + source.y0 + \",\" + source.x0 + \")\";\n })\n .on(\"click\", click);\n\n nodeEnter.append(\"circle\")\n .attr(\"r\", 1e-6)\n .style(\"fill\", function (d) { return d.status; });\n\n nodeEnter.append(\"text\")\n .attr(\"x\", function (d) {\n return d.children || d._children ? -13 : 13;\n })\n .attr(\"dy\", \".35em\")\n .attr(\"text-anchor\", function (d) {\n return d.children || d._children ? \"end\" : \"start\";\n })\n .text(function (d) { return d.name; })\n .style(\"fill-opacity\", 1e-6);\n\n // Transition nodes to their new position.\n var nodeUpdate = node2.transition()\n .duration(duration)\n .attr(\"transform\", function (d) {\n return \"translate(\" + d.y + \",\" + d.x + \")\";\n });\n\n nodeUpdate.select(\"circle\")\n .attr(\"r\", 10)\n .style(\"fill\", function (d) { return d.status; });\n\n nodeUpdate.select(\"text\")\n .style(\"fill-opacity\", 1);\n\n // Transition exiting nodes to the parent's new position.\n var nodeExit = node2.exit().transition()\n .duration(duration)\n .attr(\"transform\", function (d) {\n return \"translate(\" + source.y + \",\" + source.x + \")\";\n })\n .remove();\n\n nodeExit.select(\"circle\")\n .attr(\"r\", 1e-6);\n\n nodeExit.select(\"text\")\n .style(\"fill-opacity\", 1e-6);\n\n // Update the links…\n var link = svg.selectAll(\"path.link\")\n .data(links, function (d) { return d.target.id; });\n\n // Enter any new links at the parent's previous position.\n link.enter().insert(\"path\", \"g\")\n .attr(\"class\", \"link\")\n .attr(\"d\", function (d) {\n var o = { x: source.x0, y: source.y0 };\n return diagonal({ source: o, target: o });\n });\n\n // Transition links to their new position.\n link.transition()\n .duration(duration)\n .attr(\"d\", diagonal);\n\n // Transition exiting nodes to the parent's new position.\n link.exit().transition()\n .duration(duration)\n .attr(\"d\", function (d) {\n var o = { x: source.x, y: source.y };\n return diagonal({ source: o, target: o });\n })\n .remove();\n\n // Stash the old positions for transition.\n nodes.forEach(function (d) {\n d.x0 = d.x;\n d.y0 = d.y;\n });\n }\n\n // Toggle children on click.\n function click(d) {\n //console.log(d);\n if (d.children) {\n d._children = d.children;\n d.children = null;\n } else {\n d.children = d._children;\n d._children = null;\n }\n update(d);\n }\n });\n})(scope);\n</script>","storeOutMessages":true,"fwdInMessages":true,"templateScope":"local","x":790,"y":240,"wires":[[]]},{"id":"2b1738d4.41a168","type":"function","z":"f889d991.03a9d8","name":"prepare map data","func":"// data to read from cordinator eeprom\nvar numBonded = 4;\nvar numDiscovered = 3;\n//\t\t\t\t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\nvar nodesBonded = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0];\nvar nodesDiscovered = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0];\nvar vrnArray = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 2, 0, 0];\nvar nodesZone = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0];\nvar nodesParent = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0];\n\nvar treeData = [\n {\n \"name\": \"Cordinator\",\n \"parent\": \"null\",\n \"status\": \"orange\",\n \"children\": [],\n \"zone\": 0\n }\n];\n\nvar index = 0;\nwhile (numBonded) {\n index++;\n if (nodesBonded[index] == 1) {\n var parent = \"\";\n var status = \"\";\n\n // orphan\n if (nodesDiscovered[index] === 0) {\n parent = \"null\";\n status = \"red\";\n }\n // first children\n else if (nodesParent[index] === 0) {\n parent = \"Cordinator\";\n status = \"green\";\n }\n // other children\n else {\n parent = \"ID \" + vrnArray.indexOf(nodesParent[index]).toString() + \", VRN \" + nodesParent[index].toString();\n status = \"green\";\n }\n\n treeData.push(\n {\n \"name\": \"ID \" + index.toString() + \", VRN \" + vrnArray[index].toString(),\n \"parent\": parent,\n \"status\": status,\n \"children\": [],\n \"zone\": nodesZone[index],\n });\n numBonded--;\n }\n}\n\n// sort array by zone\ntreeData.sort(function (a, b) { return (a.zone > b.zone) ? 1 : ((b.zone > a.zone) ? -1 : 0); });\n\n// arrange tree\nwhile (treeData[treeData.length - 1].zone !== 0) {\n var nodeChild = treeData.pop();\n\n // find and add as children to parent\n var i = FindParent(treeData, nodeChild);\n\n if (i != -1)\n treeData[i].children.push(nodeChild);\n}\n\nglobal.set(\"treeData\", treeData);\nmsg.payload = { \"treeData\": treeData };\n\nreturn msg;\n\nfunction FindParent(treeData, nodeChild) {\n for (var i = treeData.length - 1; i >= 0; i--) {\n var n = nodeChild.parent.localeCompare(treeData[i].name);\n if ((treeData[i].zone === (nodeChild.zone) - 1) && (n === 0))\n return i;\n }\n return -1;\n}","outputs":1,"noerr":0,"x":550,"y":180,"wires":[["527fa260.f0c70c","dd4f4542.e90b08"]]},{"id":"cb1c32ef.a7d4a","type":"inject","z":"f889d991.03a9d8","name":"","topic":"prepare map","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":320,"y":180,"wires":[["2b1738d4.41a168"]]},{"id":"527fa260.f0c70c","type":"debug","z":"f889d991.03a9d8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":790,"y":180,"wires":[]},{"id":"4ccda03f.4a457","type":"ui_group","z":"","name":"map","tab":"e870aec0.5ba89","order":2,"disp":true,"width":"6","collapse":false},{"id":"e870aec0.5ba89","type":"ui_tab","z":"","name":"Layout","icon":"dashboard","order":2}]

```

[Next page](https://discourse.nodered.org/t/how-to-display-tree-diagram-at-dashboard/2511.md?page=2)
