How to create charts similar to PowerBI using node-red

Hello everyone

I need to understand if it's possible, and then how, to create something similar with this:

using node-red. I already did some research and didn't find anything similar.

Appreciate all the help.


Sadly, Microsoft have $$bn's to spend on their services whereas Node-RED is open source and reliant on contributors for many of its features.

So the really short answer is - no, nothing like that exists for Node-RED right now.

For a longer answer, you may need to apply some lateral thinking. PowerBI and its sister capabilities in Microsoft Excel utilise components that are data-driven. With Node-RED, you will need to think about the data and the display side a bit more independently.

Data handling not too much of an issue for Node-RED since it is based on Node.js and so can draw upon a great many libraries if needed.

The display side is a little more challenging at present. As effectively a web application server, node-red relies on one of a number of dashboard/web-UI contributed nodes. Currently the easiest to use is "Dashboard" which uses a very complex front-end which is incredibly easy to install and use with no web development knowledge needed. However, without the web dev knowledge, you are limited to what Dashboard features already exist. It is also pretty much dependent on a library which is already end-of-life. One or two other similar projects have started, of which Flexdash seems the most promising at present though it is still in beta.

Then there is my own uibuilder but that takes a different approach and would require some preparation for things like advanced charting that I don't currently have time to pursue - though the WIKI has a number of examples that show how to integrate uibuilder with various chart libraries and those have been successfully used as the basis for web apps over quite a few years now. Still, there is no avoiding that with uibuilder, you have a bit more work to do up front in order to get a working dashboard. Though you could certainly use one of the online web-page designers to design the basic page framework and then easily use node-red and uibuilder to make the page dynamic. That turns out to be fairly easy and will get even easier with the next release of uibuilder which is imminent.

Bottom line is that an open source produce will rarely be able to compete directly in terms of ease of use with one that has billions of commercial dollars invested in it. However, Node-RED does have some advantages. Not only the price of course! Which will partially be offset by the people resources needed to make it do what you want. But also the fact that it is web native which PowerBI (and you should note that I regularly use both PowerBI and Excel at work) PowerBI really isn't - though it hides the fact to people who view the output.

Hope that at least explains the background. Happy to discuss further.


I already expected an answer saying that there is no easy way to accomplish this.

My question now is, how to make the graph clickable for the user so that this event triggers a new query that will change the data of the other graphs on the same page. This is being my problem at the moment, because I confess that I don't even know where to start right now. I'm going to check your suggestion to use uibuilder and try to do this functionality of leaving the graph dynamic little by little.

Thank you so much for your answer!

I'm having the same problem as ppennachi. Mainly the interaction of the graphics. I've already found some materials that manage to make, for example, the bar become clickable and that applies a filter (as can be seen here: Getting Started – Chart JS Video Guide). I tried to replicate this in node, but I have no success, because the "canva" and "onclick" functions are not recognized by node-red. So my question is: is there a way to use these functions? A library that pulls this JS functionality?

The ui_chart node cant be used for such kind of interactions. But you can use the underlying library to create chart from scratch and then you have control over it. Of course it takes to create or modify many of chart options to make that chart again look and feel like ui_chart node does or why not even better.

To get started - here's an example of bar chart with clickable bars

[{"id":"d58b635f1bfdaa7f","type":"ui_template","z":"09deee63c1b960f7","group":"6efcc19883dcdf68","name":"","order":0,"width":"24","height":"20","format":"<div class=\"chart-container\" style=\"position: relative; height:40vh; width:50vw\">\n    <canvas id=\"myChart\"></canvas>\n</div>\n\n<script>\n(function(scope) {\n\nconst ctx = document.getElementById('myChart').getContext('2d');\nconst barchart = new Chart(ctx, {\n    type: 'bar',\n    data: {\n        labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],\n        datasets: []\n    },\n    options: {\n        events: ['mouseup'],\n        interaction: {\n        mode: 'index',\n        axis: 'y'\n        },\n        onClick: (e) => {\n            if(e.type ==\"mouseup\"){\n                const el = barchart.getElementAtEvent(e)\n                console.log(el)\n                if(el && el[0] && el[0]._view){\n                    const label = el[0]._view.label\n                    const val =[0].data[el[0]._index]\n                    scope.send({payload:{label:label,data:val},topic:\"Click_on_chart_bar\"})\n                }\n            }\n        },\n        scales: {\n            y: {\n                beginAtZero: true\n            }\n        },\n        responsive: true,\n    }\n});\n\n\n// update chart data \n  function addData(chart, data) {\n = []\n\n    chart.update();\n}\n  \n// watch for msg\nscope.$watch('msg', (msg) => {\n   if (msg) {\n      // Do something when msg arrives\n     addData(barchart, msg.payload)\n    }\n})\n\n\n})(scope)\n\n</script>","storeOutMessages":false,"fwdInMessages":false,"resendOnRefresh":false,"templateScope":"local","className":"","x":520,"y":1660,"wires":[["0869cd746de10613"]]},{"id":"53e059241791ed04","type":"inject","z":"09deee63c1b960f7","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":true,"onceDelay":0.1,"topic":"","payload":"true","payloadType":"bool","x":230,"y":1660,"wires":[["17c879d6076d6411"]]},{"id":"17c879d6076d6411","type":"function","z":"09deee63c1b960f7","name":"Chart Data","func":"msg.payload = {\n    label: '# of Votes',\n    data: [\n        12 + Math.random() * 2,\n        19 + Math.random() * 2,\n        3 + Math.random() * 2,\n        5 + Math.random() * 2,\n        2 + Math.random() * 2,\n        3 + Math.random() * 2],\n    backgroundColor: [\n        'rgba(255, 99, 132, 0.2)',\n        'rgba(54, 162, 235, 0.2)',\n        'rgba(255, 206, 86, 0.2)',\n        'rgba(75, 192, 192, 0.2)',\n        'rgba(153, 102, 255, 0.2)',\n        'rgba(255, 159, 64, 0.2)'\n    ],\n    borderColor: [\n        'rgba(255, 99, 132, 1)',\n        'rgba(54, 162, 235, 1)',\n        'rgba(255, 206, 86, 1)',\n        'rgba(75, 192, 192, 1)',\n        'rgba(153, 102, 255, 1)',\n        'rgba(255, 159, 64, 1)'\n    ],\n    borderWidth: 1\n};\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":370,"y":1660,"wires":[["d58b635f1bfdaa7f"]]},{"id":"0869cd746de10613","type":"debug","z":"09deee63c1b960f7","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":670,"y":1660,"wires":[]},{"id":"6efcc19883dcdf68","type":"ui_group","name":"Chart JS","tab":"39a6d442788cfb84","order":1,"disp":true,"width":"24","collapse":false,"className":""},{"id":"39a6d442788cfb84","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

With Amcharts you can do quite easily.

Of course there is many charting libraries you can use. And most of them offer such features. Still none of them will do it as base functionality by magic. It takes to write the code and for every library it is a bit different.

But the outcome is that you have 2 charting libraries gaining weight for your dashboard and as it is heavy enough by itself I can't just see any reason to do it unless you really use some kind of very edge functionality or some sort of not basic chart type.

Click on chart element and send the payload with some data is basic stuff. Just the option to use it is not natively supported by chart node. So it takes to use existing library with a bit more advanced way.

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