DavidH
DavidH

Reputation: 57

Chart.js animation: onComplete event fired on hover

I am loading an image export of my chart after the animation is complete, using the onComplete callback. My problem is that everytime you hover over the diagram, the onComplete callback is executed an this slows down the page immensely.

Here's 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 checked the Chart.js documentation but I did not find any other option that would only fire after the chart is built. So does anyone know how to distinguish between the hover-animation and the "build"-animation of the chart?

Upvotes: 3

Views: 14751

Answers (4)

Dale in CDA
Dale in CDA

Reputation: 1

Working on version 4.4.3, so I don't know about earlier versions.

I find that onComplete is fired in response to several events, including mouseOver (mouse is moving), and chart resize (when window is resized).

To filter only the report of "chart initialized" I tested 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 (of course) my own external function for post-load activities.)

This method avoids removing the onComplete handler.

Edit: Contrary to the initial post, I discovered the method did not allow notification on load of new datasets. To compensate for this, var data_loading was added to the external scope, and is set to true immediately before any call to chart.update() -- but not before creating the chart. For my scatter chart of 360 points, the drawing is fast enough to avoid any event trigger, but there might still be one or two issued if the update is started with the mouse over the chart.

Upvotes: 0

Luiza Rodrigues
Luiza Rodrigues

Reputation: 355

I have the same issue, but solve in a different way (put options: hover: onHover). Example:

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

Upvotes: 0

ɢʀᴜɴᴛ
ɢʀᴜɴᴛ

Reputation: 32879

Replace your animation option/object with the following :

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

Basically, you need to disable onComplete function by setting the chart.options.animation.onComplete property to null. This will make the onComplete function run only after the chart is rendered for the first time, and prevent it from firing when the chart gets hovered on.

TIP : do not use arrow function for object­'s method. (this will always refer to the window object)

Upvotes: 7

Sindhoor
Sindhoor

Reputation: 548

Try this. seems you missed function keyword oncomplete:

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();
                }
            }
        }
    });

Upvotes: 2

Related Questions