Hello:
I have migrated my DB1 dashboard to DB2. Everything is working (mostly) except for my charts that use charts.js - they are cleared when I change tabs. Based on previous discussions here, my understanding is that I can save the data and then repopulate the chart when the tab is selected. I save the original data in flow variables and then send them back in when the tab is re-selected. However, this does not appear to work even though I can see the data being sent to the ui-template node (and coming out from it).
I am not vue/CSS/javascript literate and have been bumbling my way through this but have it almost working. Would someone be able to look at the ui-template code and see if I am missing something? Or is there an alternate way to do an automatic refresh?
Thanks for your help.
ui-template code
//WIP - 8/4/2025 3:45 PM
/*
2025-08-04: Colors in arrays did not work, colors assigned to each dataset
2025-08-04: Order of dataset determines stacking (from_grid Tesla/Meter, followed by to_grid Tesla/Meter).
2025-08-04: Added grid display -> working
2025-08-04: Added white color for labels (tick.color)
2025-08-04: Added rotation for x-axis vertical lables - works with minRotation property
2025-08-04: Added weight and size to ticks (x and y values)
2025-08-04: Added x-axislabel (kWh) with size and weight
*/
<template>
<div class="base-container">
<div class="chart-container"><canvas ref="meterchart1" /></div>
</div>
</template>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
/* Assign chart colors and defaults
let textcolor = "white";
let gridcolor = "rgba(200, 200, 200, 0.5)";
let linecolors = ["#5FB404", "#E68C05", "#0489B1", "#D7DF01"];
let barPercent = 0.8
End assign chart colors and defaults */
export default {
data() {
return {
isChartLoaded: false,
dataSets: [],
}
},
watch: {
msg: function () {
if (this.isChartLoaded && this.msg.payload && this.msg.payload.labels) {
this.onInput(this.msg.payload);
}
}
},
mounted() {
let interval = setInterval(() => {
if (window.Chart) {
clearInterval(interval);
this.draw();
this.isChartLoaded = true;
}
}, 100);
},
methods: {
draw() {
const ctx = this.$refs.meterchart1;
const chart = new Chart(ctx, {
type: 'bar',
data: {
labels: [],
datasets: [
{
label: 'Tesla - From Grid',
data: [],
backgroundColor: "#5FB404",
borderColor: "#5FB404",
stack: 'tesla'
},
{
label: 'Meter - From Grid',
data: [],
backgroundColor: "#0489B1",
borderColor: "#0489B1",
stack: 'meter'
},
{
label: 'Tesla - To Grid',
data: [],
backgroundColor: "#E68C05",
borderColor: "#E68C05",
stack: 'tesla'
},
{
label: 'Meter - To Grid',
data: [],
backgroundColor: "#D7DF01",
borderColor: "#D7DF01",
stack: 'meter'
}
]
},
options: {
maintainAspectRatio: false,
animation: false,
responsive: true,
plugins: {
legend: {
position: 'bottom',
labels:{
color:'white'
}
},
title: {
display: false,
text: 'Tesla vs Meter - Injected data'
}
},
scales: {
x: {
stacked:true,
grid: {
display: true,
drawOnChartArea: true,
drawTicks: true,
color: 'rgba(200, 200, 200, 0.25)'
},
ticks:{
color:'white',
minRotation: 90,
font:{
size:13,
weight: 'bold'
}
},
},
y: {
type: 'linear',
display: true,
position: 'left',
grid: {
display: true,
drawOnChartArea: true,
drawTicks: true,
color: 'rgba(200, 200, 200, 0.25)'
},
ticks:{
color:'white',
font:{
size:13,
weight: 'bold'
}
},
title:{
display:true,
text:'kWh',
color:'white',
font:{
weight: 'bold',
size:13
},
},
},
}
},
});
this.chart = chart;
},
onInput(inputData) {
if (!inputData || !Array.isArray(inputData.labels)) return;
this.dataSets = this.chart.data.datasets;
// Clear previous data
this.dataSets.forEach(dataset => dataset.data = []);
this.chart.data.labels = [];
// Assign new data directly from arrays
this.chart.data.labels = inputData.labels;
this.dataSets[0].data = inputData.teslaFromGrid;
this.dataSets[1].data = inputData.meterFromGrid;
this.dataSets[2].data = inputData.teslaToGrid;
this.dataSets[3].data = inputData.meterToGrid;
this.updateChart();
},
updateChart() {
if (this.chart) {
this.dataSets.forEach((element, index) => {
this.chart.data.datasets[index].data = element.data;
});
this.chart.update();
}
},
clearChart() {
if (this.dataSets.length > 0) {
this.dataSets.forEach(element => element.data = []);
this.updateChart();
}
}
}
}
</script>
<style>
.base-container {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
container: chat / size;
}
.chart-container {
position: relative;
margin: auto;
height: 100%;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
</style>
Screenshot showing data being resent to ui-template