如何隐藏 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 属性提供,该属性应该是与现有切片对应的索引数组。使用 hideSlicesPluginif 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>

参考文献: