How to update dynamically data for Chart.js inside "JS Object"

How to update dynamically data for Chart.js inside "JS Object" https://forum.weintekusa.com/uploads/db0776/optimized/2X/f/ffccdaaae69449cf61183a763ef20998e21354fe_2_1024x745.png
none 0.0 0

Hi,
I’m trying to add an “JS Oject” to my EasyBuilderPro’s project able to update dynamically(periodically) the values of an “array of data” related to a Chart.js.

I started this by downloading the project " Tutorial: Chart.js Demo" found in the official documentation “JS Action/Object SDK Documentation”. Then I simplified the code by removing the parts of code I didn’t need for my test.

This screenshot shows very well what I did:

Launching online simulator, the “line chart” shows up correctly in the graphical user interface. However, the data is updated(changed) every second and that change is not reflected in the gui.

The problem seems to me kind of obvious since the line of code 31 is printing periodically: “console.error(“Canvas.resetTransform() is not supported yet”);”

I don’t know how to move forward in resolving this issue. I don’t know if I have to implement somehow the function “resetTransformation” or how to tweak somehow the function CanvasForChartJs.

Can one someone help with this problem?. Any hint or previous experience with something similar will be appreciated.

Thank you very much

Hi @mmula,

Thank you for contributing to our forum! The JS object is often used when the built-in features cannot easily accomplish the project scope. However, for a line chart it is much easier to use the built in “Trend display” object. This object does not require any code and can produce nearly the same result, we will provide a demo project that includes a chart with a similar style to the JS line chart shortly.

Hi @mmula,

Here is a demo project of our Trend Display Object. This should accomplish what you were looking to do with the JS object much easier.

In addition, here is a helpful video on data sampling and more about how to use the trend display object from our Youtube channel. https://www.youtube.com/watch?v=3Mlrwca7KB4

Hope this helps!

Hi @Brendon.S , @DanielDahilig
Thank you very much for you quick answer.
Certainly, do the job with “build-in Trend Display Object” was my plan-B. It is just I think that the “trend display” using Chart.js is a bit better; this way it look better, the animations are smoth and I can se a lot of options.

Using build-in Trend display, from the example’s project you are suggesting:

My example using Chart.js in a browser (not in EasyBuilderPro):

In summary, if it cannot be done using “JObject and Chart.js” it is ok, I will go with "build-in Trend display as you two are suggesting.
I was just experimenting how far I can get with EasyBuilderPro and javascript.

Thank you very much and congrats, EasyBuilderPro is a very good software!!!

Hi @mmula

I may have found a way to update the chart as new values are generated. I modified the timerTick function to randomly generate a new Y value, then manually inserted the new X and Y values into the lineChart object using:

lineChart.data.datasets[0].data.push({ x: newX, y: newY });

This successfully adds the new data point to the chart and renders it in real time.

A couple of things to note:

  • I used integers for the X values, but string values also work (e.g., x: String(timeIndex)).
  • I also made some changes to the options configuration in the full code to adjust scaling and animation. Feel free to modify or remove those settings based on your needs.
  • Lastly, while it is possible to use the JavaScript-based line chart, we recommend using the built-in, pre-designed objects like the Trend Display object in EasyBuilder Pro for better performance, compatibility, and ease-of-use.

Please let me know if you have other questions!

FULL FUNCTION UPDATE:

let timeIndex = 3;
function timerTick() {
    
    const newY = Math.floor(Math.random() * 10);
    lineChart.data.datasets[0].data.push({ // manual update
        x: timeIndex, // same 3 index values
        // updated y value
        y: newY 
    });
    
    
    // keep the chart moving along with the most up to date data
    if (lineChart.data.datasets[0].data.length > 10) {
        lineChart.data.datasets[0].data.shift();  // keep chart clean
    }

   

    // redraw the line chart
    lineChart.update();

    console.log("Tick", timeIndex, "→", newY);
    timeIndex++;
}

setInterval(timerTick, 2000);

FULL CODE:

// Require chart.js
const chart = require('./chart.js');
// Add date-fns date adapter for chart.js
require('./chartjs-adapter-date-fns.bundle.min.js');
// utils for demo
const demoUtils = require('./utils.js');


// CanvasForChartJs is a polyfilled Canvas for chart.js
var CanvasForChartJs = function () {
    var that = new Canvas();
    // Normally, canvas should return a DOM node. 
    // But we polyfill a simplified version for chart.js  
    that.canvas = {
        get height() {
            return that.height;
        },
        set height(val) {
            that.height = val;
        },
        get width() {
            return that.width;
        },
        set width(val) {
            that.width = val;
        },
        getContext(contextType) {
            return that;
        }
    }
    that.toDataURL = function () {
        return "";
    }
    that.resetTransform = function () {
        console.error("Canvas.resetTransform() is not supported yet")
    }
    return that
}

// EBPro does not implment ECMA-402 so inject a simplified Intl.NumberFormat for number formatting for chart.js
window.Intl = {
    NumberFormat: function (locale, options) {
        return {
            format: function (number) {
                return "" + number
            }
        }
    }
}

// Create canvas
var ctx = new CanvasForChartJs();
ctx.height = 300;
ctx.width = 500
this.widget.add(ctx);



// chartjs
var mydata = [{x: '0', y: 20}, {x: '1', y: 10}, {x: '2', y: 35}];
const lineChart = new chart.Chart(ctx.getContext('2d'), {
    type: 'line',
    data: {
        datasets: [{
            data: mydata,
        }]
    },
    options: {
  animation: false,
  parsing: false,
  scales: {
    x: {
      type: 'linear',        
      position: 'bottom'
    },
      y: {
              beginAtZero: true      // optional: always start Y-axis from 0
        }
      }
    }
});



//updated code

let timeIndex = 3;
function timerTick() {
    
    const newY = Math.floor(Math.random() * 10);
    lineChart.data.datasets[0].data.push({ // manual update
        x: timeIndex, // same 3 index values
        // updated y value
        y: newY 
    });
    
    
    // keep the chart moving along with the most up to date data
    if (lineChart.data.datasets[0].data.length > 10) {
        lineChart.data.datasets[0].data.shift();  // keep chart clean
    }

   

    // redraw the line chart
    lineChart.update();

    console.log("Tick", timeIndex, "→", newY);
    timeIndex++;
}

setInterval(timerTick, 2000);