Developing UI chart from an array

Hello

I have the data in the attached screenshot parsed from an AWS DynamoDB. I've tried to extract parts of the payload to feed into a UI chart (in this function I am trying to plot temperature vs time).

The function code is as follows:

var x=0;
var data = {};
var i=0;

for (i=0; i< msg.payload.ScannedCount; i++) {


data.push({"x": msg.payload.Items[i].time, "y" : msg.payload.Items[i].payload.M.Temperature});

}
msg.payload = {label: "label", data, series: "X"};

return msg;

But I get the error: "TypeError: data.push is not a function"

Also I suspect that I do not have the correct payload format for the chart. What is the payload format I should be sending the chart to plot the array?

If you want data to be an array that you push into then you need var data = []
As you have it you are making an object not an array.

Thanks that did the trick.

Now not sure what format to parse the data to the chart? Can someone help?

There is a link in the info panel for the Chart node that tells you how to pre-format data to be passed in as a complete chart.

thank you for that information

I've tried to feed the data in as per the flow example on

I've revised my code (see below). However, I cannot seem to store the data per the examples on that website.

The correct format looks like this:

However mine looks like this:

Also, I can't seem to work out why there's another value stored in the data array position 1, when I've declared it as an array as [0][ X ].

Sorry if this seems like a dumb question, I'm still developing my javascript skills.

var objectdata = {};
var i=0;
var data = [
    [0], [msg.payload.ScannedCount]
];
for (i=0; i< msg.payload.ScannedCount; i++) {

objectdata = {"x":msg.payload.Items[i].time, "y":msg.payload.Items[i].payload.M.Temperature};
data[0][i] = objectdata;
}

var chart = [{
    "series":["A"],
    "data":data,
    "labels":[""]
}];

msg.payload = chart;

return msg;

Looking at the most obvious problem you can see that x and y in the result are not numbers.
In the debug showing your source data expand those two elements (time and Temperature) and you will see they are objects, not numbers. You need to get the numbers.

Thanks for that!

So I now have my flow injecting the following data into a chart node (you can see the data on the right). But I cannot get it to chart.

Any ideas why?

It is a pity that the example in the docs has three series but also three points for each series so it is not entirely clear whether the data array contains one element for each series, and each of those elements contains the data points for that series, or whether the data array contains one element for each set of data points, and each of those contains one point for each series. Looking at the numbers it looks as if it is the former (which is what you have done) but I am not certain. I haven't done this myself. Hopefully someone else can comment. Alternatively perhaps there is an example on the flows website or in the cookbook that will help.

I think it's because I am parsing the values as strings instead of numbers...

Ah, you could be right. In that case use "x": Number(msg.payload.items...)

Yep - I just wrote that as you responded! Works a treat now, except the EPOCH time in the x value is not being converted correctly on the chart.

Does node-red conver that time to a normal readable time ?time

