# How to break data array into separate charts with data and labels

**URL:** https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516
**Category:** General
**Created:** [21 January 2021 21:43 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516 "2021-01-21T21:43:21Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![thebeardedgeek](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/thebeardedgeek/32/35338_2.png) [@thebeardedgeek](https://discourse.nodered.org/u/thebeardedgeek)
#### Post date: [21 January 2021 21:43 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/1 "2021-01-21T21:43:21Z")

</div>

I am new to node-red and looking for some assistance here.

I am running a SQL statement to get two fields returned from a table: customer (string) and storage size (integer).  
select trim(CUSTOMER) as "CUSTOMER",DISK\_SPACE\_USED from stats where run\_date \>= current date

I return 46 data sets into 1 array. I would like to loop through the array and have it create an output for each customer that I could then flow to a donut chart that would label the chart with the customer name and the data in the chart would be the storage size percentage (without me having to manually create each one).

Is this possible and if so what would it look like?

Right now I have it grabbing a specific customer and was going to create a function node for each customer if I had to but I would prefer it to be more dynamic if possible.  
cust = "TEST";  
var value = 0;  
msg.payload.forEach(function(row) {  
if (row.CUSTOMER == cust) {  
value = parseInt(row.DISK\_SPACE\_USED);  
}  
});

return {payload:value};

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/f/6f835c34702bd37b430f61a0c9e441fa3a677afe.png)

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/6/1/61358be39e83e9b75da44c0eab3bf37bbc65b747.png)

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [21 January 2021 22:09 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/2 "2021-01-21T22:09:35Z")

</div>

Are there 46 donuts on the dashboard or are you going to have a method of selecting the one you are interested in?

---

<div class="post-metadata">

### Author: ![thebeardedgeek](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/thebeardedgeek/32/35338_2.png) [@thebeardedgeek](https://discourse.nodered.org/u/thebeardedgeek)
#### Post date: [21 January 2021 22:15 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/3 "2021-01-21T22:15:58Z")

</div>

Colin,  
I was thinking I would have to create 46 donut graphs and have 46 outputs from the function and link them. Since I am trying to get the label of the donut and the value to populate automatically it wouldn't matter the order.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [21 January 2021 22:24 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/4 "2021-01-21T22:24:21Z")

</div>

I think I would convert your array to an object, something like (untested)

```auto
answer = {}
for (let i=0; i< msg.payload.length) {
  answer[msg.payload[i].CUSTOMER] = msg.payload.DISK_SPACE_USED
}
msg.payload = answer
return msg

```

Then you can feed that to all the gauges and in the Value format field put  
`msg.payload["this customer"]`  
Then the gauge will select the value for "this customer". At least I think you can do that, I haven't got time to check it as it is late. If I haven't got it quite right then I can have a better look in the morning.

---

<div class="post-metadata">

### Author: ![thebeardedgeek](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/thebeardedgeek/32/35338_2.png) [@thebeardedgeek](https://discourse.nodered.org/u/thebeardedgeek)
#### Post date: [21 January 2021 23:06 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/5 "2021-01-21T23:06:08Z")

</div>

