Search code examples
javascripthtmlcsschart.jsnode-red

new dataset is not accepted by chartj template


I am trying to plot a line chart on the node red dashboard. This template creates the desired scrollable chart with 100 randomly generated datapoints:

<style>.chartWrapper {
  position: relative;
}

.chartWrapper > canvas {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
}

.chartAreaWrapper {
  width: auto;
  overflow-x: scroll;
}
</style>

<div class="chartWrapper">
  <div class="chartAreaWrapper">
  <div class="chartAreaWrapper2">
      <canvas id="chart-Test" height="351" width="4000"></canvas>
  </div>
  </div>
  <canvas id="axis-Test" height="351" width="0"></canvas>
</div>

<script>
    
$(document).ready(function () {

    function generateLabels() {
        var chartLabels = [];
        for (x = 0; x < 100; x++) {
            chartLabels.push(x);
        }
        return chartLabels;
    }

   function generateData() {
        var chartData = [];
        for (x = 0; x < 100; x++) {
            chartData.push(Math.floor((Math.random() * 100) + 1));
        }
        return chartData;
    }
    

    function addData(numData, chart) {
        for (var i = 0; i < numData; i++) {
            chart.data.datasets[0].data.push(Math.random() * 100);
            chart.data.labels.push("Label" + i);
            var newwidth = $('.chartAreaWrapper2').width() + 60;
            $('.chartAreaWrapper2').width(newwidth);
        }
    }

    var chartData = {
        labels: generateLabels(),
        datasets: [{
            label: "Test Data Set",
            data: generateData(),
            pointRadius: 0,
            borderColor: "#4ED7FC",
            borderWidth: 2,
            fill: false
        }]
    };



    $(function () {
        var rectangleSet = false;

        var canvasTest = $('#chart-Test');
        var chartTest = new Chart(canvasTest, {
            type: 'line',
            data: chartData,
            
            maintainAspectRatio: false,
            responsive: true,
            
        });
        addData(5, chartTest);
    });
});    
</script>

chart1

Next I wanted to replace the generated datapoints with a payload message coming into the dashboard template node, where msg.payload[0].data is an array[2500]. I thought I would be able to achieve this by replacing generateData()like so:

<style>.chartWrapper {
  position: relative;
}

.chartWrapper > canvas {
  position: absolute;
  left: 0;
  top: 0;
  pointer-events: none;
}

.chartAreaWrapper {
  width: auto;
  overflow-x: scroll;
}
</style>

<div class="chartWrapper">
  <div class="chartAreaWrapper">
  <div class="chartAreaWrapper2">
      <canvas id="chart-Test" height="351" width="4000"></canvas>
  </div>
  </div>
  <canvas id="axis-Test" height="351" width="0"></canvas>
</div>

<script>
    
$(document).ready(function () {

    function generateLabels() {
        var chartLabels = [];
        for (x = 0; x < 100; x++) {
            chartLabels.push(x);
        }
        return chartLabels;
    }

    /*function generateData() {
        var chartData = [];
        for (x = 0; x < 100; x++) {
            chartData.push(Math.floor((Math.random() * 100) + 1));
        }
        return chartData;
    }*/
    function generateData(msg) {
        var chartData = [];
        chartData = msg.payload[0].data;        
        return chartData;
    }
    

    function addData(numData, chart) {
        for (var i = 0; i < numData; i++) {
            chart.data.datasets[0].data.push(Math.random() * 100);
            chart.data.labels.push("Label" + i);
            var newwidth = $('.chartAreaWrapper2').width() + 60;
            $('.chartAreaWrapper2').width(newwidth);
        }
    }

    var chartData = {
        labels: generateLabels(),
        datasets: [{
            label: "Test Data Set",
            data: generateData(),
            pointRadius: 0,
            borderColor: "#4ED7FC",
            borderWidth: 2,
            fill: false
        }]
    };



    $(function () {
        var rectangleSet = false;

        var canvasTest = $('#chart-Test');
        var chartTest = new Chart(canvasTest, {
            type: 'line',
            data: chartData,
            
            
            responsive: true,
            options: {
                maintainAspectRatio: false,
                tooltips: {
                    titleFontSize: 0,
                    titleMarginBottom: 0,
                    bodyFontSize: 12
                },
                legend: {
                    display: false
                },
                scales: {
                    xAxes: [{
                        ticks: {
                            fontSize: 12,
                            display: false
                        }
                    }],
                    yAxes: [{
                        ticks: {
                            fontSize: 12,
                            beginAtZero: true
                        }
                    }]
                },
            }
        });
        addData(5, chartTest);
    });
});    
</script>

But then the chart is just showing a blank: enter image description here

Why is that?

[edit]

the incoming payload is not empty: enter image description here


Solution

  • I found out that the dashboard template node does not easily accept payload messages on the script section. watch function I have to use something like:

    // Watch the payload and update
    (function(scope) {
        scope.$watch('msg.payload', function(data) {
            update(data);
        });
    })(scope);
    
    function update(dta) {
        theScope.send({payload:dta});
        bleh = dta.name;
        otherStuff();
    }
    

    to watch a incoming payload and store it.

    My initial question "Why is that?" is therefore answered. Unfortunately I am not quite sure how to implement this new bit of code to the array coming in in msg.payload[0.data in my specific case.