【问题标题】:Chart.js stacked and grouped horizontalBar chartChart.js 堆叠和分组水平条形图
【发布时间】:2016-10-29 09:15:00
【问题描述】:

我一直在尝试在我的网页上显示一些复杂的数据,因此选择了 chart.js。 因此,我需要将多个堆叠的条水平分组。

我已经为“普通”条找到了这个小提琴,但还不能完全改变它以与 Horizo​​ntalBar 一起使用。

Stackoverflow 问题:Chart.js stacked and grouped bar chart

原来的 Fiddle (http://jsfiddle.net/2xjwoLq0/) 有

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

我只是用 .horizo​​ntalBar 替换了代码中各处的 .bar(很清楚这不会成功)。

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

由于这不太奏效,我尝试按照此处对水平条的建议添加第二个堆叠修饰符: Horizontal stacked bar chart with chart.js并翻转了X和Y计算的函数(calculateBarY/calculateBarX)

这很有效,因为堆栈不会正确地相互合并。

http://jsfiddle.net/2xjwoLq0/3/

如果有人能帮我解决这个问题,我将不胜感激。

【问题讨论】:

    标签: javascript charts chart.js


    【解决方案1】:

    寻找类似的东西,我看了你给出的例子,并决定写一些东西。

    我没有尝试修复代码或重用“groupableBar”,而是从Chart.controllers.horizontalBar 获取Chart.js 代码并重写函数calculateBarYcalculateBarHeight 中的某些部分。 刚刚重用了您示例中的 getBarCount 函数。

    Chart.defaults.groupableHBar = Chart.helpers.clone(Chart.defaults.horizontalBar);
    
    Chart.controllers.groupableHBar = Chart.controllers.horizontalBar.extend({
        calculateBarY: function(index, datasetIndex, ruler) {
            var me = this;
            var meta = me.getMeta();
            var yScale = me.getScaleForId(meta.yAxisID);
            var barIndex = me.getBarIndex(datasetIndex);
            var topTick = yScale.getPixelForValue(null, index, datasetIndex, me.chart.isCombo);
            topTick -= me.chart.isCombo ? (ruler.tickHeight / 2) : 0;
            var stackIndex = this.getMeta().stackIndex;
    
            if (yScale.options.stacked) {
                if(ruler.datasetCount>1) {
                    var spBar=ruler.categorySpacing/ruler.datasetCount;
                    var h=me.calculateBarHeight(ruler);
                    
                    return topTick + (((ruler.categoryHeight - h) / 2)+ruler.categorySpacing-spBar/2)+(h+spBar)*stackIndex;
                }
                return topTick + (ruler.categoryHeight / 2) + ruler.categorySpacing;
            }
    
            return topTick +
                (ruler.barHeight / 2) +
                ruler.categorySpacing +
                (ruler.barHeight * barIndex) +
                (ruler.barSpacing / 2) +
                (ruler.barSpacing * barIndex);
        },
        calculateBarHeight: function(ruler) {
            var returned=0;
            var me = this;
            var yScale = me.getScaleForId(me.getMeta().yAxisID);
            if (yScale.options.barThickness) {
                returned = yScale.options.barThickness;
            }
            else {
                returned= yScale.options.stacked ? ruler.categoryHeight : ruler.barHeight;
            }
            if(ruler.datasetCount>1) {
                returned=returned/ruler.datasetCount;
            }
            return returned;
        },
        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: "Dogs",
          backgroundColor: "rgba(255,0,0,0.2)",
          data: [20, 10, 25],
          stack: 1,
          xAxisID: 'x-axis-0',
          yAxisID: 'y-axis-0'
        },
        {
          label: "Cats",
          backgroundColor: "rgba(255,255,0,0.2)",
          data: [70, 85, 65],
          stack: 1,
          xAxisID: 'x-axis-0',
          yAxisID: 'y-axis-0'
        },
        {
          label: "Birds",
          backgroundColor: "rgba(0,255,255,0.2)",
          data: [10, 5, 10],
          stack: 1,
          xAxisID: 'x-axis-0',
          yAxisID: 'y-axis-0'
    
        },
        {
          label: ":-)",
          backgroundColor: "rgba(0,255,0,0.2)",
          data: [20, 10, 30],
          stack: 2,
          xAxisID: 'x-axis-1',
          yAxisID: 'y-axis-0'
        },
        {
          label: ":-|",
          backgroundColor: "rgba(0,0,255,0.2)",
          data: [40, 50, 20],
          stack: 2,
          xAxisID: 'x-axis-1',
          yAxisID: 'y-axis-0'
        },
        {
          label: ":-(",
          backgroundColor: "rgba(0,0,0,0.2)",
          data: [60, 20, 20],
          stack: 2,
          xAxisID: 'x-axis-1',
          yAxisID: 'y-axis-0'
        },
      ]
    };
    
    var ctx = document.getElementById("myChart").getContext("2d");
    new Chart(ctx, {
      type: 'groupableHBar',
      data: data,
      options: {
        scales: {
          yAxes: [{
            stacked: true,
            type: 'category',
            id: 'y-axis-0'
          }],
          xAxes: [{
            stacked: true,
            type: 'linear',
            ticks: {
              beginAtZero:true
            },
            gridLines: {
              display: false,
              drawTicks: true,
            },
            id: 'x-axis-0'
          },
          {
            stacked: true,
            position: 'top',
            type: 'linear',
            ticks: {
              beginAtZero:true
            },
            id: 'x-axis-1',
            gridLines: {
              display: true,
              drawTicks: true,
            },
            display: false
          }]
        }
      }
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>
    <canvas id="myChart"></canvas>

    这里也放上 jsfiddle 的例子:https://jsfiddle.net/b7gnron7/4/

    代码没有经过严格测试,您可能会发现一些错误,尤其是当您尝试仅显示一个堆叠组时(在这种情况下使用 Horizo​​ntalBar)。

    您的帖子有点旧...不确定您是否仍然需要解决方案,但它可能对其他人有用^_^

    【讨论】:

    • @Rohan 谢谢 :)