Adding multiple series with different axis to chart

Hi All

I want to display a chart for my heating. Ideally I would like the chart to have:

  • Current Temperature
  • Set Temperature
  • Heating Effort

Current Temperature and set temperature can obviously share the same axis as they are both temperature but heating effort (a percentage) is a different scale and if plotted on the same axis as temperature will mean that the graph will go from 0 - 100 and any temperature changes (in degrees C) will be hard to make out on a scale that is too large.

Is there any support for having a mixed bar graph and line graph or support for different axis like this?

Thanks

May be you can find something useful from this thread

Or more advanced use case from here

brilliant, thanks very much.

Thanks for your reply @hotNipi and thanks for the original posts that you made about this. I have used your Multi Axis example and got a working multi axis chart but I am trying to understand why it has been done this way and how to manage the data that will be pushed to the chart over time.

Firstly why is the template in a template node and not in the chart node? I tried moving the template to the dashboard template node (and removed the curly braces from the template) and nothing appeared.

Secondly how do I push data to the chart? I assume that I will have 2 inputs to the node. One for the template and one for the time based data. Does the dashboard node collate and store the data from the messages that I can then display in my chart template? What about discarding older messages?

Perhaps I am hoping for too much and have to store all the previously received data in a function node and manage it myself and the re-generate the template from scratch each time using the stringify approach that you have.

Once again, many thanks.

Because of native chart node is good for basic charting, but whenever you need to go beyond basics, the only possible way is to use the underlying charjs library directly. (Well you can use any JavaScript charting library you can find. I use same library the standard chart node uses because of most questions about how to do this or that can be solved with it. )

The ui_template node is here to give option to build something on top of ray JavaScript libraries.
Using the template node to prepare and feed content to ui_template node just simplifies codding. That may not be true for everybody of course. The Mustache may be confusing if you haven't worked with it before and that is partially true even for me :slight_smile: . But why not to learn a bit.
But of course same thing can be written into ui_template directly, just the data manipulation will be different.

Example of handling live data:

