Good Day, i need some help please new to node-red, i have managed to bring in google charts in Dashboard 2.0 using a ui-template node. With in the code i would like to inject my values. But i have been unable to find a way to pull variables from the msg.payload i send to the ui-template.
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', {'packages':['corechart', 'bar']});
google.charts.setOnLoadCallback(drawStuff);
function drawStuff() {
//var button = document.getElementById('change-chart');
var chartDiv = document.getElementById('chart_div');
*Would like to inject my values*
var data = google.visualization.arrayToDataTable([
['Galaxy', 'Distance', 'Brightness'],
['Canis Major Dwarf', 8000, 23.3],
['Sagittarius Dwarf', 24000, 4.5],
['Ursa Major II Dwarf', 30000, 14.3],
['Lg. Magellanic Cloud', 50000, 0.9],
['Bootes I', 60000, 13.1]
]);
var materialOptions = {
width: 900,
chart: {
title: 'temp', *Would like to inject my values*
subtitle: 'distance on the left, brightness on the right'
},
series: {
0: { axis: 'distance' }, // Bind series 0 to an axis named 'distance'.*Would like to inject my values*
1: { axis: 'brightness' } // Bind series 1 to an axis named 'brightness'.*Would like to inject my values*
},
axes: {
y: {
distance: {label: 'parsecs'}, // Left y-axis.*Would like to inject my values*
brightness: {side: 'right', label: 'apparent magnitude'} // Right y-axis.*Would like to inject my values*
}
}
};
function drawMaterialChart() {
var materialChart = new google.charts.Bar(chartDiv);
materialChart.draw(data, google.charts.Bar.convertOptions(materialOptions));
button.innerText = 'Change to Classic';
button.onclick = drawClassicChart;
}
function drawClassicChart() {
var classicChart = new google.visualization.ColumnChart(chartDiv);
classicChart.draw(data, classicOptions);
button.innerText = 'Change to Material';
button.onclick = drawMaterialChart;
}
drawMaterialChart();
};
</script>
</head>
<body>
<br><br>
<div id="chart_div" style="width: 800px; height: 500px;"></div>
</body>type or paste code here
Any point in the right direction would be appreciated.
So this isn't a full solution, but does show how you can transfer some of the behaviour you have into a Vue Component with ui-template such that you can get easy access to the msg.payload value:
<template>
<div ref="g-chart"></div>
</template>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script>
export default {
mounted () {
// code runs here when the component is first loaded
let interval = setInterval(() => {
if (window.google) {
// call a draw function to utilise the Google Charts library
draw();
// Google Charts has loaded now, so we can use it
clearInterval(interval);
}
}, 100);
},
watch: {
value: {
// watch the "value" of the template node,
// which under the covers in ui-template is msg.payload
handler: function (payload) {
// update your chart with some data
var data = window.google.visualization.arrayToDataTable(payload);
// ... do something with data
// e.g. this.draw()
},
deep: true
}
},
methods: {
draw: function () {
// ensure we have persistent access to the vue object,
// even inside our own function () { ... } definitions where this. is re-assigned
const vue = this
// easier reference to window.google object
const google = window.google
// ... draw the chart and use vue.value which will be the latest received msg.payload
}
}
}
</script>
I've not transferred everything over, but have tried to at least offer the scaffolding. I had issues whereby window.google.visualization is coming back undefined, but that'll be a Google Charts problem rather than something I can help with.
Sorry to bother you again with this, but i have been unable to get this code to work. I have been through 20+ iteration, but just end up with errors. My understanding of the coding is very bad.
<template>
<div id="chart_div" style="width: 100%; height: 300px;"></div>
</template>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script>
export default {
data: {
value: 0, // Initial value
chartData: [['Category', 'Value'], ['Initial', 0]] // Initial chart data
},
mounted : function() {
// Load Google Charts library
google.charts.load('current', {'packages':['corechart']});
// Set a callback function to draw the chart when the library is loaded
google.charts.setOnLoadCallback(this.drawChart);
},
watch: {
value: function(newValue) {
// Update chart data when value changes
this.chartData[1][1] = newValue;
// Redraw the chart
this.drawChart();
}
},
methods: {
// Method to draw or redraw the chart
drawChart: function() {
var data = google.visualization.arrayToDataTable(this.chartData);
var options = {
title: 'My Chart',
width: '100%',
height: 300
};
var chart = new google.visualization.ColumnChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
}
}
</script>
Hey @jwj001 not going to get a chance to dive into this heavily today, but a quick pointer is the content of your mounted:
// Load Google Charts library
google.charts.load('current', {'packages':['corechart']});
// Set a callback function to draw the chart when the library is loaded
google.charts.setOnLoadCallback(this.drawChart);
The google script would likely not have loaded at this point, as mounted runs as soon as the page loads, not necessarily, once your <script /> tag has fully loaded the Google Charts library.
Instead, you'll want to make the most of the interval I provided above, which checks when when the google charts library has loaded. Reasoning for this piece of code is justified in the docs here
Thanks for the assist i managed to get it going...
<template>
<div>
<div id="columnchart_material" style="width: 1200px; height: 600px;"></div>
</div>
</template>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script>
export default {
mounted () {
// Load Google Charts library
google.charts.load('current', {'packages':['bar']});
// Set a callback function to draw the chart when the library is loaded
google.charts.setOnLoadCallback(this.drawChart);
},
watch: {
value: {
// Watch the "value" of the template node,
// which under the covers in ui-template is msg.payload
handler: function (payload) {
// Update your chart with the new data
this.updateChart(payload);
},
deep: true
}
},
methods: {
drawChart: function () {
// Default data for the chart
var data = google.visualization.arrayToDataTable([
['Year', 'Sales', 'Expenses', 'Profit'],
['2014', 1000, 400, 200],
['2015', 1170, 460, 250],
['2016', 660, 1120, 300],
['2017', 1030, 540, 350]
]);
var options = {
chart: {
title: 'Company Performance JK 2024',
subtitle: 'Sales, Expenses, and Profit: 2014-2017',
}
};
// Draw the chart
var chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data, google.charts.Bar.convertOptions(options));
},
updateChart: function (payload) {
// Update the chart with new data
var data = google.visualization.arrayToDataTable(payload);
// Redraw the chart with updated data
var chart = new google.charts.Bar(document.getElementById('columnchart_material'));
chart.draw(data);
}
}
}
</script>