Problems with ui_value_trail

Hello,

I think that's a question for hotNipi. There are some problems with ui_value_trail. I'm currently working on a wireless battery sensor project. To save energy, the sensors only send a value when it has changed. To get a constant trail, I store the values in a variable and output them with a timestamp every 10 seconds. When restarting, a zero is first injected into the variable. Now there are the following problems:

1.The trail only appears when the value changes for the first time. Otherwise the display remains blank.

2.If the voltage value does not change for a longer time, the trail is only displayed until the last change has reached the end of the display window. Then the display remains blank until the next change in the voltage value.

I think both problems have the same cause. Is it possible to modify the node to eleminate this behavior?

Regards
Manfred

If you read the nodes readme page, it says (or at least tries to say) that the widget is created to behave like this. There is many reasons for that but for most - it is not replacement for the line chart. And it does work only for live data.
And there isn't any plans to improve in therms of supporting historical data or having time component involved.

That's a pity, because line chart is not suitable for me. I have designed the gauges and the chart very small for iPhone application (only 2x1). Line charts need more space for labeling of the x and y axis. I cannot use it.

Well, I'm still with my statements. The value-trail node will not change.

But to draw the line to represent value changing, it is relatively easy task. With the d3 library it takes not too many code lines to draw chart line. Fits nicely into 2x1, no need for any ticks or rendered scales.

[{"id":"3781ad0a.887972","type":"ui_template","z":"f56ccabd.7567e8","group":"a1b48177.63b91","name":"d3 line","order":3,"width":"2","height":"1","format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":690,"y":780,"wires":[[]]},{"id":"72a60b38.b58f44","type":"ui_template","z":"f56ccabd.7567e8","group":"a1b48177.63b91","name":"load d3 script","order":4,"width":0,"height":0,"format":"<script src=\"https://d3js.org/d3.v4.js\"></script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","x":630,"y":740,"wires":[[]]},{"id":"c74fa282.368c4","type":"function","z":"f56ccabd.7567e8","name":"","func":"var s = context.get(\"s\") || []\nif(msg.payload == \"init\"){\n    s = []\n    context.set(\"s\",s)\n    return\n}\n\nvar a = [new Date().getTime(),msg.payload]\ns.push(a)\n\nif(s.length > 10){\n    s.shift()\n}\n\ncontext.set(\"s\",s)\n\nif(s.length < 2){\n    return\n}\nmsg.payload = JSON.stringify(s);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":420,"y":780,"wires":[["87219e8d.5a505"]]},{"id":"87219e8d.5a505","type":"template","z":"f56ccabd.7567e8","name":"","field":"template","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<div id=\"charting\" ></div>\n<style type =\"text/css\">\n#charting{\n    width:100%;\n    height:100%;\n}\n.linestyle {\n    fill: none !important;\n    stroke: teal;\n    stroke-width: 2px;\n}\n</style>\n<script>\n  var w = 96;\n  var h = 40;\n  var svg = d3.select(\"#charting\").append(\"svg\").attr(\"width\", w).attr(\"height\", h);\n  var dataset = {{payload}}\n  var xScale = d3.scaleTime().domain([d3.min(dataset, d => d[0]), d3.max(dataset, d => d[0])]).range([0, w]);\n  var yScale = d3.scaleLinear().domain([d3.min(dataset, d => d[1]), d3.max(dataset, d => d[1])]).range([h, 0]);\n  var mylinegen = d3.line().x(d => xScale(d[0])).y(d => yScale(d[1]));\n  svg.append(\"path\").datum(dataset).attr(\"d\", mylinegen).attr(\"class\", \"linestyle\");\n</script>","output":"str","x":560,"y":780,"wires":[["3781ad0a.887972"]]},{"id":"abb6982c.d189b8","type":"random","z":"f56ccabd.7567e8","name":"","low":1,"high":10,"inte":"true","property":"payload","x":280,"y":780,"wires":[["c74fa282.368c4"]]},{"id":"348e8971.09c126","type":"ui_button","z":"f56ccabd.7567e8","name":"","group":"a1b48177.63b91","order":5,"width":0,"height":0,"passthru":false,"label":"add random to chart","tooltip":"","color":"","bgcolor":"","icon":"","payload":"","payloadType":"str","topic":"topic","topicType":"msg","x":280,"y":720,"wires":[["abb6982c.d189b8"]]},{"id":"a1b48177.63b91","type":"ui_group","name":"Default","tab":"c122ecdc.526d7","order":1,"disp":true,"width":"6","collapse":false},{"id":"c122ecdc.526d7","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]
1 Like

Thank you very much for this hints. But I have some questions:

  1. There is a node that loads code from d3js.org. Is it possible to implement this code in my application permanent? I'm afraid that someday the external source will change or go away and then I'll have a problem.

  2. It seems it works only with integer values. My values have one decimal place and when I inject it doesn't work.

  3. Wher can I adjust the time base for the x-axis?

  4. Is it possible to show the min and max values left at the y-axis as showed on the screenshot?

The example I made is really very basic what you can do with the d3.js. And the loaded library is kind of old. But as the example is basic, it is good enough. Of course, things can change over the time and to prevent all such issues, you can find the script to download and serve it from your static folder. It also makes your setup to be fully working if offline.
But the d3 is pretty trustful thing.

I think you missing something somewhere. It works fully with any number.

That really depends on your intentions.
There is no time base adjustment in my example but I limited the amount of data-points to be 10. It is in the function node before the template node.

if(s.length > 10){
    s.shift()
}

But there is the beauty of the solution - you can do it in the way you like.
For example filter the array in the way that the older than current moment (timestamp) minus the desired period of time (in milliseconds) will be thrown away.

Absolutely. The min and max values can be asked from d3 (or you can calculate and send them in with the msg) and all you need to do is to create div or span elements for them to be displayed. (a bit HTML and CSS)

Actually I was prepared for questions like - "can the line be curved ..." :wink:

I found the problem number 2. The values come from a mqtt broker and this is always a string an not a number. After I change string to number it works properly.
It seems that d3.js is a powerful tool, but there is a lot of documentation to read and I don't have time now. So i will use your value_trail for now and improve it in the future.

1 Like

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