如何在Chart.js甜甜圈图表中显示第二组标签?

时间:2020-07-27 11:54:31

标签: charts chart.js chart.js2

按照SO上的其他问题,我成功添加了第二组标签。

但是现在我想显示所有标签的图例,第二组被划掉。如何避免这种情况?

这是我的尝试: https://jsfiddle.net/L5gs39u2/1/

  var platform_labels = ["Tablet","Ordenador"];
  var platform_dataset = [14,5];
  var os_labels = ["Android","Windows","GNU\/Linux"];
  var os_dataset = [14,4,1];
  var devices_labels = ["Tablet","Ordenador","Android","Windows","GNU\/Linux"];
  
  
  var chartColors = {
      red: 'rgb(255, 99, 132)',
      orange: 'rgb(255, 159, 64)',
      yellow: 'rgb(255, 205, 86)',
      green: 'rgb(75, 192, 192)',
      blue: 'rgb(54, 162, 235)',
      purple: 'rgb(153, 102, 255)',
      grey: 'rgb(201, 203, 207)'
  };


  var config = {
      type: 'doughnut',
      data: {
          datasets: [{
              data: platform_dataset,
              backgroundColor: [
                  chartColors.red,
                  chartColors.orange,
                  chartColors.yellow
              ],
              label: 'Platform',
              labels: platform_labels
          }, {
              data: os_dataset,
              backgroundColor: [
                  chartColors.purple,
                  chartColors.green,
                  chartColors.blue
              ],
              label: 'OS',
              labels: os_labels
          }],
          labels: devices_labels
      },
      options: {
          tooltips: {
              callbacks: {
                  label: function (tooltipItem, data) {
                      var dataset = data.datasets[tooltipItem.datasetIndex];
                      var index = tooltipItem.index;
                      return dataset.labels[index] + ": " + dataset.data[index];
                  }
              }
          }
      }
  };
  var ctx = document.getElementById('deviceChart').getContext('2d');
  var employeesGraph = new Chart(ctx, config);

2 个答案:

答案 0 :(得分:1)

删除第二组标签是因为chartjs认为它们是隐藏的,即它们没有值,因此不会呈现,并且标签只能从第一个数据集中绘制。

有几种解决方法,您可以禁用图例,然后创建自定义图例,但是我不确定这是否会抓住所有标签:

var chart = new Chart(ctx, {
        type: 'line',
        data: data,
        options: {
            legend: {
                display: false
            },
            legendCallback: function(chart) {
                var text = [];
                text.push('<ul>');
                for (var i=0; i<devices_labels.length; i++) {
                    text.push('<li>');
                    text.push('<span style="background-color:' + 
                    chart.data.datasets[i].borderColor + '">' + devices_labels[i] + 
                    '</span>');
                    text.push('</li>');
                }
                text.push('</ul>');
                return text.join("");
            }
        }
    });

或者您可以扩展chartjs来更改隐藏数据标签的行为:-change legend item style when dataset is hidden

或者最简单的方法是将一些虚拟数据添加到第一个数据集中:-

var platform_labels = ["Tablet","Ordenador"];
  var platform_dataset = [14, 5, 0, 0, 0];
  var os_labels = ["Android","Windows","GNU\/Linux"];
  var os_dataset = [14,4,1];
  var devices_labels = ["Tablet","Ordenador","Android","Windows","GNU\/Linux"];
  
  
      var chartColors = {
          red: 'rgb(255, 99, 132)',
          orange: 'rgb(255, 159, 64)',
          yellow: 'rgb(255, 205, 86)',
          green: 'rgb(75, 192, 192)',
          blue: 'rgb(54, 162, 235)',
          purple: 'rgb(153, 102, 255)',
          grey: 'rgb(201, 203, 207)'
      };


      var config = {
          type: 'doughnut',
          data: {
              datasets: [{
                  data: platform_dataset,
                  backgroundColor: [
                      chartColors.red,
                      chartColors.orange,
                      chartColors.purple,
                      chartColors.green,
                      chartColors.blue
                  ],
                  label: 'Platform',
                  labels: platform_labels
              }, {
                  data: os_dataset,
                  backgroundColor: [
                      chartColors.purple,
                      chartColors.green,
                      chartColors.blue
                  ],
                  label: 'OS',
                  labels: os_labels
              }],
              labels: devices_labels
          }
      };
      var ctx = document.getElementById('deviceChart').getContext('2d');
      var employeesGraph = new Chart(ctx, config);