> [@Colin](#):
>
> msg.payload["this customer"]

Thanks for the suggestion Colin. When I tried this it broke my flow and wouldn't load the flow or ui. I had to backdoor my flow and remove the code. Maybe I did something wrong.

---

<div class="post-metadata">

### Author: ![E1cid](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/e1cid/32/77971_2.png) [@E1cid](https://discourse.nodered.org/u/E1cid)
#### Post date: [21 January 2021 23:50 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/6 "2021-01-21T23:50:09Z")

</div>

Why not use the ui-template node and create the gauges all dynamically, something like below.  
The payload array is injected by the inject node. The function creates a html page with javascript. and the ui-template node displays all dounuts.

```auto
[{"id":"a7d1f1c4.c8cb1","type":"inject","z":"57675e72.26a0d8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[{\"customer\":\"john\",\"size\":23},{\"customer\":\"sarah\",\"size\":47},{\"customer\":\"tom\",\"size\":34}]","payloadType":"json","x":80,"y":2460,"wires":[["422318c8.3f3c","819c37d1.394e8"]]},{"id":"422318c8.3f3c","type":"function","z":"57675e72.26a0d8","name":"","func":"let html = \"\";\nlet script = `<script>\n `;\n\n\nfor(let i=0; i < msg.payload.length; i++){\n let vals = [100-msg.payload[i].size,msg.payload[i].size]\n html += `<canvas id=\"canvas${i}\" width=150 height=150 ></canvas>\\n`;\n script += `var canvas=document.getElementById(\"canvas${i}\");\n var ctr=canvas.getContext(\"2d\")\n var colors=['gray','skyblue'];\n values=[${vals[0]},${vals[1]}];\n labels=['name','${msg.payload[i].customer}'];\n dmbChart(ctr,70,70,60,10,values,colors,labels,1);`\n}\nmsg.template= html+script+\n`function dmbChart(ctx,cx,cy,radius,arcwidth,values,colors,labels,selectedValue){\n var tot=0;\n var accum=0;\n var PI=Math.PI;\n var PI2=PI*2;\n var offset=-PI/2;\n ctx.lineWidth=arcwidth;\n for(var i=0;i<values.length;i++){tot+=values[i];}\n for(var i=0;i<values.length;i++){\n ctx.beginPath();\n ctx.arc(cx,cy,radius,\n offset+PI2*(accum/tot),\n offset+PI2*((accum+values[i])/tot)\n );\n ctx.strokeStyle=colors[i];\n ctx.stroke();\n accum+=values[i];\n }\n var innerRadius=radius-arcwidth-3;\n ctx.beginPath();\n ctx.arc(cx,cy,innerRadius,0,PI2);\n ctx.fillStyle=colors[selectedValue];\n ctx.fill();\n ctx.textAlign='center';\n ctx.textBaseline='bottom';\n ctx.fillStyle='white';\n ctx.font=(innerRadius)+'px verdana';\n ctx.fillText(values[selectedValue],cx,cy+innerRadius*.9);\n ctx.font=(innerRadius/4)+'px verdana';\n ctx.fillText(labels[selectedValue],cx,cy-innerRadius*.25);\n}\n</script>`;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":310,"y":2480,"wires":[["a0b72f46.f0133","6bd8925c.1728b4"]]},{"id":"a0b72f46.f0133","type":"ui_template","z":"57675e72.26a0d8","group":"8b5cde76.edd58","name":"","order":0,"width":0,"height":0,"format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":570,"y":2460,"wires":[[]]},{"id":"6bd8925c.1728b4","type":"debug","z":"57675e72.26a0d8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"template","targetType":"msg","statusVal":"","statusType":"auto","x":500,"y":2540,"wires":[]},{"id":"8b5cde76.edd58","type":"ui_group","z":"","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"6","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","z":"","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

```

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [22 January 2021 09:49 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/7 "2021-01-22T09:49:07Z")

</div>

> [@thebeardedgeek](#):
>
> When I tried this it broke my flow and wouldn't load the flow or ui.

It works ok for me

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/5/d/5d4fdd8d007d8e272b583cc5f1a7a7c49cb44d5d.png)

```auto
[{"id":"253472e5.9048ae","type":"inject","z":"2320900f.56c54","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"customer 1\": 7.3, \"customer 2\": 1.0}","payloadType":"json","x":90,"y":900,"wires":[["c2cb0f2c.789298","98a0db7b.e71498"]]},{"id":"c2cb0f2c.789298","type":"ui_gauge","z":"2320900f.56c54","name":"","group":"903a6ab8.4f4ca8","order":1,"width":0,"height":0,"gtype":"gage","title":"gauge","label":"units","format":"{{msg.payload[\"customer 1\"]}}","min":0,"max":10,"colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":320,"y":900,"wires":[]},{"id":"98a0db7b.e71498","type":"ui_gauge","z":"2320900f.56c54","name":"","group":"903a6ab8.4f4ca8","order":1,"width":0,"height":0,"gtype":"gage","title":"gauge","label":"units","format":"{{msg.payload[\"customer 2\"]}}","min":0,"max":10,"colors":["#00b500","#e6e600","#ca3838"],"seg1":"","seg2":"","x":310,"y":980,"wires":[]},{"id":"903a6ab8.4f4ca8","type":"ui_group","name":"Home","tab":"e2e6f4f5.56f91","order":1,"disp":false,"width":"6","collapse":false},{"id":"e2e6f4f5.56f91","type":"ui_tab","name":"Homet","icon":"dashboard","order":3,"disabled":false,"hidden":false}]

```

---

<div class="post-metadata">

### Author: ![thebeardedgeek](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/thebeardedgeek/32/35338_2.png) [@thebeardedgeek](https://discourse.nodered.org/u/thebeardedgeek)
#### Post date: [22 January 2021 18:26 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/8 "2021-01-22T18:26:39Z")

</div>

Colin,  
Thank you. I will try this out and respond. From my initial look at this I believe this is what I was looking for but would like to test it.

---

<div class="post-metadata">

### Author: ![thebeardedgeek](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/thebeardedgeek/32/35338_2.png) [@thebeardedgeek](https://discourse.nodered.org/u/thebeardedgeek)
#### Post date: [22 January 2021 19:51 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/9 "2021-01-22T19:51:08Z")

</div>

Colin,  
I think I am very close based on your suggestion; however, how do I grab specific values from the array? When I do {{msg.payload["1"]}} for the Label I get the whole array's values. I have tried various methods to get the value of that array but I'm missing something. Can you help here? Thank you.

For this graph I would like to grab value 0 of array 0 for the value and value 0 of array 1 for the label.

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/4/e4cccb745541aa783bf204a7868102b6e44a550c.png)

---

<div class="post-metadata">

### Author: ![thebeardedgeek](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/thebeardedgeek/32/35338_2.png) [@thebeardedgeek](https://discourse.nodered.org/u/thebeardedgeek)
#### Post date: [22 January 2021 20:35 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/10 "2021-01-22T20:35:33Z")

</div>

I was able to work it out. This displays the value 0 of both arrays. Thanks for your help @Colin!!

```auto
**Function Node:**
var m = {};

m.data=[];
m.labels=[];
var datatemp=[]; 
msg.payload.forEach(function(row) {
        datatemp.push(parseFloat(row.DISK_SPACE_USED));
        m.labels.push(row.CUSTOMER);
});

m.data.push(datatemp);

return {payload:[m.data,m.labels]};

**Donut Graph node:**
Label: {{msg.payload[1][0]}}
Value format: {{msg.payload[0][0][0]}}

```

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/6/b66b3a87d61a87fbca0d2911243a78ca49e324b3.png)

---

<div class="post-metadata">

### Author: ![thebeardedgeek](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/thebeardedgeek/32/35338_2.png) [@thebeardedgeek](https://discourse.nodered.org/u/thebeardedgeek)
#### Post date: [22 January 2021 20:36 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/11 "2021-01-22T20:36:38Z")

</div>

@E1cid Thank you for the reply. This would more than likely work but I wanted to try to stick with the system supplied node graphs.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [22 January 2021 20:46 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/12 "2021-01-22T20:46:40Z")

</div>

> [@thebeardedgeek](#):
>
> `datatemp.push(parseFloat(row.DISK_SPACE_USED));`

You shouldn't need the parseFloat, I think. Assuming that the field is numeric in the database it should return a number not a string. Try it without and see.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [5 February 2021 20:47 UTC](https://discourse.nodered.org/t/how-to-break-data-array-into-separate-charts-with-data-and-labels/39516/13 "2021-02-05T20:47:31Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
