Chartjs嵌套饼图/圆环图

时间:2015-03-02 09:53:52

标签: javascript chart.js

Chart.js制作了一些非常棒的图表,直到现在它一直很好用。我想创建这样的东西:

nested doughnut chart

有可能吗?

2 个答案:

答案 0 :(得分:3)

我认为这可能是Chart.js的2.0版本。这是一个例子:



var ctx = document.getElementById("myChart");
var chartData = {
  labels: [
    "Red",
    "Blue",
    "Yellow"
  ],
  datasets: [{
    data: [300, 50, 100],
    backgroundColor: [
      "#FF6384",
      "#36A2EB",
      "#FFCE56"
    ],
    hoverBackgroundColor: [
      "#FF6384",
      "#36A2EB",
      "#FFCE56"
    ]
  }, {
    data: [200, 100, 25, 25, 66, 34],
    backgroundColor: [
      "#FF6384",
      "#36A2EB",
      "#FFCE56",
      "#FF6384",
      "#36A2EB",
      "#FFCE56"
    ],
    hoverBackgroundColor: [
      "#FF6384",
      "#36A2EB",
      "#FFCE56",
      "#FF6384",
      "#36A2EB",
      "#FFCE56"
    ]
  }]
};
var pieChart = new Chart(ctx, {
  type: 'pie',
  data: chartData
})

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.3.0/Chart.min.js"></script>

<canvas id="myChart" width="300" height="300"></canvas>
&#13;
&#13;
&#13;

答案 1 :(得分:2)

如果您需要一个图例,其中包含来自外部和内部数据集的所有标签,则必须自己生成图例标签。

enter image description here

这是通过定义legend.labels.generateLabels函数和legend.onClick函数来完成的,该函数负责隐藏和显示各个甜甜圈切片。可能如下所示:

int FLUSH_MAX_ACTIONS = 10_000;
long FLUSH_INTERVAL_MILLIS = 1_000;
int FLUSH_MAX_SIZE_MB = 1;

esSinkBuilder.setBulkFlushMaxActions(FLUSH_MAX_ACTIONS);
esSinkBuilder.setBulkFlushInterval(FLUSH_INTERVAL_MILLIS);
esSinkBuilder.setBulkFlushMaxSizeMb(FLUSH_MAX_SIZE_MB);
esSinkBuilder.setBulkFlushBackoff(true);

请查看下面的可运行代码,并查看其工作方式:

legend: {
  position: 'left',
  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: chart ? chart.getDatasetMeta(iDs).data[iLabel].hidden : false,
        strokeStyle: '#fff'
      }))));
      return labels;
    }
  },
  onClick: (event, legendItem) => {
    let metaData = chart.getDatasetMeta(legendItem.datasetIndex).data;
    metaData[legendItem.labelIndex].hidden = !metaData[legendItem.labelIndex].hidden;
    chart.update();
  }
},
var outer_labels = ['A', 'B', 'C'];
var inner_labels = ['X', 'Y', 'Z'];

var config = {
  type: 'doughnut',
  data: {
    datasets: [{
      data: [40, 15, 45],
      backgroundColor: ['rgb(0, 140, 75)', 'rgb(94, 140, 0)', 'rgb(140, 89, 0)'],
      label: 'Outer Dataset',
      labels: outer_labels
    }, {
      data: [30, 20, 50],
      backgroundColor: ['rgb(247, 70, 74)', 'rgb(70, 191, 189)', 'rgb(253, 180, 91)'],
      label: 'Inner Dataset',
      labels: inner_labels
    }],
    labels: outer_labels.concat(inner_labels)
  },
  options: {
    rotation: -0.8 * Math.PI,
    legend: {
      position: 'left',
      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: chart ? chart.getDatasetMeta(iDs).data[iLabel].hidden : false,
            strokeStyle: '#fff'
          }))));
          return labels;
        }
      },
      onClick: (event, legendItem) => {
        let metaData = chart.getDatasetMeta(legendItem.datasetIndex).data;
        metaData[legendItem.labelIndex].hidden = !metaData[legendItem.labelIndex].hidden;
        chart.update();
      }
    },
    tooltips: {
      callbacks: {
        label: (tooltipItem, data) => {
          let dataset = data.datasets[tooltipItem.datasetIndex];
          let index = tooltipItem.index;
          return dataset.labels[index] + ": " + dataset.data[index];
        }
      }
    }
  }
};

var chart = new Chart('canvas', config);
div {
  width: 300px;
}