我定义了两个略有不同的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版:我想到了一个可能的解决方法,即将插件的不同行为指定为各个图表的选项,然后定义一个基于图表的特定选项的插件。但我仍然想知道是否有一种方法可以将插件应用于特定的图表。
我认为解决方案是在每个插件的图表选项中分配一个特定的属性。每个图表将填充不同的属性以使用每个插件。在您的情况下,您有plugin1
和plugin2
。
然后,在每个定义中,您将检查不同的属性,看看该图表是否使用该插件。例如,您的定义如下:
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], ...```