Flexdash 'Time Plot Raw' chart formatting (uPlot)

Anybody using the Flexdash Time Plot Raw or uPlot?

I've used the Flexdash Time Plot node so far for charts, which is much easier to use, but I wanted the flexibility to create a High/Low bands chart, and use more advanced formatting.
I've read the uPlot guide (which Time Plot Raw uses), and have got the basic framework working.

chart

But, in the Time Plot node, the chart values appear as a pop-up when hovering over the datapoints, but I can't get my head around how to do that with Time Plot Raw.
Not sure if it's a flexdash limitation, or my bad!

snip

I've googled, and even tried to reverse engineer the Time Plot node, but the code is difficult to follow...

Anyone any ideas? I've attached a small working flow of my work so far (flexdash nodes required).

[{"id":"81d402139aaaa9bf","type":"inject","z":"1543d308b342690a","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"[[1670007600,4,5,3],[1670011200,5.02,5.08,4.78],[1670014800,5.1,5.14,4.92],[1670018400,4.41,5.1,4.32],[1670022000,4.84,4.91,4.41],[1670025600,4.67,4.84,4.6],[1670029200,4.55,4.67,4.51],[1670032800,4.61,4.67,4.55],[1670036400,4.39,4.61,4.19],[1670040000,4.39,4.43,4.3],[1670043600,4.33,4.49,4.27],[1670047200,4.67,4.68,4.33],[1670050800,4.78,4.89,4.67],[1670054400,4.51,4.78,4.47],[1670058000,5.19,5.23,4.51],[1670061600,5.93,5.94,5.19],[1670065200,6.65,6.68,5.93],[1670068800,6.93,7.01,6.65],[1670072400,7.21,7.25,6.93],[1670076000,7.02,7.21,6.97],[1670079600,6.75,7.02,6.74],[1670083200,6.09,6.75,6.04],[1670086800,5.56,6.09,5.48],[1670090400,5.24,5.56,5.22],[1670094000,4.77,5.24,4.75]]","payloadType":"json","x":275,"y":2145,"wires":[["8be74ea01231dfab"]]},{"id":"8be74ea01231dfab","type":"change","z":"1543d308b342690a","name":"","rules":[{"t":"set","p":"options","pt":"msg","to":"{\"series\":[{},{\"label\":\"Temp\",\"stroke\":\"purple\",\"width\":1,\"dash\":[10,5],\"value\":\"degC\",\"scale\":\"temp\"},{\"label\":\"MaxTemp\",\"stroke\":\"red\",\"scale\":\"temp\"},{\"label\":\"MinTemp\",\"stroke\":\"green\",\"scale\":\"temp\"}],\"bands\":[{\"series\":[2,1],\"fill\":\"rgba(255,0,0,0.1)\"},{\"series\":[1,3],\"fill\":\"rgba(0,255,0,0.1)\"}],\"axes\":[{},{\"scale\":\"temp\",\"grid\":{\"show\":true}}],\"ticks\":{\"show\":true,\"stroke\":\"#eee\",\"width\":2,\"dash\":[],\"size\":10}}","tot":"json"},{"t":"set","p":"title","pt":"msg","to":"Time Plot Raw - High/Low bands example","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":435,"y":2145,"wires":[["63f87178b139ec44","d94c6b4c7d22e8e7"]]},{"id":"d94c6b4c7d22e8e7","type":"debug","z":"1543d308b342690a","name":"debug 23","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":2180,"wires":[]},{"id":"63f87178b139ec44","type":"fd-time-plot-raw","z":"1543d308b342690a","fd_container":"a2fd476acabc61e3","fd_cols":"6","fd_rows":"4","fd_array":false,"fd_array_max":10,"name":"","title":"","popup_info":"","options":"","data":null,"x":670,"y":2145,"wires":[]},{"id":"a2fd476acabc61e3","type":"flexdash container","name":"Weather","kind":"StdGrid","fd_children":",6916febb69369323,754b848b6afed702,2876ba66ff2679bb,43aefa2fadb84bae,7c544937f1551351,a740e629dee0d44b,dbdb33e6290c28b1,ca21852cd51c24f5,0d31953fbe4bf5da,403cac5059d3b463,6149f97eab3c8c6b,d1cbbc0e8b5f919d,63f87178b139ec44","title":"","tab":"1839949e733ccb05","min_cols":"1","max_cols":"20","parent":"69c2e3f5798c3475","solid":false,"cols":"1","rows":"1"},{"id":"1839949e733ccb05","type":"flexdash tab","name":"Weather","icon":"mdi-weather-night-partly-cloudy","title":"","fd_children":",a2fd476acabc61e3","fd":"e8f5aea52ab49500"},{"id":"69c2e3f5798c3475","type":"flexdash container","name":"Energy","kind":"StdGrid","fd_children":",43719d5359575f6b,bb113511ea8e41fd,3a60132d9af9f863,6201d0ac747c461c,69906bafd65a0c83,75c16f30cf7f4718,f38aa8e4f00caf79","title":"","tab":"fef6c0f6d48841d6","min_cols":"8","max_cols":10,"parent":"","solid":false,"cols":"1","rows":"1"},{"id":"fef6c0f6d48841d6","type":"flexdash tab","name":"Energy","icon":"mdi-home-lightning-bolt-outline","title":"","fd_children":",69c2e3f5798c3475","fd":"e8f5aea52ab49500"}]
1 Like

The on-hover tooltip is done in TimePlotRaw, so you should be seeing it. I'll try to take a look tomorrow, it's now time for some sleep for me...

Took a quick look anyway, the problem is

"value": "degC",

in one of your series. An error is printed in the browser console. The value field is supposed to be a function that prints the value. You can pass a string that gets eval'd to a function. I recommend leaving it out 'til you have the basics working.

Yes, that's what I'm having problems with.
The uPlot examples shows something like;

value: (u, v) => v == null ? "-" : v.toFixed(1) + "°C"

Ahh OK.

"value": "v.toFixed(1)", does work, but I get errors trying to include the full function above, especially including "-" and "°C", as it results in errors.

1 Like

That's because I haven't documented how that stuff works in TimePlotRaw, plus the function signatures have changed in uPlot, plus ... :roll_eyes:

For reference, the code in TimePlotRaw that does the string-to-function conversion is:

        // if we got a value formatting function we need to 'eval' it
        if (typeof serie.value === 'string') {
          serie.value = new Function('u', 'v', `"use strict";return (${serie.value})`)
          // handle point fill for dark mode
          if (this.is_dark) {
            if (!serie.points) serie.points = {}
            if (!serie.points.fill) serie.points.fill = '#1e1e1e'
          }
        }

where u is a handle onto uPlot, and v is the value. There's similar code a few lines down for axes[i].values and again for scales[i].range.

so what believe you want is:

"value": "v.toFixed(1)+'°C'",

and then probably for your Y axis you want:

    "axes": [
        {},
        {
            "scale": "temp",
            "values": "vv.map(v=>v&&(v.toFixed(1)+'°C'))",
            "grid": {
                "show": true
            }
        }
    ],

Here vv is the array of values used in the scale, and it's possible for values to be null (I believe for tick marks that don't have a value shown).

Obvious, huh? :joy:

NB: looking at this, I should perhaps change v to value and vv to values so the json reads more naturally. Or perhaps that just adds one more level of confusion...

Thanks for the help, and both are displaying OK now.
I'll post my flow below, in case it helps others.
(Do you want a PR to add it to node-red-fd-corewidgets as an example??)

Most of the uPlot examples use v, so yes changing it to values may confuse users (like me :roll_eyes:)

[{"id":"81d402139aaaa9bf","type":"inject","z":"1543d308b342690a","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"[[1670007600,4,5,3],[1670011200,5.02,5.08,4.78],[1670014800,5.1,5.14,4.92],[1670018400,4.41,5.1,4.32],[1670022000,4.84,4.91,4.41],[1670025600,4.67,4.84,4.6],[1670029200,4.55,4.67,4.51],[1670032800,4.61,4.67,4.55],[1670036400,4.39,4.61,4.19],[1670040000,4.39,4.43,4.3],[1670043600,4.33,4.49,4.27],[1670047200,4.67,4.68,4.33],[1670050800,4.78,4.89,4.67],[1670054400,4.51,4.78,4.47],[1670058000,5.19,5.23,4.51],[1670061600,5.93,5.94,5.19],[1670065200,6.65,6.68,5.93],[1670068800,6.93,7.01,6.65],[1670072400,7.21,7.25,6.93],[1670076000,7.02,7.21,6.97],[1670079600,6.75,7.02,6.74],[1670083200,6.09,6.75,6.04],[1670086800,5.56,6.09,5.48],[1670090400,5.24,5.56,5.22],[1670094000,4.77,5.24,4.75]]","payloadType":"json","x":275,"y":2145,"wires":[["8be74ea01231dfab"]]},{"id":"8be74ea01231dfab","type":"change","z":"1543d308b342690a","name":"","rules":[{"t":"set","p":"options","pt":"msg","to":"{\"series\":[{},{\"label\":\"Temp\",\"stroke\":\"purple\",\"width\":1,\"dash\":[10,5],\"value\":\"v.toFixed(1)+'°C'\",\"scale\":\"temp\"},{\"label\":\"MaxTemp\",\"stroke\":\"red\",\"value\":\"v.toFixed(1)+'°C'\",\"scale\":\"temp\"},{\"label\":\"MinTemp\",\"stroke\":\"green\",\"value\":\"v.toFixed(1)+'°C'\",\"scale\":\"temp\"}],\"bands\":[{\"series\":[2,1],\"fill\":\"rgba(255,0,0,0.1)\"},{\"series\":[1,3],\"fill\":\"rgba(0,255,0,0.1)\"}],\"axes\":[{},{\"scale\":\"temp\",\"values\":\"vv.map(v=>v&&(v.toFixed(1)+'°C'))\",\"grid\":{\"show\":true}}],\"ticks\":{\"show\":true,\"stroke\":\"#eee\",\"width\":2,\"dash\":[],\"size\":10}}","tot":"json"},{"t":"set","p":"title","pt":"msg","to":"Time Plot Raw - High/Low bands example","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":435,"y":2145,"wires":[["63f87178b139ec44","d94c6b4c7d22e8e7"]]},{"id":"d94c6b4c7d22e8e7","type":"debug","z":"1543d308b342690a","name":"debug 23","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":660,"y":2180,"wires":[]},{"id":"63f87178b139ec44","type":"fd-time-plot-raw","z":"1543d308b342690a","fd_container":"a2fd476acabc61e3","fd_cols":"6","fd_rows":"4","fd_array":false,"fd_array_max":10,"name":"","title":"","popup_info":"","options":"","data":null,"x":670,"y":2145,"wires":[]},{"id":"a2fd476acabc61e3","type":"flexdash container","name":"Weather","kind":"StdGrid","fd_children":",6916febb69369323,754b848b6afed702,2876ba66ff2679bb,43aefa2fadb84bae,7c544937f1551351,a740e629dee0d44b,dbdb33e6290c28b1,ca21852cd51c24f5,0d31953fbe4bf5da,403cac5059d3b463,6149f97eab3c8c6b,d1cbbc0e8b5f919d,63f87178b139ec44","title":"","tab":"1839949e733ccb05","min_cols":"1","max_cols":"20","parent":"69c2e3f5798c3475","solid":false,"cols":"1","rows":"1"},{"id":"1839949e733ccb05","type":"flexdash tab","name":"Weather","icon":"mdi-weather-night-partly-cloudy","title":"","fd_children":",a2fd476acabc61e3","fd":"e8f5aea52ab49500"},{"id":"69c2e3f5798c3475","type":"flexdash container","name":"Energy","kind":"StdGrid","fd_children":",43719d5359575f6b,bb113511ea8e41fd,3a60132d9af9f863,6201d0ac747c461c,69906bafd65a0c83,75c16f30cf7f4718,f38aa8e4f00caf79","title":"","tab":"fef6c0f6d48841d6","min_cols":"8","max_cols":10,"parent":"","solid":false,"cols":"1","rows":"1"},{"id":"fef6c0f6d48841d6","type":"flexdash tab","name":"Energy","icon":"mdi-home-lightning-bolt-outline","title":"","fd_children":",69c2e3f5798c3475","fd":"e8f5aea52ab49500"}]

Sure! Having the first PR being from you would be nice! :smiley:

3 Likes

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