core.controller.js bug breaking chartjs-annotation and chartjs-draggable plugins (configMerge issue)

With the release of 2.7.x the chartjs-plugin-annotation(https://github.com/chartjs/chartjs-plugin-annotation) and chartjs-plugin-draggable (https://github.com/compwright/chartjs-plugin-draggable) are now broken.

If you pull down their sample files you can see that by using chart.js 2.7.x doesn’t work while 2.6.x works just fine. I have filed issues in those respective plugins and posted temporary work arounds for these problems, but would like some clarification from the chart.js team if this is a bug or an architecture change in the framework.

What I have discovered is that the reason why these plugins are breaking is the in the samples they are doing something like this. . .

Please forgive the pseudo code

var anno = [{annotation_config}];

var chartOptions = {
. . . .
annotation: {annotations: anno},
. . . .
}

var myChart = new Chart(ctx, chartOptions);

function addLine(){
anno.push({another_annotation_config});
myChart.update(0);
}

What you will see if you inspect the chart object in chrome’s console is that after the addLine function is called the annotation array is not updated with the added value.

I did some digging in the various commits leading up to the release of 2.7.x and saw that /src/core/core.controller.js was changed in commit 333f2eb#diff-de7249441169d0e646c53d8220e8b0c5

Looking here the chart options were changed to use something called helpers.configMerge(). . . Looking at that method it appears to copy all configuration to a new array and then set it back as the chart.options property. I believe that this is effectively losing reference to outside arrays/objects so that they can no longer be changed by their original object but rather must be accessed via the chart itself. Example of what I’m talking about below.

var anno = [{annotation_config}];

var chartOptions = {
. . . .
annotation: {annotations: anno},
. . . .
}

var myChart = new Chart(ctx, chartOptions);

function addLine(){
//DOES NOT WORK AS REFERENCE IS LOST DUE TO MERGE
anno.push({another_annotation_config});
myChart.update(0);
}


//WORKS FINE AS YOU ARE EDITING THE NOW "INTERNAL" CONFIGURATION THAT WAS MERGED
Chart.helpers.each(Chart.instances,(instance) => {
            if (chartId == instance.canvas.id) {
                instance.options.annotation.annotations.push({another_annotation_config});
                return;
            }
        });

So ultimately what I’m asking here is was this done as part of an architecture change, meaning you want people to not be able to update external objects/arrays but rather update them on the instance itself? Was this a bug that was introduced?

Author: Fantashit

1 thought on “core.controller.js bug breaking chartjs-annotation and chartjs-draggable plugins (configMerge issue)

  1. So it sounds like the conclusion that was reached is to use chart.options instead of array references. I will go update the same files and throw together some documentation on the various plugins that I use that alerts people that they may have to change their code to use the chart.options approach.

    Thanks for looking into this!

Comments are closed.