node-red-dashboard: Chart Timeseries Data Format

3,733 views
Skip to first unread message

joearkay

unread,
Mar 17, 2018, 4:07:38 PM3/17/18
to Node-RED
Hi all, 

I'm having some issues formatting data for the chart, from a timeseries set of data. 

As per the charts.md document, we want a dataset that looks like this:

[{
"series": ["A", "B", "C"],
"data": [
    [{ "x": 1504029632890, "y": 5 },
     { "x": 1504029636001, "y": 4 },
     { "x": 1504029638656, "y": 2 }
    ],
    [{ "x": 1504029633514, "y": 6 },
     { "x": 1504029636622, "y": 7 },
     { "x": 1504029639539, "y": 6 }
    ],
    [{ "x": 1504029634400, "y": 7 },
     { "x": 1504029637959, "y": 7 },
     { "x": 1504029640317, "y": 7 }
    ]
],
"labels": [""]
}]

(https://github.com/node-red/node-red-dashboard/blob/master/Charts.md)

I've managed to format my data to the point where it looks like this:

{
"series": ["Data"],
"data": [{
"x": "2018-02-07T14:33:03.927Z",
"y": 29.375
}, {
"x": "2018-03-05T22:22:17.468Z",
"y": 19.687
}, {
"x": "2018-03-05T22:27:21.068Z",
"y": 19.25
}],
"labels": ["Labels"],
"_msgid": "4f90333.dd809cc"
}

...however, the chart node doesn't seem to display anything here. I have a couple of thoughts:

-The chart is expecting a whole array (i.e. my data should be encapsulated as a JSON array [])
-Node-red is appending a _msgid field to this dataset

My Javascript used to get this far (within a function block) looks like this:

var data = [];
var series =["Data"];
var labels = ["Labels"];

for (var i = 0; i< msg.payload.length; i++){
    data.push({"x": msg.payload[i].timeStamp, "y" : msg.payload[i].value});
}

var object = [[{series, data, labels}]];

return object;



What am I missing here? I've tried `return [object]` and other variants. Any ideas appreciated. 

Thanks 

Rewe Node

unread,
Mar 17, 2018, 9:33:09 PM3/17/18
to Node-RED
Your format is not correct. Try this:

[
    {
        "series": [
            "Data"
        ],
        "data": [
            [
                {
                    "x": "2018-02-07T14:33:03.927Z",
                    "y": 29.375
                },
                {
                    "x": "2018-03-05T22:22:17.468Z",
                    "y": 19.687
                },
                {
                    "x": "2018-03-05T22:27:21.068Z",
                    "y": 19.25
                }
            ]
        ],
        "labels": [
            "Labels"
        ]
    }
]


Mark Setrem

unread,
Mar 18, 2018, 5:41:23 AM3/18/18
to Node-RED

Your original data format works for me, but you are returning it from your function as the object.  when it needs to be msg.payload.
(99.9% or node-red node return the send the key data as msg.payload. )

Tested in node-red-dashboard v.2.8.2

[{"id":"3dd66bf4.a63784","type":"inject","z":"444a6ea5.d96ab","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":117.5,"y":136,"wires":[["774c414c.1cbbb"]]},{"id":"774c414c.1cbbb","type":"template","z":"444a6ea5.d96ab","name":"Original data to msg.payload","field":"payload","fieldType":"msg","format":"json","syntax":"plain","template":"[{\n\"series\": [\"A\", \"B\", \"C\"],\n\"data\": [\n    [{ \"x\": 1504029632890, \"y\": 5 },\n     { \"x\": 1504029636001, \"y\": 4 },\n     { \"x\": 1504029638656, \"y\": 2 }\n    ],\n    [{ \"x\": 1504029633514, \"y\": 6 },\n     { \"x\": 1504029636622, \"y\": 7 },\n     { \"x\": 1504029639539, \"y\": 6 }\n    ],\n    [{ \"x\": 1504029634400, \"y\": 7 },\n     { \"x\": 1504029637959, \"y\": 7 },\n     { \"x\": 1504029640317, \"y\": 7 }\n    ]\n],\n\"labels\": [\"\"]\n}]","output":"json","x":340.5,"y":138,"wires":[["f2c9cbfe.619cb","82bf0850.728a58"]]},{"id":"f2c9cbfe.619cb","type":"ui_chart","z":"444a6ea5.d96ab","name":"","group":"f5e8187.acab268","order":0,"width":0,"height":0,"label":"chart","chartType":"line","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":534.5,"y":195,"wires":[[],[]]},{"id":"82bf0850.728a58","type":"debug","z":"444a6ea5.d96ab","name":"Chart Data","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":528.5,"y":263,"wires":[]},{"id":"f5e8187.acab268","type":"ui_group","z":"","name":"LOG","tab":"643c1a1d.08fffc","order":6,"disp":true,"width":"6"},{"id":"643c1a1d.08fffc","type":"ui_tab","z":"","name":"Heizung","icon":"dashboard","order":2}]

joearkay

unread,
Mar 18, 2018, 6:01:06 AM3/18/18
to Node-RED
Hi Rewe - thanks for the comment. I understand that my format is not identical - it's what I'm trying to fix ;) 

Thanks, 
Joe 

Rewe Node

unread,
Mar 18, 2018, 6:06:24 AM3/18/18
to Node-RED
"_msgid": "4f90333.dd809cc" is ignored, you can also let it in.

joearkay

unread,
Mar 18, 2018, 6:07:03 AM3/18/18
to Node-RED
Hi Mark, 

Thanks for the comment. I've copied over your flow - but I'm still unsure as to how to return as a msg.payload, from my javascript - any pointers? Playing around at the moment. 

Thanks, 
Joe 

joearkay

unread,
Mar 18, 2018, 6:11:02 AM3/18/18
to Node-RED
Mark/Rewe, 

I'm not sure my original data format actually works, as I've tried modifying Mark's flow with my dataset and my graph does not display anything? 

[{"id":"35fadd46.e62ce2","type":"ui_chart","z":"597c72b.a0c0c8c","name":"Boiler Return Temperature","group":"1cc6f4a1.5aabfb","order":0,"width":0,"height":0,"label":"Boiler Return Temperature","chartType":"line","legend":"false","xformat":"auto","interpolate":"linear","nodata":"","dot":false,"ymin":"0","ymax":"100","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"x":1440,"y":500,"wires":[[],[]]},{"id":"ccab7b0a.eed838","type":"inject","z":"597c72b.a0c0c8c","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":880,"y":500,"wires":[["1c209c05.c88c74"]]},{"id":"1c209c05.c88c74","type":"template","z":"597c72b.a0c0c8c","name":"Original data to msg.payload","field":"payload","fieldType":"msg","format":"json","syntax":"plain","template":"{\n\t\"series\": [\"Data\"],\n\t\"data\": [{\n\t\t\"x\": \"2018-02-07T14:33:03.927Z\",\n\t\t\"y\": 29.375\n\t}, {\n\t\t\"x\": \"2018-03-05T22:22:17.468Z\",\n\t\t\"y\": 19.687\n\t}, {\n\t\t\"x\": \"2018-03-05T22:27:21.068Z\",\n\t\t\"y\": 19.25\n\t}],\n\t\"labels\": [\"Labels\"]\n}","output":"json","x":1140,"y":500,"wires":[["35fadd46.e62ce2"]]},{"id":"1cc6f4a1.5aabfb","type":"ui_group","z":"","name":"Boiler Measurements","tab":"8ea03526.88f288","disp":true,"width":"6","collapse":false},{"id":"8ea03526.88f288","type":"ui_tab","z":"","name":"Boiler","icon":"dashboard"}]

Rewe Node

unread,
Mar 18, 2018, 6:11:21 AM3/18/18
to Node-RED
I use JSONata for that. See here: https://groups.google.com/d/msg/node-red/SeHasjoue6g/h7sQvuAZBgAJ
But I don't know your input format

joearkay

unread,
Mar 18, 2018, 6:18:22 AM3/18/18
to Node-RED
Hi Rewe, 

Original data is as follows:

[
   {
      "id":19,
      "sensorId":"FFA4B8B01604",
      "sensorName":"Boiler Return Temperature",
      "sensorType":"Temperature",
      "timeStamp":"2018-02-07T14:33:03.927Z",
      "value":29.375
   },
   {
      "id":22,
      "sensorId":"FFA4B8B01604",
      "sensorName":"Boiler Return Temperature",
      "sensorType":"Temperature",
      "timeStamp":"2018-02-07T14:38:06.647Z",
      "value":29.312
   },
   {
      "id":25,
      "sensorId":"FFA4B8B01604",
      "sensorName":"Boiler Return Temperature",
      "sensorType":"Temperature",
      "timeStamp":"2018-02-07T14:43:09.367Z",
      "value":29.312
   }
]

This is then pushed into my function block:

[{"id":"1438a747.556619","type":"function","z":"597c72b.a0c0c8c","name":"Format for UI Chart Object","func":"var data = [];\nvar series =[\"Data\"];\nvar labels = [\"Labels\"];\n\nfor (var i = 0; i< msg.payload.length; i++){\n    data.push({\"x\": msg.payload[i].timeStamp, \"y\" : msg.payload[i].value});\n}\n\nvar object = [{series, data, labels}];\n\nreturn object;\n\n","outputs":1,"noerr":0,"x":1120,"y":140,"wires":[["bbdd1cd5.d945f","35fadd46.e62ce2"]]}]


Which at the moment is outputting something like:

{
   "series":[
      "Data"
   ],
   "data":[
      {
         "x":"2018-02-07T14:33:03.927Z",
         "y":29.375
      },
      {
         "x":"2018-02-07T14:38:06.647Z",
         "y":29.312
      },
      {
         "x":"2018-02-07T14:43:09.367Z",
         "y":29.312
      },
      {
         "x":"2018-02-07T14:48:12.087Z",
         "y":29.312
      }
   ],
   "labels":[
      "Labels"
   ],
   "_msgid":"344e5359.36613c"
}


Obviously I've shortened these both - so the datapoints won't match point-to-point in this example. 

Thanks 

Rewe Node

unread,
Mar 18, 2018, 6:18:52 AM3/18/18
to Node-RED
"data" is an array of arrays of objects
This works:

[{"id":"6f19903b.76a6e8","type":"ui_chart","z":"823cb8b8.b8dba8","name":"","group":"56c599b5.e72208","order":0,"width":0,"height":0,"label":"chart","chartType":"line","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":1430,"y":660,"wires":[[],[]]},{"id":"770b5e49.3a1ee8","type":"inject","z":"823cb8b8.b8dba8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":920,"y":660,"wires":[["ab92b5d9.bf159"]]},{"id":"ab92b5d9.bf159","type":"template","z":"823cb8b8.b8dba8","name":"Original data to msg.payload","field":"payload","fieldType":"msg","format":"json","syntax":"plain","template":"[{\n\t\"series\": [\"Data\"],\n\t\"data\": [[{\n\t\t\"x\": \"2018-02-07T14:33:03.927Z\",\n\t\t\"y\": 29.375\n\t}, {\n\t\t\"x\": \"2018-03-05T22:22:17.468Z\",\n\t\t\"y\": 19.687\n\t}, {\n\t\t\"x\": \"2018-03-05T22:27:21.068Z\",\n\t\t\"y\": 33.25\n\t}]],\n\t\"labels\": [\"Labels\"]\n}]","output":"json","x":1180,"y":660,"wires":[["6f19903b.76a6e8"]]},{"id":"56c599b5.e72208","type":"ui_group","z":"","name":"Test Influx","tab":"38b065a0.2822b2","disp":true,"width":"6","collapse":false},{"id":"38b065a0.2822b2","type":"ui_tab","z":"","name":"Influx","icon":"dashboard"}]

Nick O'Leary

unread,
Mar 18, 2018, 6:24:25 AM3/18/18
to node...@googlegroups.com

> I'm still unsure as to how to return as a msg.payload

You set msg.payload and return msg:

msg.payload = [[{series, data, labels}]]
return msg;




--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/74902774-7dfe-46f8-8e08-ec34027f798d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

joearkay

unread,
Mar 18, 2018, 6:25:35 AM3/18/18
to Node-RED
Hi Rewe, 

Thanks - I get this - I'm just not sure on the JavaScript to realise this within my function block. 

Thanks, 
Joe 

joearkay

unread,
Mar 18, 2018, 6:37:43 AM3/18/18
to Node-RED
Thanks Nick - my function block is now as follows:

var data = [];
var series =["Data"];
var labels = ["Labels"];

for (var i = 0; i< msg.payload.length; i++){
    data.push({"x": msg.payload[i].timeStamp, "y" : msg.payload[i].value});
}

msg.payload = [{series, data, labels}];
return msg;


and this outputs:

 
   "_msgid":"bf6e05b8.f5bf28",
   "topic":"SELECT * From sensorData WHERE sensorName = \"Boiler Return Temperature\";",
   "payload": 
       

         "series": 
            "Data"
         ],
         "data": 
             
               "x":"2018-02-07T14:33:03.927Z",
               "y":29.375
            },
             
               "x":"2018-03-05T22:22:17.468Z",
               "y":19.687
            },
             
               "x":"2018-03-05T22:27:21.068Z",
               "y":19.25
            }
         ],
         "labels": 
            "Labels"
         ]
      }
   ]
}