答案 1 :(得分:1)

您必须通过定义legend.labels.generateLabels函数和legend.onClick函数来自己生成图例标签,该函数负责隐藏和显示各个饼图。可能如下所示:

legend: {
  labels: {
    generateLabels: () => {
      let labels = [];
      config.data.datasets.forEach((ds, iDs) => labels = labels.concat(ds.labels.map((l, iLabel) => ({
        datasetIndex: iDs,
        labelIndex: iLabel,
        text: l,
        fillStyle: ds.backgroundColor[iLabel],
        hidden: employeesGraph ? employeesGraph.getDatasetMeta(iDs).data[iLabel].hidden : false,
        strokeStyle: '#fff'
      }))));
      return labels;
    }
  },
  onClick: (event, legendItem) => {
    const metaData = employeesGraph.getDatasetMeta(legendItem.datasetIndex).data;
    metaData[legendItem.labelIndex].hidden = !metaData[legendItem.labelIndex].hidden;
    employeesGraph.update();
  }
},

请在下面查看您的修改后的代码:

var platform_labels = ["Tablet", "Ordenador"];
var platform_dataset = [14, 5];
var os_labels = ["Android", "Windows", "GNU\/Linux"];
var os_dataset = [14, 4, 1];
var devices_labels = ["Tablet", "Ordenador", "Android", "Windows", "GNU\/Linux"];

var chartColors = {
  red: 'rgb(255, 99, 132)',
  orange: 'rgb(255, 159, 64)',
  yellow: 'rgb(255, 205, 86)',
  green: 'rgb(75, 192, 192)',
  blue: 'rgb(54, 162, 235)',
  purple: 'rgb(153, 102, 255)',
  grey: 'rgb(201, 203, 207)'
};

var config = {
  type: 'doughnut',
  data: {
    datasets: [{
      data: platform_dataset,
      backgroundColor: [
        chartColors.red,
        chartColors.orange,
      ],
      label: 'Platform',
      labels: platform_labels
    }, {
      data: os_dataset,
      backgroundColor: [
        chartColors.purple,
        chartColors.green,
        chartColors.blue
      ],
      label: 'OS',
      labels: os_labels
    }],
    labels: devices_labels
  },
  options: {
    legend: {
      labels: {
        generateLabels: () => {
          let labels = [];
          config.data.datasets.forEach((ds, iDs) => labels = labels.concat(ds.labels.map((l, iLabel) => ({
            datasetIndex: iDs,
            labelIndex: iLabel,
            text: l,
            fillStyle: ds.backgroundColor[iLabel],
            hidden: employeesGraph ? employeesGraph.getDatasetMeta(iDs).data[iLabel].hidden : false,
            strokeStyle: '#fff'
          }))));
          return labels;
        }
      },
      onClick: (event, legendItem) => {
        const metaData = employeesGraph.getDatasetMeta(legendItem.datasetIndex).data;
        metaData[legendItem.labelIndex].hidden = !metaData[legendItem.labelIndex].hidden;
        employeesGraph.update();
      }
    },
    tooltips: {
      callbacks: {
        label: function(tooltipItem, data) {
          var dataset = data.datasets[tooltipItem.datasetIndex];
          var index = tooltipItem.index;
          return dataset.labels[index] + ": " + dataset.data[index];
        }
      }
    }
  }
};
var ctx = document.getElementById('deviceChart').getContext('2d');
var employeesGraph = new Chart(ctx, config);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.js"></script>
<canvas id="deviceChart" height="120"></canvas>