Obtain additional information to address concerns related to onZoom and onPan issues on the line

Attempting to enhance my Chart.js line chart by fetching more data or utilizing cached backup data during onZoom/onPan events has proven quite challenging.

The original code base is too intricate to share entirely, but I will outline the approaches I have taken so far.

1st approach: Using Chartjs-plugin-zoom for the onZoom and onPan callbacks. However, these callbacks do not provide any context (chart, x, y) during panning/zooming and are not functioning correctly. More details can be found here.

A pull request has been created to address some of these issues which is currently pending: Link

2nd approach: Attempting to modify data in the Chart.js chart using the beforeUpdate callback, but encountering various challenges. The graph initially displays around 1000 data points, updating every second. To handle zooming out, a backup data set containing additional data beyond the initial 1000 points is being considered. When zoomed out, the data set should expand based on changes in left and right coordinates detected in the beforeUpdate callback.

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)
                            const right = scale.getValueForPixel(scale.right)
                            const diffSec = (right - left) / 1000;
                            // Code snippet continued...
                        }
                    }
    }

The second method is resulting in errors such as:

TypeError: Cannot read property 'hidden' of undefined

Would appreciate insights into a potential 3rd solution.

EDIT: Experimentation with different versions has led to a semi-functional state where the first solution appears to be working. However, a new issue has arisen:

  • onZoom is triggered continuously while zooming instead of

    Function called once zooming is completed

    as indicated in the Readme, rendering it ineffective for fetching data from an API.

Answer №1

There is a lack of context in the onZoom and onPan callbacks of Chartjs-plugin-zoom, as mentioned in the documentation.

In fact, there is some context provided—it comes in the form of an object containing the chart. You can access it like so:

function handleCallback(context) {
  console.log('The chart is: ' + context.chart);
}

Answer №2

The solution I discovered is functioning perfectly within the beforeUpdate callBack.

In my graphs, I typically have 1-3 datasets, and this solution is effective regardless of the number of datasets you choose to include specifically for time series data only, utilizing allLabels and allData in the graph.

Although my use case is more complex, I am sharing a simple code snippet below for the beforeUpdate and filterData functions:


function filterData(chartInstance, leftLegendTime) {

    let diff = chartInstance.data.labels[0].getTime() - leftLegendTime
    // Ensure there's at least a 10-second difference between graph and zoomed out graph to avoid over-updating
    if (!chartInstance.data.labels || diff === 0 || diff <= 10000) return

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

    // Matching the start of the graph's left axis...
    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()
}


// ...within 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, 
    mode: 'x',
    rangeMax: {
        x: new Date(Date.now() + 1000)
    },
    rangeMin: {
        x: new Date(Date.now() - 900 * 1000) // e.g., to display maximum history...
    }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The second guard in Angular 5 (also known as Angular 2+) does not pause to allow the first guard to complete an HTTP request

In my application, I have implemented two guards - AuthGuard for logged in users and AdminGuard for admins. The issue arises when trying to access a route that requires both guards. The problem is that the AdminGuard does not wait for the AuthGuard to fini ...

Pause for a minimum of 2 seconds after ajax has been completed before proceeding with transition.next() using Vue.js

For the smooth transition after completing an ajax call, I need to display the spinner for a minimum of 2 seconds. Below is my code, which unfortunately isn't functioning as expected: route: { data(transition) { this.getDelayedData(); ...

Managing the state of a flag: communicating between Angular2 header and sidebar components

In my Angular2 project, I was working on a layout folder where I divided common layouts of certain pages into three components: header, sidebar, and footer. There was an anchor tag in the header that, when clicked, needed to extend the header to the left e ...

Establishing global credentials in VueJS using Axios

When working in main.js, I included the following code: axios.defaults.withCredentials = true; Although this should make it work, I found that the cookies were not being sent to the back end. I inspected the request header and noticed something strange: ...

Tips for continuing code execution in an ajax success function following the completion of a nested ajax call within the success block

I am facing an issue with a function that utilizes $.ajax. In the success section of the function, I have three nested functions. The first one executes properly, but the second one contains another $.ajax call. While the internal $.ajax call works fine, t ...

