将冲突的插件应用/注册到不同的图表



我定义了两个略有不同的Chart.js插件,并且我有一个包含两个不同图表的页面。我想把第一个插件应用到第一个图表,把第二个应用到第二个图表。

根据消息来源,插件有一个注册和注销功能,但你可以将它们注册到一些全局变量"Chart.plugins"中。

我尝试过这样的解决方案:

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

但这似乎会在发生任何事情之前注销这两个插件。如果我不注销插件,第二个插件会覆盖第一个插件所做的任何事情。

此外,似乎不可能将插件直接注册到特定的图表中,例如"windows.myBar.plugins"是未定义的。

有人知道是否存在不同的解决方案吗?

第1版:我想到了一个可能的解决方法,即将插件的不同行为指定为各个图表的选项,然后定义一个基于图表的特定选项的插件。但我仍然想知道是否有一种方法可以将插件应用于特定的图表。

我认为解决方案是在每个插件的图表选项中分配一个特定的属性。每个图表将填充不同的属性以使用每个插件。在您的情况下,您有plugin1plugin2

然后,在每个定义中,您将检查不同的属性,看看该图表是否使用该插件。例如,您的定义如下:

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

要使用这个插件,您的图表必须在其选项中填充plugin_one_attribute。像这样:

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
}

在创建图表时使用这个:

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

因此,为了使用plugin2,您的myBar2图表将需要plugin2的特定属性(它将在注册时检查它)。通过这种方式,您可以控制哪些插件将在每个图表中处于活动状态。

希望能有所帮助!

当前Chartjs v2.9.4版本,从Chartjs文档中,如果您有多个图表,每个图表的插件都可以在图表的配置中定义,如下所示:

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

这个问题已经存在五年了。现在,我们可以使用plugins和钩子调用(在本例中为beforeTooltipDraw)来捕获tooltip.caretX。此外,我们还可以使用内置交互选项来实现这一点。

此实现适用于ChartJS 的4.0.1版本

const plugin = {
  id: 'customText',
  afterDraw: (chart, args, options) => {
    const {ctx} = chart
    texts = options.texts
    if (!texts || texts.length === 0) return

    ctx.save();
    for (const text of texts) {
        const align =  text.align || 'center'
        const size = text.size || '20px'
        const family = text.font || 'Arial'
        const color = text.color || 'black'
        const str = text.str ?? null
        const x = text.x || 0
        const y = text.y || 0
        if (!str) continue
        ctx.textAlign = align
        ctx.font = `${size} ${family}`
        ctx.fillStyle = color
        ctx.fillText(str, x, y)
    }
    ctx.restore();
  }
}
const data = {
  labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"],
  datasets: [{
    data: [12, 3, 2, 1, 8, 8, 2, 2, 3, 5, 7, 1]
  }]
}
const config = {
  type: 'line',
  data,
  options: {
    maintainAspectRatio: false,
    plugins: {
      customText: {
        texts: [{
            x: 300,
            y: 50,
            str: 'Custom',
            size: '30px',
            font: 'Arial black'
          },
          {
            x: 300,
            y: 120,
            str: 'Text',
            color: 'red',
          }
        ]
      }
    }
  },
  plugins: [plugin]
}
const $chart = document.getElementById('chart')
const chart = new Chart($chart, config)
<div class="wrapper" style="width: 98vw; height:180px">
  <canvas id="chart"></canvas>
</div>
<script src="https://npmcdn.com/chart.js@4.0.1/dist/chart.umd.js"></script>

我解决了我的问题(只需在本地注册数据标签插件)

TypeError: Cannot read property 'x' of null

ChartDataLabels插件已在我拥有的另一个图表中全局注册。相反,我在本地注册,这解决了我的问题。文档

基本上,我只需要在我所有的图表定义中删除这一行

// Register the plugin to all charts:
Chart.register(ChartDataLabels);

相反,我只需要它在我的插件对象中的ChartDataLabels:

  plugins: [ChartDataLabels], ...```

相关内容

  • 没有找到相关文章

最新更新