Chart.js 堆叠和分组柱状图

6
3个回答

8

好的,我找到了解决方法。在这个GitHub问题中有描述,解决方案在这个JSFiddle中。

Chart.defaults.groupableBar = Chart.helpers.clone(Chart.defaults.bar);

var helpers = Chart.helpers;
Chart.controllers.groupableBar = Chart.controllers.bar.extend({
  calculateBarX: function (index, datasetIndex) {
    // position the bars based on the stack index
    var stackIndex = this.getMeta().stackIndex;
    return Chart.controllers.bar.prototype.calculateBarX.apply(this, [index, stackIndex]);
  },

  hideOtherStacks: function (datasetIndex) {
    var meta = this.getMeta();
    var stackIndex = meta.stackIndex;

    this.hiddens = [];
    for (var i = 0; i < datasetIndex; i++) {
      var dsMeta = this.chart.getDatasetMeta(i);
      if (dsMeta.stackIndex !== stackIndex) {
        this.hiddens.push(dsMeta.hidden);
        dsMeta.hidden = true;
      }
    }
  },

  unhideOtherStacks: function (datasetIndex) {
    var meta = this.getMeta();
    var stackIndex = meta.stackIndex;

    for (var i = 0; i < datasetIndex; i++) {
      var dsMeta = this.chart.getDatasetMeta(i);
      if (dsMeta.stackIndex !== stackIndex) {
        dsMeta.hidden = this.hiddens.unshift();
      }
    }
  },

  calculateBarY: function (index, datasetIndex) {
    this.hideOtherStacks(datasetIndex);
    var barY = Chart.controllers.bar.prototype.calculateBarY.apply(this, [index, datasetIndex]);
    this.unhideOtherStacks(datasetIndex);
    return barY;
  },

  calculateBarBase: function (datasetIndex, index) {
    this.hideOtherStacks(datasetIndex);
    var barBase = Chart.controllers.bar.prototype.calculateBarBase.apply(this, [datasetIndex, index]);
    this.unhideOtherStacks(datasetIndex);
    return barBase;
  },

  getBarCount: function () {
    var stacks = [];

    // put the stack index in the dataset meta
    Chart.helpers.each(this.chart.data.datasets, function (dataset, datasetIndex) {
      var meta = this.chart.getDatasetMeta(datasetIndex);
      if (meta.bar && this.chart.isDatasetVisible(datasetIndex)) {
        var stackIndex = stacks.indexOf(dataset.stack);
        if (stackIndex === -1) {
          stackIndex = stacks.length;
          stacks.push(dataset.stack);
        }
        meta.stackIndex = stackIndex;
      }
    }, this);

    this.getMeta().stacks = stacks;
    return stacks.length;
  },
});

var data = {
  labels: ["January", "February", "March"],
  datasets: [
    {
      label: "Apples",
      backgroundColor: "rgba(99,255,132,0.2)",
      data: [20, 10, 30],
      stack: 1
    },
    {
      label: "Bananas",
      backgroundColor: "rgba(99,132,255,0.2)",
      data: [40, 50, 20],
      stack: 1
    },
    {
      label: "Cookies",
      backgroundColor: "rgba(255,99,132,0.2)",
      data: [60, 20, 20],
      stack: 1
    },
    {
      label: "Apples",
      backgroundColor: "rgba(99,255,132,0.2)",
      data: [20, 10, 30],
      stack: 2
    },
    {
      label: "Bananas",
      backgroundColor: "rgba(99,132,255,0.2)",
      data: [40, 50, 20],
      stack: 2
    },
    {
      label: "Cookies",
      backgroundColor: "rgba(255,99,132,0.2)",
      data: [60, 20, 20],
      stack: 2
    },
    {
      label: "Apples",
      backgroundColor: "rgba(99,255,132,0.2)",
      data: [20, 10, 30],
      stack: 3
    },
    {
      label: "Bananas",
      backgroundColor: "rgba(99,132,255,0.2)",
      data: [40, 50, 20],
      stack: 3
    },
    {
      label: "Cookies",
      backgroundColor: "rgba(255,99,132,0.2)",
      data: [60, 20, 20],
      stack: 3
    },
  ]
};

var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, {
  type: 'groupableBar',
  data: data,
  options: {
    legend: {
      labels: {
        generateLabels: function(chart) {
          return Chart.defaults.global.legend.labels.generateLabels.apply(this, [chart]).filter(function(item, i){
                return i <= 2;
          });
        }
      }
    },
    scales: {
      yAxes: [{
        ticks: {
          max: 160,
        },
        stacked: true,
      }]
    }
  }
});

1
有没有可能仅从“一月”的三个条形图中删除第一个条形图? - Anubhav Dhawan

6
每个数据集应使用数据集对象的堆栈属性。如Chart.js文档中所示,stack被定义为“该数据集所属组的ID(当堆叠时,每个组将是单独的堆栈)”。我相信这个功能是最近引入的,在2016年,由于这篇文章的原因,Chart.js没有这个功能。

Chart.js有堆叠组示例:https://www.chartjs.org/samples/latest/charts/bar/stacked-group.html - ishakkulekci

0

您可以使用以下数据实现堆叠条形图

this.dataStackedBarChart = {
      type: 'horizontalBar',
      labels: this.stackedBarChartLabel,
      datasets: [
        {
          label: 'Success Count',
          stack: 'Stack 0',
          data: this.successCount,
          backgroundColor: 'green'
        },
        {
          label: 'FailureCount',
          stack: 'Stack 0',
          data: this.failureCount,
          backgroundColor: 'red'
        },
        {
          label: 'AvgDuration',
          stack: 'Stack 1',
          data: this.avgDuration,
          backgroundColor: 'black'
      },
      {
        label: 'MaxDuration',
        stack: 'Stack 2',
        data: this.maxDuration,
        backgroundColor: 'orange'
    },
    {
        label: 'MinDuration',
        stack: 'Stack 3',
        data: this.minDuration,
        backgroundColor: 'pink'
    }
      ],
      borderWidth: 2
    }
    this.optionsStackedBarChart = {
      tooltips: {
        callbacks: {
          label: function (tooltipItem, data) {
            var label = this.uniqueApiPath[tooltipItem.index];
            return label;
          }
        }
      },
      scales: {
        xAxes: [
          {
            stacked: true,
            display: true,
            ticks: {
              beginAtZero: true,
              min: 0,
              suggestedMin: 0
            }
          }
        ],
        yAxes: [
          {
            stacked: true,
            display: true,
            ticks: {
              beginAtZero: true,
              min: 0,
              suggestedMin: 0
            }
          }
        ]
      }

谢谢,这个帮助我解决了一个问题! - Ab5

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接