Efficiently refine your search using the combination of checkboxes and dropdown menus simultaneously

I am currently in the process of creating a highly sortable and filterable image gallery that utilizes numerous tags. The inspiration for this project stems from a similar question on Stack Overflow regarding dropdown menus and checkboxes. You can view the ...

Tips for properly invoking an asynchronous function on every rerender of a component in Vue.js

Situation: An analysis module on a website that needs to display three different data tables, one at a time. Approach: The module is a component containing three buttons. Each button sets a variable which determines which table to render. Depending on the ...

What is the best way to implement window.load in React Native?

I'm encountering an issue with a simple button on my page in Expo/React Native. When I try to navigate to a new page using window.open upon clicking the button, I receive an error message saying "undefined is not a function." Although I am utilizing ...

Retrieve the complete HTML content of a webpage, including the values of all input fields

I'm attempting to save the entire webpage as an HTML file, including all previously entered values in input fields. I have already tried this method: $("#content").html(); However, it does not retain the values entered into input fields. $("#conten ...

Switch modules based on user options

My goal is to process an array of image files. I have the option to select them randomly or one by one (queue) based on the configuration specified in the config.json. To start off, I create the processor and determine the appropriate image selection modu ...

Utilizing Jquery for comparing and retrieving string arrays

Hey there! I'm currently working on a jQuery application and I'm facing an issue with comparing two arrays. Here is an example: FirstArray=["Mike","Jack"]; SecondArray=["Mike","Jack","Andy","Cruz"]; I want to find out which strings are common i ...

Create a CSS menu that centers the links

Here is the CSS code I am using for my horizontal menu: nav { height: 40px; width: 100%; background: #F00; font-size: 11pt; font-family: Arial; font-weight: bold; position: relative; border-bottom: 2px solid # ...

Guide on centering an unfamiliar element in the viewport using HTML, CSS, and JavaScript

In the process of developing my VueJS project, I have successfully implemented a series of cards on the page. However, I am now facing a challenge - when a user selects one of these cards, I want it to move to the center of the screen while maintaining its ...

Is it possible to combine Vue.Draggable with Vuetify's v-data-table to enable the use of table v-slot:item.<name>?

When it comes to Vuetify's v-data-table, there are various types of slots available such as v-slot:body, v-slot:item, and v-slot:item.<name>. One particular slot that we have been utilizing extensively is v-slot:item.<name>. These slots o ...

Problems with radio button serialization in jQuery form plugin

I've created a basic form: <form class="dataform" method="post" id="settings" action="/"> <input type="radio" name="shareSetting" value="n"/> <input type="radio" name="shareSetting" value="y"/> <input type="button" na ...

Experimenting with the inner workings of a method by utilizing vue-test-utils alongside Jest

Is there a way to properly test the internal logic of this method? For instance: async method () { this.isLoading = true; await this.GET_OFFERS(); this.isLoading = false; this.router.push("/somewhere"); } This method toggles isLoading, ...

The online server is unable to access the route from the ajax function in a separate JavaScript file

I am currently working on a Laravel project where each view page has its own separate JS file. However, I have encountered an issue when trying to access route functions from AJAX post or get calls on the online server (Digital Ocean). The error message I ...

Shifting hues with every upward and downward movement

I am experiencing a small issue with this JS code... -I have multiple divs that are changing automatically in rows as they move randomly... I want to change the color of the div moving up to green. And for the div moving down, I want to change the colo ...

Tips for utilizing navigator.getDisplayMedia with automatic screen selection:

navigator.mediaDevices.getDisplayMedia({ audio: false, video: true }).then(gotMedia).catch(function(e) { console.log('getDisplayMedia() error: ', e); }); Triggering the above code will result in a popup like this. There is anoth ...

What is the best way to make changes to elements in an express array?

I have been developing an express application that enables users to manage a list of web projects through various HTTP methods such as get, post, put, and delete. So far, I have successfully implemented the logic for handling get, delete, and post reques ...