[{"id":"26d66b9b.186034","type":"ui_template","z":"82bb9cb4.29b64","group":"304730.1de8e8d","name":"Line Chart","order":4,"width":"15","height":"10","format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":710,"y":300,"wires":[[]]},{"id":"29e44bca.6d2594","type":"inject","z":"82bb9cb4.29b64","name":"","repeat":"5","crontab":"","once":false,"onceDelay":"0.62","topic":"","payload":"","payloadType":"date","x":350,"y":270,"wires":[["98fd0130.0550d"]]},{"id":"98fd0130.0550d","type":"function","z":"82bb9cb4.29b64","name":"fake live data","func":"msg.payload = {}\nmsg.payload.first = Math.random() * 300\nmsg.payload.second = -2.5 + Math.random() * 5\nreturn msg;\n","outputs":1,"noerr":0,"x":510,"y":270,"wires":[["26d66b9b.186034"]]},{"id":"55e9c5a5.e31f0c","type":"template","z":"82bb9cb4.29b64","name":"","field":"template","fieldType":"msg","format":"html","syntax":"mustache","template":"<canvas id=\"myChart\" width=600 height =300></canvas>\n<script>\nvar textcolor = getComputedStyle(document.documentElement).getPropertyValue('--nr-dashboard-widgetTextColor');\nvar gridcolor = getComputedStyle(document.documentElement).getPropertyValue('--nr-dashboard-groupBorderColor');\nvar linecolors = ['#009900','#889900']\nvar maxDataPoints = 20\n\nvar ctx = document.getElementById('myChart').getContext('2d');\nvar chart = new Chart(ctx, {\n    // The type of chart we want to create\n    type: 'line',\n\n    // The data for our dataset\n    data: {\n        labels: [],\n        datasets: [\n            {\n                label: 'first',\n                backgroundColor: linecolors[0],\n                borderColor: linecolors[0],\n                data: [],\n                yAxisID: 'left-y-axis',\n                steppedLine: true,\n                fill: false,\n                borderWidth: 1\n            },\n            {\n                label: 'second',\n                backgroundColor: linecolors[1],\n                borderColor: linecolors[1],\n                data: [],\n                yAxisID: 'right-y-axis',\n                steppedLine: false,\n                fill: false,\n                borderWidth: 1\n            }\n        ]\n    },\n\n    // Configuration options go here\n    options: {\n        scales: {\n            yAxes: [\n                {\n                    gridLines :{display:false},\n                    id: 'left-y-axis',\n                    type: 'linear',\n                    position: 'left',\n                    ticks: {\n                        fontColor: linecolors[0]\n                    }\n                },\n                {\n                    gridLines :{zeroLineColor:gridcolor,color:gridcolor,lineWidth:0.5},\n                    id: 'right-y-axis',\n                    type: 'linear',\n                    position: 'right',\n                    ticks: {\n                        fontColor:linecolors[1]\n                    }\n                }\n            ],\n            xAxes: [\n                {\n                    gridLines :{zeroLineColor:gridcolor,color:gridcolor,lineWidth:0.5},\n                    type: 'time',\n                    distribution: 'series',\n                    time:{\n                        displayFormats: {\n                            quarter: 'MMM YYYY',\n                            millisecond:'h:mm:ss',\n                            second:\t'h:mm:ss',\n                            minute:\t'h:mm',\n                            hour:\t'h'                        \n                        }\n                    },\n                    \n                    ticks: {\n                        fontColor:textcolor\n                    }\n                }\n            ]\n        }\n    }\n});\nfunction addData(chart, data, label) {\n    chart.data.datasets.forEach((dataset) => {\n        if(dataset.label == label){\n            dataset.data.push(data);\n        }\n        if(dataset.data.length > maxDataPoints){\n            dataset.data.shift()\n        }\n    });\n    chart.update(0);//0 means no animation\n}\n(function(scope) {\n  scope.$watch('msg', function(msg) {\n    if (msg) {\n      // Do something when msg arrives\n      addData(chart,{x:new Date(),y:msg.payload.first},\"first\")\n      addData(chart,{x:new Date(),y:msg.payload.second},\"second\")\n\n    }\n  });\n})(scope);\n</script>\n","output":"str","x":500,"y":330,"wires":[["26d66b9b.186034"]]},{"id":"bf7ecf9e.8f61f","type":"inject","z":"82bb9cb4.29b64","name":"","repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":350,"y":330,"wires":[["55e9c5a5.e31f0c"]]},{"id":"304730.1de8e8d","type":"ui_group","name":"Chart","tab":"ebf9c239.14c15","order":3,"disp":true,"width":"15","collapse":false},{"id":"ebf9c239.14c15","type":"ui_tab","name":"Ovens","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Thanks again. I am not bothered by the moustache syntax - I assume it works in much the same way as {{ does in angular. I am just trying to figure out why it doesn't work when doing it without the template node.
Your example of handling live data doesn't work for me. In fact it is very similar to what I tried by myself. I get no chart appearing at all.

Aha, the issue was that no labels had been defined. Fixed here:

[{"id":"9807f246.fdf94","type":"ui_template","z":"4e687c89.ebe754","group":"d64d0f44.4e899","name":"Line chart no template","order":4,"width":"15","height":"10","format":"<canvas id=\"myChart\" width=600 height =300></canvas>\n<script>\nvar textcolor = getComputedStyle(document.documentElement).getPropertyValue('--nr-dashboard-widgetTextColor');\nvar gridcolor = getComputedStyle(document.documentElement).getPropertyValue('--nr-dashboard-groupBorderColor');\nvar linecolors = ['#FF0000','#00FF00']\n\nvar ctx = document.getElementById('myChart').getContext('2d');\nvar chart = new Chart(ctx, {\n    // The type of chart we want to create\n    type: 'bar',\n\n    // The data for our dataset\n    data: {\n        labels: [\"one\", \"two\", \"three\", \"four\", \"five\", \"six\", \"seven\", \"eight\", \"nine\", \"ten\"],\n        datasets: [\n            {\n                type:'line',\n                label: 'First',\n                backgroundColor: linecolors[0],\n                borderColor: linecolors[0],\n                data: Array.from({length: 10}).map(() => Math.random()),\n                yAxisID: 'left-y-axis',\n                steppedLine: false,\n                fill: false,\n                borderWidth: 1\n            },\n            {\n                type:'bar',\n                label: 'Second',\n                \n                backgroundColor: linecolors[1],\n                borderColor: linecolors[1],\n                data: Array.from({length: 10}).map(() => Math.random()),\n                yAxisID: 'right-y-axis',\n                barPercentage: 0.5,\n                barThickness: 6,\n                maxBarThickness: 8,\n                minBarLength: 2,\n            }\n        ]\n    },\n\n    // Configuration options go here\n    options: {\n        scales: {\n            yAxes: [\n                {\n                    gridLines :{display:false},\n                    id: 'left-y-axis',\n                    type: 'linear',\n                    position: 'left',\n                    ticks: {\n                        fontColor: linecolors[0]\n                    }\n                },\n                {\n                    gridLines :{zeroLineColor:gridcolor,color:gridcolor,lineWidth:0.5},\n                    id: 'right-y-axis',\n                    type: 'linear',\n                    position: 'right',\n                    ticks: {\n                        fontColor:linecolors[1]\n                    }\n                }\n            ],\n            xAxes: [\n                {\n                    gridLines :{zeroLineColor:gridcolor,color:gridcolor,lineWidth:0.5},\n                    \n                    ticks: {\n                        fontColor:textcolor\n                    }\n                }\n            ]\n        }\n    }\n});\n</script>\n","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":false,"templateScope":"local","x":780,"y":580,"wires":[[]]},{"id":"d64d0f44.4e899","type":"ui_group","z":"","name":"Chart","tab":"dd54d96a.57e058","order":3,"disp":true,"width":"15","collapse":false},{"id":"dd54d96a.57e058","type":"ui_tab","z":"","name":"Ovens","icon":"dashboard","order":1,"disabled":false,"hidden":false}]
2 Likes