The first point pased is:
x: 1552215913 (converts to Sunday March 10, 2019 22:05:13 (pm)
y: 24.5

That last point parsed is:
x: 1552294289 (converts to Monday March 11, 2019 19:51:29 (pm))
y: 23.86

Why is it reading 09:10:15 -> 09:11:35? Is there a way to set it so that it converts to GMT+11?

If you look again at the example in the docs you will see that the timestamps should be javascript time (which is milliseconds), so the first thing to do is to multiply all your timestamps by 1000.

Thanks very much!

One more issue I'm having, the points all display correctly on the chart, but the X-axis does not reflect the points ?

Is there a setting on the chart somewhere to ensure this adjusts to the time stamps I am plotting?

query

What do the popup timestamps show for the points where the line crosses the the 22:00 axis lines?

Thanks for the response. It has changed times now, but instead of 22:00 it's showing 00:00:00... Here is a few screenshots:

Can you make a simple flow showing the problem, using an inject and function node or similar to provide half a dozen of your data points passed into a chart, so we can attempt to replicate the problem?

OK this has me puzzled.

My original node flow looks like this:

This returns graph posted above. The function Extract Temperature looks like this:

var time=[];
var temp=[];
var deviceid=[];
var time_float = 0;
var temp_float=0;

var i=0;
var dataarray = [[]];

for (i=0; i< msg.payload.ScannedCount; i++) {
time = Object.values(msg.payload.Items[i].time);
temp =  Object.values(msg.payload.Items[i].payload.M.Temperature);
time_float = Number(time[0])*1000;
temp_float = Number(temp[0]);
dataarray[0][i] = {"x":time_float,"y":temp_float};

}

var chart = [{
    "series":["Temperature ="],
    "data":dataarray,
    "labels":[""]
}];

msg.payload = chart;

return msg;


However, when I re-create the node with some input data using the code below, the graph displays the x-axis correctly.

[{"id":"5e52f683.e88988","type":"function","z":"3d772458.67327c","name":"Extract Temperature","func":"var time=[];\nvar temp=[];\nvar time_float = 0;\nvar temp_float=0;\n\ntemp[0] = 24.5\ntemp[1] = 26\ntemp[2] = 28\ntemp[3] = 30\n\ntime[0] = 1552215913000\ntime[1] = 1552218111000 \ntime[2] = 1552225320000 \ntime[3] = 1552232527000\n\nvar i=0;\nvar dataarray = [[]];\n\nfor (i=0; i< 4; i++) {\ntime_float = Number(time[i]);\ntemp_float = Number(temp[i]);\ndataarray[0][i] = {\"x\":time_float,\"y\":temp_float};\n\n}\n\nvar chart = [{\n    \"series\":[\"Temperature =\"],\n    \"data\":dataarray,\n    \"labels\":[\"\"]\n}];\n\nmsg.payload = chart;\n\nreturn msg;\n\n","outputs":1,"noerr":0,"x":553,"y":262,"wires":[["c57af1f0.79a22","2768353f.11f2fa"]]},{"id":"2a1aac7.6cad654","type":"inject","z":"3d772458.67327c","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":305,"y":266,"wires":[["5e52f683.e88988"]]},{"id":"c57af1f0.79a22","type":"ui_chart","z":"3d772458.67327c","name":"","group":"788afba5.70ef64","order":0,"width":"5","height":"8","label":"","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"bezier","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":"24","removeOlderPoints":"0","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#14aee4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#ffffff"],"useOldStyle":false,"outputs":1,"x":806,"y":265,"wires":[[]]},{"id":"2768353f.11f2fa","type":"debug","z":"3d772458.67327c","name":"TEST","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":794,"y":146,"wires":[]},{"id":"788afba5.70ef64","type":"ui_group","z":"","name":"Temperature (°C)","tab":"54f8799a.3418b8","order":1,"disp":true,"width":"6","collapse":false},{"id":"54f8799a.3418b8","type":"ui_tab","z":"","name":"Sensatech - Device 1CEE2B","icon":"dashboard","disabled":false,"hidden":false}]

In your test set include timestamps from the first and last ones in your actual data. It may be to do with that.

[Edit] Also tell us what the start and end timestamps are (in UTC) so we don't have to look them up ourselves.

You're quite right, I injected the start/middle/end points into the code below and the same problem occurs now. The x-axis shows 00:00:00

The converted times are listed next to the arrays.

Is this a chart setting issue?

var time=[];
var temp=[];
var time_float = 0;
var temp_float=0;

temp[0] = 24.5
temp[1] = 26.31
temp[2] = 24.43
temp[3] = 23.95

time[0] = 1552215913000 // Sunday March 10, 2019 22:05:13
time[1] = 1552267716000 //Monday March 11, 2019 12:28:36 
time[2] = 1552363351000 //Tuesday March 12, 2019 15:02:31 
time[3] = 1552474514000 //Wednesday March 13, 2019 21:55:14

var i=0;
var dataarray = [[]];

for (i=0; i< 4; i++) {
time_float = Number(time[i]);
temp_float = Number(temp[i]);
dataarray[0][i] = {"x":time_float,"y":temp_float};

}

var chart = [{
    "series":["Temperature ="],
    "data":dataarray,
    "labels":[""]
}];

msg.payload = chart;

return msg;