如何隐藏 Chart.js 饼图中的部分
How to hide section in a Chart.js Pie Chart
在 Chart.js 中,您可以通过单击顶部的标签来隐藏图表的一部分。
带隐藏部分的饼图图片
我想要在启动时隐藏图表的一部分。对于另一种类型的图表,我会使用隐藏的数据集 属性,但饼图部分与数据集不对应。因此,如果您这样做,整个数据集都会被隐藏,而不仅仅是需要的部分。
(额外信息:我使用了一个包含多个数据集的饼图)
我最接近的解决方案是这段代码:
for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
meta.data[index].hidden = !meta.data[index].hidden;
}
chart.update();
或者我可以覆盖 generateLabels 函数。
谁能帮我找到更好的解决方案?
谢谢
您可能会看到作为插件的实现 here 及以下。
// A plugin that hides slices, given their indices, across all datasets.
var hideSlicesPlugin = {
afterInit: function(chartInstance) {
// If `hiddenSlices` has been set.
if (chartInstance.config.data.hiddenSlices !== undefined) {
// Iterate all datasets.
for (var i = 0; i < chartInstance.data.datasets.length; ++i) {
// Iterate all indices of slices to be hidden.
chartInstance.config.data.hiddenSlices.forEach(function(index) {
// Hide this slice for this dataset.
chartInstance.getDatasetMeta(i).data[index].hidden = true;
});
}
chartInstance.update();
}
}
};
Chart.pluginService.register(hideSlicesPlugin);
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
data: [15, 1, 1, 1, 45, 1],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}, {
data: [5, 1, 25, 10, 5, 1],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}],
// Hide the second (index = 1) and the fourth (index = 3) slice.
hiddenSlices: [1, 3]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
要隐藏的切片使用 hiddenSlices
属性提供,该属性应该是与现有切片对应的索引数组。使用 hideSlicesPlugin
、if hiddenSlices
已设置,切片在所有数据集中隐藏。
更新 - 17/Nov/2019
不要这样做,在我写这篇文章的时候,我也是 ChartJS 和 Web 开发的新手,上面的解决方案似乎已经过时了,所以我试着用对我有用的东西来回答。也许它也已经过时了,从那以后我就没怎么用过 ChartJS 了。我搬到了Echarts。
由于@xnakos 的回答已经过时,我只是想分享在当前的 ChartJS 版本 (2.7.3) 中可以更轻松地完成同样的事情。只需将值设置为 undefined
,将其设置为其他值,例如 null
将使图例可见(或不交叉)。
var ctx = document.getElementById("myDoughnut").getContext("2d");
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ["Red", "Green", "Blue"],
datasets: [{
label: '# of Votes',
data: [12, 19, undefined],
// Set this value to undefined
backgroundColor: [
'#f87979',
'#79f879',
'#7979f8'
],
borderWidth: 5
}]
},
options: {
tooltips: {
mode: null
},
plugins: {
datalabels: {
borderWidth: 5,
borderColor: "white",
borderRadius: 8,
// color: 0,
font: {
weight: "bold"
},
backgroundColor: "lightgray"
}
}
}
});
<div id="app">
<div width="400">
<canvas id="myDoughnut"></canvas>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.4.0/dist/chartjs-plugin-datalabels.js"></script>
<!-- Made in 21 Nov 2018 -->
<!-- with ChartJS 2.7.3 -->
这里有一个 link 的 JSFiddle,供你玩玩。
http://jsfiddle.net/irfandyjip89/fokbgnvz/5/
但是,必须注意,如果您使用 Pie/Doughnut 上的数据集,最好将其设置为 null
。因为任何数据集中的一个 undefined
值都会跨越图例。
但是如果你在任何数据集上设置一个undefined
值,这将导致图例划线(或删除线)。 即使下一个数据集上有值。
这意味着,如果您只使用一个数据集,并且您不希望图表中显示数据并使图例交叉,您希望将值设置为 undefined
。然而,null
值会得到相同的结果 ,而不会 越过图例。
然而,它偏爱图表的显示方式,但就我个人而言,如果我想跨越图例(通常在一个数据集图表上)并隐藏数据,我想使用 undefined
值,并且将如果我只想隐藏数据而不让图例交叉(通常在多个数据集图表上),请使用 null
值。
如果你想检查它在玩多个数据集时的表现如何,你可以检查这个 fiddle http://jsfiddle.net/irfandyjip89/fokbgnvz/19/
P.S. 如果您想知道我是如何将标签值放在中心的,它使用了一个名为 chartjs-plugin-datalabels[=24 的插件=]
创建图表后,您可以通过 .getDatasetMeta(index)
检索其元数据,更改所需切片的 hidden
属性并更新图表,如以下代码片段所示。当用户点击隐藏切片的标签时,它会再次变为可见。
const chart = new Chart(document.getElementById('myChart'), {
type: 'pie',
data: {
labels: ['Red', 'Orange', 'Yellow', 'Green', 'Blue'],
datasets: [{
data: [100, 100, 200, 300, 140],
backgroundColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(255, 205, 86)', 'rgb(75, 192, 192)', 'rgb(54, 162, 235)']
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
title: {
display: true,
text: 'Colors - Sample Pie Chart'
}
}
});
chart.getDatasetMeta(0).data[4].hidden = true;
chart.update();
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="150"> </canvas>
None 此处提供的答案适用于 Chart.js 版本 3.2.1(我正在使用的)。这是我想出的(并且有效):
let ctx = document.getElementById('myChart').getContext('2d');
window.chart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['Red', 'Orange', 'Yellow', 'Green', 'Blue'],
datasets: [{
data: [100, 100, 200, 300, 140],
backgroundColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(255, 205, 86)', 'rgb(75, 192, 192)', 'rgb(54, 162, 235)'],
hoverOffset: 6,
}]
},
options: {
layout: { padding: 10 },
responsive: true,
maintainAspectRatio: true,
plugins: {
title: {
display: true,
text: 'Colors - Sample Pie Chart'
}
}
}
});
toggleData('red');
window.chart.render();
function toggleData(txt) {
let ci = window.chart;
let legendItems = ci.legend.legendItems;
let index;
for (index = 0; index < legendItems.length; ++index) {
let legendItem = legendItems[index];
if (legendItem.text.toLowerCase() === txt.toLowerCase()) {
// let visible = chart.getDataVisibility(index);
ci.toggleDataVisibility(index);
ci.update();
return;
}
}
}
/*
Note: Do not style the canvas element. See:
https://github.com/chartjs/Chart.js/issues/9089
*/
#myChartContainer {
width:400px;
height:400px;
}
<div id="myChartContainer">
<canvas id="myChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"
integrity="sha256-uVEHWRIr846/vAdLJeybWxjPNStREzOlqLMXjW/Saeo=" crossorigin="anonymous"></script>
参考文献:
在 Chart.js 中,您可以通过单击顶部的标签来隐藏图表的一部分。
带隐藏部分的饼图图片
我想要在启动时隐藏图表的一部分。对于另一种类型的图表,我会使用隐藏的数据集 属性,但饼图部分与数据集不对应。因此,如果您这样做,整个数据集都会被隐藏,而不仅仅是需要的部分。
(额外信息:我使用了一个包含多个数据集的饼图)
我最接近的解决方案是这段代码:
for (i = 0, ilen = (chart.data.datasets || []).length; i < ilen; ++i) {
meta = chart.getDatasetMeta(i);
meta.data[index].hidden = !meta.data[index].hidden;
}
chart.update();
或者我可以覆盖 generateLabels 函数。
谁能帮我找到更好的解决方案?
谢谢
您可能会看到作为插件的实现 here 及以下。
// A plugin that hides slices, given their indices, across all datasets.
var hideSlicesPlugin = {
afterInit: function(chartInstance) {
// If `hiddenSlices` has been set.
if (chartInstance.config.data.hiddenSlices !== undefined) {
// Iterate all datasets.
for (var i = 0; i < chartInstance.data.datasets.length; ++i) {
// Iterate all indices of slices to be hidden.
chartInstance.config.data.hiddenSlices.forEach(function(index) {
// Hide this slice for this dataset.
chartInstance.getDatasetMeta(i).data[index].hidden = true;
});
}
chartInstance.update();
}
}
};
Chart.pluginService.register(hideSlicesPlugin);
var ctx = document.getElementById("myChart");
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
data: [15, 1, 1, 1, 45, 1],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}, {
data: [5, 1, 25, 10, 5, 1],
backgroundColor: [
'rgba(255, 99, 132, 0.2)',
'rgba(54, 162, 235, 0.2)',
'rgba(255, 206, 86, 0.2)',
'rgba(75, 192, 192, 0.2)',
'rgba(153, 102, 255, 0.2)',
'rgba(255, 159, 64, 0.2)'
],
borderColor: [
'rgba(255,99,132,1)',
'rgba(54, 162, 235, 1)',
'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)',
'rgba(153, 102, 255, 1)',
'rgba(255, 159, 64, 1)'
],
borderWidth: 1
}],
// Hide the second (index = 1) and the fourth (index = 3) slice.
hiddenSlices: [1, 3]
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
<canvas id="myChart" width="400" height="400"></canvas>
要隐藏的切片使用 hiddenSlices
属性提供,该属性应该是与现有切片对应的索引数组。使用 hideSlicesPlugin
、if hiddenSlices
已设置,切片在所有数据集中隐藏。
更新 - 17/Nov/2019
不要这样做,在我写这篇文章的时候,我也是 ChartJS 和 Web 开发的新手,上面的解决方案似乎已经过时了,所以我试着用对我有用的东西来回答。也许它也已经过时了,从那以后我就没怎么用过 ChartJS 了。我搬到了Echarts。
由于@xnakos 的回答已经过时,我只是想分享在当前的 ChartJS 版本 (2.7.3) 中可以更轻松地完成同样的事情。只需将值设置为 undefined
,将其设置为其他值,例如 null
将使图例可见(或不交叉)。
var ctx = document.getElementById("myDoughnut").getContext("2d");
var myChart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: ["Red", "Green", "Blue"],
datasets: [{
label: '# of Votes',
data: [12, 19, undefined],
// Set this value to undefined
backgroundColor: [
'#f87979',
'#79f879',
'#7979f8'
],
borderWidth: 5
}]
},
options: {
tooltips: {
mode: null
},
plugins: {
datalabels: {
borderWidth: 5,
borderColor: "white",
borderRadius: 8,
// color: 0,
font: {
weight: "bold"
},
backgroundColor: "lightgray"
}
}
}
});
<div id="app">
<div width="400">
<canvas id="myDoughnut"></canvas>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@0.4.0/dist/chartjs-plugin-datalabels.js"></script>
<!-- Made in 21 Nov 2018 -->
<!-- with ChartJS 2.7.3 -->
这里有一个 link 的 JSFiddle,供你玩玩。 http://jsfiddle.net/irfandyjip89/fokbgnvz/5/
但是,必须注意,如果您使用 Pie/Doughnut 上的数据集,最好将其设置为 null
。因为任何数据集中的一个 undefined
值都会跨越图例。
但是如果你在任何数据集上设置一个undefined
值,这将导致图例划线(或删除线)。 即使下一个数据集上有值。
这意味着,如果您只使用一个数据集,并且您不希望图表中显示数据并使图例交叉,您希望将值设置为 undefined
。然而,null
值会得到相同的结果 ,而不会 越过图例。
然而,它偏爱图表的显示方式,但就我个人而言,如果我想跨越图例(通常在一个数据集图表上)并隐藏数据,我想使用 undefined
值,并且将如果我只想隐藏数据而不让图例交叉(通常在多个数据集图表上),请使用 null
值。
如果你想检查它在玩多个数据集时的表现如何,你可以检查这个 fiddle http://jsfiddle.net/irfandyjip89/fokbgnvz/19/
P.S. 如果您想知道我是如何将标签值放在中心的,它使用了一个名为 chartjs-plugin-datalabels[=24 的插件=]
创建图表后,您可以通过 .getDatasetMeta(index)
检索其元数据,更改所需切片的 hidden
属性并更新图表,如以下代码片段所示。当用户点击隐藏切片的标签时,它会再次变为可见。
const chart = new Chart(document.getElementById('myChart'), {
type: 'pie',
data: {
labels: ['Red', 'Orange', 'Yellow', 'Green', 'Blue'],
datasets: [{
data: [100, 100, 200, 300, 140],
backgroundColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(255, 205, 86)', 'rgb(75, 192, 192)', 'rgb(54, 162, 235)']
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
title: {
display: true,
text: 'Colors - Sample Pie Chart'
}
}
});
chart.getDatasetMeta(0).data[4].hidden = true;
chart.update();
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="myChart" height="150"> </canvas>
None 此处提供的答案适用于 Chart.js 版本 3.2.1(我正在使用的)。这是我想出的(并且有效):
let ctx = document.getElementById('myChart').getContext('2d');
window.chart = new Chart(ctx, {
type: 'pie',
data: {
labels: ['Red', 'Orange', 'Yellow', 'Green', 'Blue'],
datasets: [{
data: [100, 100, 200, 300, 140],
backgroundColor: ['rgb(255, 99, 132)', 'rgb(255, 159, 64)', 'rgb(255, 205, 86)', 'rgb(75, 192, 192)', 'rgb(54, 162, 235)'],
hoverOffset: 6,
}]
},
options: {
layout: { padding: 10 },
responsive: true,
maintainAspectRatio: true,
plugins: {
title: {
display: true,
text: 'Colors - Sample Pie Chart'
}
}
}
});
toggleData('red');
window.chart.render();
function toggleData(txt) {
let ci = window.chart;
let legendItems = ci.legend.legendItems;
let index;
for (index = 0; index < legendItems.length; ++index) {
let legendItem = legendItems[index];
if (legendItem.text.toLowerCase() === txt.toLowerCase()) {
// let visible = chart.getDataVisibility(index);
ci.toggleDataVisibility(index);
ci.update();
return;
}
}
}
/*
Note: Do not style the canvas element. See:
https://github.com/chartjs/Chart.js/issues/9089
*/
#myChartContainer {
width:400px;
height:400px;
}
<div id="myChartContainer">
<canvas id="myChart"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.2.1/dist/chart.min.js"
integrity="sha256-uVEHWRIr846/vAdLJeybWxjPNStREzOlqLMXjW/Saeo=" crossorigin="anonymous"></script>
参考文献: