Chart.js animation: onComplete event triggered when hovering over the chart

One issue I'm facing is loading an image export of my chart after the animation finishes, using the onComplete callback. The problem arises when hovering over the diagram triggers the onComplete callback, significantly slowing down the page.

Below is my chart code:

this.chart = new Chart(this.$chart.getContext("2d"), {
        type: 'doughnut',
        data: data,
        options: {
            tooltips: {
                enabled: false
            },
            animation: {
                onComplete: (e) => {
                    console.log(e);
                    this.initExport();
                }
            }
        }
    });

I reviewed the Chart.js documentation but couldn't find a way to distinguish between the hover-animation and the "build"-animation of the chart. Does anyone have a solution for this challenge?

Answer №1

Swap out your animation choice/object with the code snippet below:

animation: {
   onComplete(e) => {
      this.options.animation.onComplete = null; //turn off after first display
      console.log(e);
      this.initExport();
   }
}

To clarify, you should deactivate the onComplete function by setting the

chart.options.animation.onComplete
property to null. This will ensure that the onComplete function is only executed once the chart is initially rendered, preventing it from running when hovering over the chart.

HINT : avoid using arrow functions for method inside object. (this will point to the window object)

Answer №2

Don't forget to include the function keyword oncomplete in your code:

this.chart = new Chart(this.$chart.getContext("2d"), {
        type: 'doughnut',
        data: data,
        options: {
            tooltips: {
                enabled: false
            },
            animation: {
                onComplete: function(e) {
                    console.log(e);
                    this.initExport();
                }
            }
        }
    });

Answer №3

I am encountering a similar problem, but I approached it in a different manner by using the following method (utilizing hover options):

let myChart = new Chart(ctx, {
    type: 'doughnut',
    data: {
        labels: labels,
        ..... (other attributes)
    },
    options: {
        onClick: handleClick,
        animation: {
           onComplete: function () { 
                     .... (actions performed on completion) 
           }
        },
        hover: {
            onHover:function(event, chart) {
                if (chart.length > 0)
                    event.target.style.cursor = 'pointer';
                }   
            },
        }
    });

Answer №4

Currently focusing on version 4.4.3, my knowledge is limited to this iteration and not the earlier ones.

I have observed that the onComplete function is triggered by various events, such as mouseOver (when the mouse moves) and chart resize (when the window is resized).

To specifically filter out only the occurrence of "chart initialized," I experimented with the 'initial' property of the event:

options: {
    animation: {
        onComplete: function(e) {
            if ( Object.hasOwn(e, 'initial') ) {
                if ( data_loading || e.initial ) {
                   data_loading = false;
                   chartReady();
                }
            }
        }
    },

("chartReady()" is a custom external function used for post-load tasks.)

This approach prevents the removal of the onComplete handler.

Update: Despite my initial claim, it became apparent that this method did not provide notifications when loading new datasets. To address this issue, I introduced a variable called data_loading into the external scope, ensuring it is set to true just before any call to chart.update() – but not prior to creating the chart itself. In the case of my scatter chart containing 360 points, the rendering process is swift enough to bypass most event triggers, although there might still be occasional ones when updating while hovering over the chart.

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

Issue with Material UI: Style overrides for nested components are not being applied

Having recently delved into CSS in JS techniques, I've hit a roadblock when it comes to styling components in Material UI, particularly with overriding styles of nested elements. Although I have been referring to the official documentation, I still fi ...

Calculate the sum of arrays within an array (matrix) by adding the elements

What is the best way to calculate the vertical sum of data in an array of arrays? arrayOfArrays = [{ label: 'First Value', data: [1, 2, 3, 4, 5, 6, 7, 8] }, { label: 'Second Value', data: [1, 2, 3, 4, 5, 6, 7, 8] ...

The React application is being continuously accessed by a node.js server and processed within async functions

Currently, I am utilizing React, MongoDB, Node.js, and Express in my project. The specific scenario I am facing involves the following code snippet within my component: renderWishlist(){ var quantity; var itemID; var tmp; var my ...

Checking the submission text field with Javascript is being confirmed

It seems I've made a small mistake somewhere, and I would appreciate it if someone could help me find it. I'm attempting to validate a postcode in a form field once it's been entered. I've tried similar code in PHP, and it works fine, b ...

Learn the process of applying distinct CSS classes to various elements within an AJAX response

The client initiates an AJAX call via jQuery. Upon fetching data from the database, I return the response which includes the application of numerous classes and styles to various HTML tags. Unfortunately, this process results in code that appears unsightly ...

Struggling to handle multiple name-field POST requests using Node.js on heroku

Currently, I am in the process of building a web application using Node.js. As part of this project, I have incorporated a hidden form with enctype="multipart/form-data" to facilitate file uploads and input text fields. However, I seem to be encountering a ...

The default value initialization for React-Native Picker is not functioning correctly

When initializing my Picker, I am trying to display the default value but encountering an issue where selectedValue is not firing on the first call. Here is the code for my Picker: <Picker selectedValue={this.props.expense.currency} onValueChan ...

"Adding a .js file to your Google App Engine project: a step-by-step guide

When working on my app, I encountered an issue with including a separate .js file in my .jsp frontend page. This is how my directories are arranged: src |--->com.stuff |--->servlet.java war |-->WEB-INF |--->pages |---->pa ...

Tips for explaining the structure of a basic Just functor in TypeScript

I am embarking on my first attempt to create a simple interface in TypeScript, and I find myself questioning every step along the way. The core question that troubles me is: How can I best describe this straightforward Jest matcher extension? /** * @par ...

jQuery Triggered Download Resulting in 'Error: Connection Issue'

I need to trigger a download using a JQuery AJAX request once it's finished. EXAMPLE CODE: $('.getPDF').click(function(){ var filepath = 'localhost:3000/pdf/formula-' + this.id + '.pdf'; $.ajax({ url: '/formu ...

why is the sum coming out as an undefined number?

My challenge involves creating a table that should display the total price, however, it keeps showing NaN. The code snippet below outlines how the total price is calculated: import React from 'react'; const Total = (props) => { const {ite ...

Deleting an item from a JSON object using Angular

Whenever I click on an item in the list, it generates an input text and adds the attributes of that input to a JSON. Currently, each time I click on an item multiple times, the JSON accumulates all the clicks. For instance, if I click 3 times on the first ...

Tips for avoiding duplicate elements in ASP.NET during postback

My issue is that I have a div with the ID "mydiv" and runat=server. <div ID="mydiv" runat="server"></div> I move mydiv to a Container using jQuery. $("#mydiv").appendTo('#Container'); After a PostBack, my div gets duplicated and I ...

A guide to tracing a button click with a personalized <img> tag in Google Tag Manager

Recently, a marketing firm provided me with a custom tag to implement on a Wordpress site for tracking clicks on specific buttons. I am utilizing the Elementor page builder and have assigned unique IDs to each button. Although I am new to Google Tag Manage ...

Is there a way to display "not found" if the code's output is blank?

Incorporating an "ajax select" and "while scrolling load data" script has been successful for me. However, I'm struggling with displaying a "not found data" message in div.status when the output variable on animals.php is empty. index.html <!DOCT ...

Tips for resolving the error "Parsing near 'Unexpected end of JSON input while parsing...' for...'mocha':'^3.2.0','s'":

Once I've successfully set up react and react-dom, the next step is to install webpack. However, I encountered an error during this process. To troubleshoot, I decided to install babel-loader first to ensure that both npm and my internet connection a ...

There seems to be an issue with Bootstrap: the property this._config is

Here is the button I have: <button class="kv_styleclass_0 btn btn-outline-success btn-lg" data-bs-toggle="modal" data-bs-target="formModal" type="button"> Become a participant </button ...

Unable to locate AngularJS controller

As my single controller started to become too large, I decided to split it into multiple controllers. However, when I try to navigate to /signup, I encounter an issue where my UserController cannot be found. The error message states: Error: [ng:areq] Argu ...

When defining a component decorator in Angular 2, mixing tabs and spaces can lead to an unhandled exception

After refactoring my Angular 2 component code and adding some tabulations, the code suddenly stopped working. Surprisingly, when I removed the tabs (spaces), it started working again. @Component({ templateUrl : './app.component.html', styl ...