Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply/Register conflicting plugins to different charts

I have defined two slightly different Chart.js plugins and I have a page with two different charts. I want to apply the first plugin to the first chart and the second to the second chart.

According to the source, there are a register and unregister function for plugins, but you register them to some global variable 'Chart.plugins'.

I have tried a solution like this:

Chart.plugins.register(plugin1);
window.myBar = new Chart(...);
Chart.plugins.unregister(plugin1);

Chart.plugins.register(plugin2);
window.myBar2 = new Chart(...);
Chart.plugins.unregister(plugin2);

but it appears this unregisters both plugins before anything happens. And if I do not unregister the plugins, the second overrides anything the first plugin does.

In addition it does not seem possible to register a plugin directly to a specific chart, as for example 'windows.myBar.plugins' is undefined.

Does anybody know if there exists a different solution?

Edit1: I thought of a possible workaround, namely by specifying the different behaviours of the plugins as options of the individual charts, and then define a single plugin that acts based on the specific options of a chart. But I would still like to know if there exists a way to apply plugins to a specific chart.

like image 729
David Avatar asked Aug 03 '16 19:08

David


2 Answers

Currently Chartjs v2.9.4, from the chartjs documentation, if you have multiple charts, each chart's plugin can be defined in the chart's config, like this:

var ctx = document.getElementById("myChart").getContext('2d');
var chart = new Chart(ctx, {
    type: 'line',
    plugins: [{ //plugin added for this chart
        beforeInit: function(chart, options) {
            //Add statements here
        }
   }],
   options: {
      responsive: true, // Instruct chartjs to respond nicely.
      maintainAspectRatio: false
   },
   // And any other config options as you wish
});
like image 142
Brian Avatar answered Nov 09 '22 09:11

Brian


I think a solution is to assign a specific property in your chart options for each plugin. Each chart will fill a different attribute to use each plugin. In your case, you have plugin1 and plugin2.

Then, in each definition you will check for different attributes to see if that chart is using that plugin or not. For example, your definitions will be something like:

Chart.pluginService.register({
  afterDraw: function(chart) {
    if (chart.config.options.plugin_one_attribute) {
      // Plugin code here...  
    }
  }
});

To use this plugin, your chart will have to fill the plugin_one_attribute, in its options. Like this:

optionsUsingPlugin1 = {
  plugin_one_attribute: // Your variable to be used in the plugin goes here!
  responsive: true,      
  maintainAspectRatio: true,
  title: {
    display: true
  } 
  // And any other config options you are already using
}

And use this when creating your chart:

var myBar = new Chart(ctx, {
  type: 'bar',
  data: data,
  options: optionsUsingPlugin1
});

So, in order to use plugin2, your myBar2 chart will need a specific attribute for plugin2 (which will check for it when registering). This way you can control which plugins will be active in each chart.

Hope that helps!

like image 33
Miguel Péres Avatar answered Nov 09 '22 10:11

Miguel Péres