Hey, I'm new to Node red and trying to build a dashboard where one of the widgets is a chart that should display electricity prices from Nordpool's API (using node-red-contrib-nordpool-api-plus), updated daily with prices hour by hour from 00 to 23 for the entire day.
I'm processing the data in a function node to present it as "Hour" on the x-axis and "priceperkwh" on the y-axis for all hours of the upcoming day. My issue is that I can't code it so that "priceperkwh" updates with new values that I'm passing to my template. I've used this template to create the chart using chart.js HTML code.
As I mentioned, I'm a beginner and mainly using ChatGPT to create the code. But no matter how I instruct it, I can't come up with code that can receive and update the chart with new values. Does anyone know how I can solve this so that I have a chart that responds to the latest data I send from my function node?
Here's the date from my function-node:
[{"hour":0,"pricePerKwh":55.47},{"hour":1,"pricePerKwh":56.01},{"hour":2,"pricePerKwh":55.99},{"hour":3,"pricePerKwh":57.13},{"hour":4,"pricePerKwh":60.21},{"hour":5,"pricePerKwh":62.79},{"hour":6,"pricePerKwh":63.9},{"hour":7,"pricePerKwh":65.89},{"hour":8,"pricePerKwh":63.63},{"hour":9,"pricePerKwh":60.35},{"hour":10,"pricePerKwh":52},{"hour":11,"pricePerKwh":36.18},{"hour":12,"pricePerKwh":37.14},{"hour":13,"pricePerKwh":18.39},{"hour":14,"pricePerKwh":23.46},{"hour":15,"pricePerKwh":50.55},{"hour":16,"pricePerKwh":74},{"hour":17,"pricePerKwh":81.75},{"hour":18,"pricePerKwh":82.94},{"hour":19,"pricePerKwh":78.96},{"hour":20,"pricePerKwh":74.75},{"hour":21,"pricePerKwh":71.27},{"hour":22,"pricePerKwh":65.99},{"hour":23,"pricePerKwh":60.73}]
Node-RED version: v3.1.8
Node.js version: v20.11.1
Darwin 23.4.0 arm64 LE
Dashboard version 3.6.5 started at /ui
Edit: This reply relates to using the Node-red dashboard chart widget, not chart.js
You need to send your data to the chart node in a specific format:
An array containing a single object with properties "series", "data" and "labels".
"series" is an array of the names of lines on the chart. For a single line, just one element in the array.
"data" is an array of arrays, one array per line on the chart. Each array element is an object with x and y properties to define the points on the line.
"labels" - Actually I'm not sure what labels does, but it is an array of strings, in my experience always an array of one element, an empty string.
Thanks for great help! While I was trying to figure out how to solve it, it seems I messed up somehow in Node red, because now I can't create charts by placing chart.js code in a template node. I've created multiple charts that way before, but now I just get a blank space where the chart should be visible. Any ideas on what I might have done...?
Now I've got the function node processing the data so it looks right I think. But I can't seem to create a chart.js diagram with my template node. Do you see any obvious mistakes in my code?
Here's how my data looks now:
{"series":["Price (SEK)"],"data":[[{"x":0,"y":466.41},{"x":1,"y":466.18},{"x":2,"y":461.8},{"x":3,"y":432.71},{"x":4,"y":421.17},{"x":5,"y":421.17},{"x":6,"y":425.67},{"x":7,"y":464.57},{"x":8,"y":489.03},{"x":9,"y":471.72},{"x":10,"y":432.71},{"x":11,"y":350.76},{"x":12,"y":208.22},{"x":13,"y":231.42},{"x":14,"y":115.77},{"x":15,"y":51.59},{"x":16,"y":47.55},{"x":17,"y":151.78},{"x":18,"y":391.39},{"x":19,"y":421.74},{"x":20,"y":370.96},{"x":21,"y":324.21},{"x":22,"y":48.01},{"x":23,"y":3.81}]],"labels":[""]}
No problem, I actually suspected that, so I tried both the chart node and the template node. At first I figured I would use chart.js code to be able to customize the design more. But right now, I'm just happy if I can create a chart at all. If I use a chart node, do I need to set anything specific in the settings for it to receive the data correctly?
I think I've managed to get the data right now, but still nothing is showing up in my chart. I'm starting to wonder if there's something else fundamental that I've missed. Actually, I reinstalled the entire Node-RED yesterday because I was afraid I messed something up, so I should have a clean installation. This is how the data looks now:
Thanks, that helped me move forward a bit. It seems like there's no need to clear the graph, but I noticed that the line chart works while the bar chart doesn't. Also, shouldn't the values on the x-axis be displayed as 00 - 23 as in the data? I redesigned the flow with my API node, but that shouldn't have any impact on the outcome, right?
Ok, one more step forward. With Vue, I can display a bar chart in Dashboard 1.0 but not in Dashboard 2.0. Is there any difference in how the template node is configured in 2.0, or should the code work in both versions?
Sure, I'll have another look. Is there anything specific in the instructions you think I should focus on to solve my issue with displaying charts in my template node?
You are using the input formatted for a Dashboard 1.0 chart, but you're using Dashboard 2.0.
If you set your msg.topic to be your series name (as you have configured on the chart) and then msg.payload to equal what you currently have as msg.payload.data then it should work
I'm still struggling with my graphs. I think I managed to change the code as you suggested. But there's something weird with my dashboard. I've managed to display one graph with hardcoded values in a template node. But I can't publish any other graphs, not even if I copy the working node and add it to the dashboard with a unique canvas id. I don't know how many 100 graphs I've tried that just show a blank area, so I'm starting to suspect that something else is wrong than just the code for my graphs. I appreciate any help I can get!
This is what my template node looks like now:
<template>
<div>
<canvas id="priceChart" width="800" height="400"></canvas>
</div>
</template>
<script>
import Chart from 'chart.js/auto';
export default {
mounted() {
// Kalla pĂĄ renderChart vid montering
this.renderChart();
},
props: ['chartData'], // Definiera en prop för att ta emot data från överordnad komponent
methods: {
renderChart() {
// Hämta canvas-elementet för diagrammet
var ctx = document.getElementById('priceChart').getContext('2d');
// Skapa ett nytt diagram med Chart.js
var priceChart = new Chart(ctx, {
type: 'bar', // Typ av diagram är stapeldiagram
data: {
// Data för diagrammet
labels: msg.payload.labels, // Skapa labels för timmarna 0 till 23
datasets: [{
label: 'Price (SEK)', // Etikett för dataserien
data: msg.payload.data, // Använd den mottagna datan för y-värdena
backgroundColor: 'rgb(75, 192, 192)', // Bakgrundsfärg för staplarna
borderColor: 'rgb(54, 162, 235)', // Kantfärg för staplarna
borderWidth: 1 // Bredd på kanten för staplarna
}]
},
options: {
responsive: true, // Göra diagrammet responsivt
scales: {
x: {
title: {
display: true,
text: 'Hour of the day' // Text för x-axeln
}
},
y: {
title: {
display: true,
text: 'Price (SEK)' // Text för y-axeln
},
beginAtZero: true // Börja y-axeln vid noll
}
}
}
});
}
}
};
</script>
<style>
/* Här kan du lägga till CSS-stilar om det behövs */
</style>
Your running your renderChart on mounted, i.e. when the chart first renders, at that point though, there is no data available in msg.payload until a new message is received.
You'd be best off defining your Chart structure, etc, then add a socket listener for watching msg-input and then add your fata to the chart accordinlgy