This has a JSON 'payload' object with an array containing all of the necessary parts, but it still isn't graphing? Appreciate the help so far. Thanks. 

Rewe Node

unread,
Mar 18, 2018, 6:57:11 AM3/18/18
to Node-RED
try this:

[{"id":"4e8ae46c.b6bff4","type":"ui_chart","z":"b9acf092.52dba8","name":"myTemp Chart N","group":"e707478.acd72b8","order":1,"width":"0","height":"0","label":"Temperatur","chartType":"line","legend":"true","xformat":"auto","interpolate":"linear","nodata":"hole Daten","dot":false,"ymin":"","ymax":"","removeOlder":"100","removeOlderPoints":"3","removeOlderUnit":"604800","cutout":0,"useOneColor":false,"colors":["#1F77B4","#AEC7E8","#FF7F0E","#2CA02C","#98DF8A","#D62728","#FF9896","#9467BD","#C5B0D5"],"useOldStyle":false,"x":743,"y":649,"wires":[["3f0fb7d9.efecf8"],[]]},{"id":"3f0fb7d9.efecf8","type":"debug","z":"b9acf092.52dba8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":954,"y":650,"wires":[]},{"id":"92abfbb4.7e478","type":"change","z":"b9acf092.52dba8","name":"prepare data strukture for chart","rules":[{"t":"set","p":"payload","pt":"msg","to":"(\t$ts := msg.payload;\t$series := \"Boiler Return Temperature\";\t$data := $map($ts, function($v) \t                       {\t                           {\t                               \"x\": $v.timeStamp,\t                               \"y\": $v.value\t                           }\t                        }\t                 );\t    \t    [\t       {\t           \"series\": [$series],\t           \"data\": [[$data]]\t       }\t    ]                 \t )","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":438,"y":649,"wires":[["4e8ae46c.b6bff4"]]},{"id":"71e4e797.3bb92","type":"inject","z":"b9acf092.52dba8","name":"input JSON","topic":"","payload":"[{\"id\":19,\"sensorId\":\"FFA4B8B01604\",\"sensorName\":\"Boiler Return Temperature\",\"sensorType\":\"Temperature\",\"timeStamp\":\"2018-02-07T14:33:03.927Z\",\"value\":29.375},{\"id\":22,\"sensorId\":\"FFA4B8B01604\",\"sensorName\":\"Boiler Return Temperature\",\"sensorType\":\"Temperature\",\"timeStamp\":\"2018-02-07T14:38:06.647Z\",\"value\":29.312},{\"id\":25,\"sensorId\":\"FFA4B8B01604\",\"sensorName\":\"Boiler Return Temperature\",\"sensorType\":\"Temperature\",\"timeStamp\":\"2018-02-07T14:43:09.367Z\",\"value\":29.312}]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":163.5,"y":647,"wires":[["92abfbb4.7e478"]]},{"id":"e707478.acd72b8","type":"ui_group","z":"","name":"HM_loop","tab":"117d29fb.cbb31e","disp":true,"width":"6"},{"id":"117d29fb.cbb31e","type":"ui_tab","z":"","name":"Homematic","icon":"dashboard","order":1}]

your "data" isn't array of arrays of objects. 

joearkay

unread,
Mar 18, 2018, 7:02:59 AM3/18/18
to Node-RED
Oh wow - like it! 

Thanks for your help. 

Rewe Node

unread,
Mar 18, 2018, 12:17:29 PM3/18/18
to Node-RED
But for this simple input format JSONata is of course not necessary.  This is very easy with Javascript.

let r = msg.payload;
let serie = [r[0].sensorName];
let data = [r.map( v => ({
    "x": v.timeStamp,
    "y": v.value
}))]; 

msg.payload = [{"series": serie, "data": data}]; 
return msg;




[{"id":"513d52ff.145bf4","type":"inject","z":"41d9f92a.be46f","name":"input JSON","topic":"","payload":"[{\"id\":19,\"sensorId\":\"FFA4B8B01604\",\"sensorName\":\"Boiler Return Temperature\",\"sensorType\":\"Temperature\",\"timeStamp\":\"2018-02-07T14:33:03.927Z\",\"value\":29.375},{\"id\":22,\"sensorId\":\"FFA4B8B01604\",\"sensorName\":\"Boiler Return Temperature\",\"sensorType\":\"Temperature\",\"timeStamp\":\"2018-02-07T14:38:06.647Z\",\"value\":29.312},{\"id\":25,\"sensorId\":\"FFA4B8B01604\",\"sensorName\":\"Boiler Return Temperature\",\"sensorType\":\"Temperature\",\"timeStamp\":\"2018-02-07T14:43:09.367Z\",\"value\":29.312}]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":181,"y":1027,"wires":[["e3d6376.28fe4c8","e2ebe96f.71ccd"]]},{"id":"e2ebe96f.71ccd","type":"function","z":"41d9f92a.be46f","name":"prepare data strukture for chart with Javascript","func":"let r = msg.payload;\nlet serie = [r[0].sensorName];\nlet data = [r.map( v => ({\n    \"x\": v.timeStamp,\n    \"y\": v.value\n}))]; \n\nmsg.payload = [{\"series\": serie, \"data\": data}]; \nreturn msg;","outputs":1,"noerr":0,"x":477.5,"y":1026,"wires":[["5391d9a3.9164"]]},{"id":"5391d9a3.9164","type":"debug","z":"41d9f92a.be46f","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":783.5,"y":1027,"wires":[]}]
Reply all
Reply to author
Forward
0 new messages