Chartjs-Fetch more data for line chart onZoom/onPan issues

0πŸ‘

Chartjs-plugin-zoom shares onZoom and onPan callbacks as mentioned here but these doesn’t provide any context (chart, x, y) with these call backs

There actually is context provided. It is called with an object containing the chart so you can do:

function callback(context) {
  console.log('Here is the chart: ' + context.chart);
}

0πŸ‘

I found the solution and it is working well in beforeUpdate callBack.

I am having 1-3 datasets in my graphs and the solution works for any number of datasets you want to put But for a time series only with having allLabels and allData to utilise in graph.

I am having a more complex use case but sharing simplest code here for beforeUpdate and filterData code:


function filterData(chartInstance, leftLegendTime) {

    let diff = chartInstance.data.labels[0].getTime() - leftLegendTime
    // Check min 10 sec difference between graph and zoomed out graph to get safe from over updates
    if (!chartInstance.data.labels || diff === 0 || diff <= 10000) return

    let allLabels = chartInstance.data.datasets[0].allLabels

    // Matching graph's left axis start...
    let leftIndex = allLabels.map(
        (elem) => parseInt(elem.getTime()/1000)
    ).indexOf(parseInt(leftLegendTime/1000))

    if (leftIndex === -1) return;

    chartInstance.data = {...chartInstance.data, labels: allLabels.slice(leftIndex)}

    for (let i = 0;i < chartInstance.data.datasets.length; i++) {
        chartInstance.data.datasets[i] = {
            ...chartInstance.data.datasets[i],
            data: chartInstance.data.datasets[i].allData.slice(leftIndex)
        }
    }

    chartInstance.update()
}


// ...in graphOptions:
scales: {
        xAxes: [{
        id: 'x-axis-0',
        type: 'time',
        beforeUpdate: function (chart) {
        const scale = chart.chart.scales['x-axis-0']
        if (scale.margins) {
            const left = scale.getValueForPixel(scale.left)
            filterData(chart.chart, left._d.getTime())
        }
     }
}],
zoom: {
    enabled: true,
    drag: false, // cannot have drag-to-zoom and pan at once
    mode: 'x',
    rangeMax: {
        x: new Date(Date.now() + 1000)
    },
    rangeMin: {
        x: new Date(Date.now() - 900 * 1000) // eg. to show max history...
    }
}

Leave a comment