# DB2: Migrating chart.js from DB1

**URL:** <https://discourse.nodered.org/t/db2-migrating-chart-js-from-db1/98421>\
**Category:** Dashboard\
**Tags:** dashboard-2\
**Created:** [31 July 2025 16:12 UTC](https://discourse.nodered.org/t/db2-migrating-chart-js-from-db1/98421 "2025-07-31T16:12:42Z")\
**Posts on this page:** 1\
**Showing post:** 9

<div class="post-metadata">

**Author:** ![rakgupta](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rakgupta/32/42535_2.png) [@rakgupta](https://discourse.nodered.org/u/rakgupta)\
**Post date:** [4 August 2025 15:04 UTC](https://discourse.nodered.org/t/db2-migrating-chart-js-from-db1/98421/9 "2025-08-04T15:04:19Z")

</div>

@Buckskin - I got it working!! And ChatGPT (after 2 days) was finally able to simplify the code a bit.

Below is the flow in case it helps someone:

```auto
[{"id":"f8c7169724fa4baf","type":"inject","z":"3d460c91742c0584","name":"Updated Meter Data (w/payload1)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"labels\":[\"2025-07-15\",\"2025-07-16\",\"2025-07-17\",\"2025-07-18\",\"2025-07-19\",\"2025-07-20\",\"2025-07-21\",\"2025-07-22\",\"2025-07-23\",\"2025-07-24\",\"2025-07-25\",\"2025-07-26\",\"2025-07-27\",\"2025-07-28\",\"2025-07-29\",\"2025-07-30\",\"2025-07-31\",\"2025-08-01\"],\"teslaFromGrid\":[30.548,44.488,28.566,54.282,13.648,0.928,4.604,6.062,6.962,6.876,5.488,7.96,39.938,36.71,46.704,50.692,53.876,45.47],\"meterFromGrid\":[30.869,44.852,28.843,54.751,13.73,0.943,4.668,6.118,7.03,6.928,5.534,8.028,40.279,37.037,47.157,51.154,54.372,45.84],\"teslaToGrid\":[-0.11,-0.07,-0.045,-0.024,-16.551,-9.227,-4.552,-10.018,-4.244,-9.096,-2.726,-0.091,-0.063,-0.076,-0.074,-0.066,-0.057,-0.065],\"meterToGrid\":[-0.201,-0.154,-0.1,-0.068,-16.757,-9.393,-4.664,-10.154,-4.358,-9.246,-2.804,-0.162,-0.113,-0.122,-0.126,-0.083,-0.074,-0.07]}","payloadType":"json","x":384.8345642089844,"y":320.82720947265625,"wires":[["8e254e2bad333e5c"]]},{"id":"8e254e2bad333e5c","type":"ui-template","z":"3d460c91742c0584","group":"5cd7a2a79d14beb5","page":"","ui":"","name":"Clean Temlate for Testing","order":1,"width":"22","height":"10","head":"","format":"<template>\n <div class=\"base-container\">\n <div class=\"chart-container\"><canvas ref=\"meterchart0\" /></div>\n </div>\n</template>\n\n<script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script>\n\n<script>\n export default { \n data() {\n return {\n isChartLoaded: false,\n dataSets: [],\n }\n },\n\n watch: {\n msg: function () {\n if (this.isChartLoaded && this.msg.payload && this.msg.payload.labels) {\n this.onInput(this.msg.payload);\n }\n }\n },\n\n mounted() {\n let interval = setInterval(() => {\n if (window.Chart) {\n clearInterval(interval);\n this.draw();\n this.isChartLoaded = true;\n }\n }, 100);\n },\n\n methods: {\n draw() {\n const ctx = this.$refs.meterchart0;\n const chart = new Chart(ctx, {\n type: 'bar',\n data: {\n labels: [],\n datasets: [\n {\n label: 'Tesla - From Grid',\n data: [],\n backgroundColor: \"lightblue\",\n stack: 'tesla'\n },\n {\n label: 'Meter - From Grid',\n data: [],\n backgroundColor: \"red\",\n stack: 'meter'\n },\n {\n label: 'Tesla - To Grid',\n data: [],\n backgroundColor: \"orange\",\n stack: 'tesla'\n },\n {\n label: 'Meter - To Grid',\n data: [],\n backgroundColor: \"green\",\n stack: 'meter'\n }\n ]\n },\n options: {\n maintainAspectRatio: false,\n animation: false,\n responsive: true,\n plugins: {\n legend: {\n position: 'top',\n },\n title: {\n display: true,\n text: 'Tesla vs Meter - Injected data'\n }\n },\n scales: {\n x: {\n stacked: true,\n },\n y: {\n type: 'linear',\n display: true,\n position: 'left'\n }\n }\n },\n });\n\n this.chart = chart;\n },\n\n onInput(inputData) {\n if (!inputData || !Array.isArray(inputData.labels)) return;\n\n this.dataSets = this.chart.data.datasets;\n\n // Clear previous data\n this.dataSets.forEach(dataset => dataset.data = []);\n this.chart.data.labels = [];\n\n // Assign new data directly from arrays\n this.chart.data.labels = inputData.labels;\n this.dataSets[0].data = inputData.teslaFromGrid;\n this.dataSets[1].data = inputData.meterFromGrid;\n this.dataSets[2].data = inputData.teslaToGrid;\n this.dataSets[3].data = inputData.meterToGrid;\n\n this.updateChart();\n },\n\n updateChart() {\n if (this.chart) {\n this.dataSets.forEach((element, index) => {\n this.chart.data.datasets[index].data = element.data;\n });\n this.chart.update();\n }\n },\n\n clearChart() {\n if (this.dataSets.length > 0) {\n this.dataSets.forEach(element => element.data = []);\n this.updateChart();\n }\n }\n }\n }\n</script>\n\n<style>\n .base-container {\n width: 100%;\n height: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n container: chat / size;\n }\n\n .chart-container {\n position: relative;\n margin: auto;\n height: 100cqb;\n width: 100cqi;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n</style>","storeOutMessages":true,"passthru":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":670.6471252441406,"y":395.3216857910156,"wires":[["ea6162aff0119e33"]]},{"id":"8dc54484cd9c7e23","type":"inject","z":"3d460c91742c0584","name":"Updated Meter Data (w/payload2)","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"labels\":[\"2025-07-15\",\"2025-07-16\",\"2025-07-17\",\"2025-07-18\",\"2025-07-19\",\"2025-07-20\",\"2025-07-21\",\"2025-07-22\",\"2025-07-23\",\"2025-07-24\",\"2025-07-25\",\"2025-07-26\",\"2025-07-27\",\"2025-07-28\",\"2025-07-29\",\"2025-07-30\",\"2025-07-31\",\"2025-08-01\"],\"teslaFromGrid\":[60.548,104.488,88.566,114.282,73.648,63.928,64.604,66.062,66.962,66.876,65.488,67.96,99.938,96.71,106.704,110.692,113.876,105.47],\"meterFromGrid\":[30.869,44.852,28.843,54.751,13.73,0.943,4.668,6.118,7.03,6.928,5.534,8.028,40.279,37.037,47.157,51.154,54.372,45.84],\"teslaToGrid\":[-0.11,-0.07,-0.045,-0.024,-16.551,-9.227,-4.552,-10.018,-4.244,-9.096,-2.726,-0.091,-0.063,-0.076,-0.074,-0.066,-0.057,-0.065],\"meterToGrid\":[-0.201,-0.154,-0.1,-0.068,-16.757,-9.393,-4.664,-10.154,-4.358,-9.246,-2.804,-0.162,-0.113,-0.122,-0.126,-0.083,-0.074,-0.07]}","payloadType":"json","x":379.8345642089844,"y":470.82720947265625,"wires":[["8e254e2bad333e5c"]]},{"id":"ea6162aff0119e33","type":"debug","z":"3d460c91742c0584","name":"Output debug","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":911.6471252441406,"y":396.8106384277344,"wires":[]},{"id":"5cd7a2a79d14beb5","type":"ui-group","name":"Tesla vs Meter - Testing","page":"8d56444ee1e5169e","width":"22","height":"10","order":1,"showTitle":true,"className":"","visible":"true","disabled":"false","groupType":"default"},{"id":"8d56444ee1e5169e","type":"ui-page","name":"New Page for Testing","ui":"de5759a313e7ad79","path":"/page21","icon":"home","layout":"grid","theme":"e4b50d7892c4eb32","breakpoints":[{"name":"Default","px":"0","cols":"3"},{"name":"Tablet","px":"576","cols":"6"},{"name":"Small Desktop","px":"768","cols":"9"},{"name":"Desktop","px":"1024","cols":"12"}],"order":22,"className":"","visible":"true","disabled":"false"},{"id":"de5759a313e7ad79","type":"ui-base","name":"Node-RED Dashboard","path":"/dashboard","appIcon":"","includeClientData":false,"acceptsClientConfig":["ui-notification","ui-control"],"showPathInSidebar":false,"headerContent":"dashboard","navigationStyle":"fixed","titleBarStyle":"default","showReconnectNotification":true,"notificationDisplayTime":5,"showDisconnectNotification":true,"allowInstall":true},{"id":"e4b50d7892c4eb32","type":"ui-theme","name":"Default Theme","colors":{"surface":"#ffffff","primary":"#0094ce","bgPage":"#eeeeee","groupBg":"#ffffff","groupOutline":"#cccccc"},"sizes":{"pagePadding":"12px","groupGap":"12px","groupBorderRadius":"4px","widgetGap":"12px","density":"default"}}]

```

Below is the code for ui-template:

> **ui-template configuration:**
>
> ```auto
> <template>
> <div class="base-container">
> <div class="chart-container"><canvas ref="meterchart0" /></div>
> </div>
> </template>
> 
> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
> 
> <script>
> 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.meterchart0;
> const chart = new Chart(ctx, {
> type: 'bar',
> data: {
> labels: [],
> datasets: [
> {
> label: 'Tesla - From Grid',
> data: [],
> backgroundColor: "lightblue",
> stack: 'tesla'
> },
> {
> label: 'Meter - From Grid',
> data: [],
> backgroundColor: "red",
> stack: 'meter'
> },
> {
> label: 'Tesla - To Grid',
> data: [],
> backgroundColor: "orange",
> stack: 'tesla'
> },
> {
> label: 'Meter - To Grid',
> data: [],
> backgroundColor: "green",
> stack: 'meter'
> }
> ]
> },
> options: {
> maintainAspectRatio: false,
> animation: false,
> responsive: true,
> plugins: {
> legend: {
> position: 'top',
> },
> title: {
> display: true,
> text: 'Tesla vs Meter - Injected data'
> }
> },
> scales: {
> x: {
> stacked: true,
> },
> y: {
> type: 'linear',
> display: true,
> position: 'left'
> }
> }
> },
> });
> 
> 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: 100cqb;
> width: 100cqi;
> display: flex;
> justify-content: center;
> align-items: center;
> }
> </style>
> 
> ```

You can do almost the same in the chart node in DB2 but stacking is not an option and also, I have other charts that are a mix of line/bar charts, hence the dive into chart.js

I hope this helps someone. Again - thank you @Buckskin and @hotNipi . Could not have done this without your help 🙏🏼

> **Sample Output**
>
> ![Screenshot 2025-08-04 at 10.00.33 AM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/3/03912e3adacdcc38894b34262aa8a6c1f5bc620a.png)

---

_[View the full topic](https://discourse.nodered.org/t/db2-migrating-chart-js-from-db1/98421)._
