Highcharts Stack Column总和正和负

时间:2016-01-06 17:52:14

标签: javascript highcharts

我有一个堆积的柱形图,显示每个月堆叠一个的3个键/值。有些月份可能有负面影响。目前的功能是让highcharts每个月放置两个堆叠标签。一个用于积极(在顶部),一个用于阴性(在底部)。

请参阅下面的代码和js小提琴作为例子:

$(function () {
    $('#container').highcharts({
        chart: {
            type: 'column'
        },
        xAxis: {
            categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
        },
        yAxis: {
            stackLabels: {
                enabled: true,
                align: 'center'
            }
        },
        plotOptions: {
            column: {
                stacking: 'normal',
                pointPadding: 0,
                groupPadding: 0,
                dataLabels: {
                    enabled: false,
                    color: '#FFFFFF'
                }
            }
        },

        series: [{
            data: [29.9, -71.5, 106.4, -129.2, 144.0, -176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
        }, {
            data: [144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4, 29.9, 71.5, 106.4, 129.2]
        },
        {
            data: [55.9, 90.5, 106.4, 350.2, 144.0, 52.0, 130.6, 148.5, 216.4, 194.1, 95.6, 54.4]
        }]
    });
});

http://jsfiddle.net/sph1LjtL/

我希望的功能是实际上有一个堆叠标签,其中包含所有三个值的总和,而不是两个单独的标签。因此,对于二月(在小提琴中),它将在列上方显示195,因为266.50 - 71.50 = 195。

我一直试图找到一种方法来做到这一点,但一直没有成功,因为highcharts将积极和消极视为单独的图表。任何帮助,将不胜感激!谢谢。

4 个答案:

答案 0 :(得分:3)

这可能是一个解决方案,使用yAxis.stackLabels.formatter函数,并在处理正堆栈时查找负堆栈。在代码中:

yAxis: {
    stackLabels: {
        formatter: function() {
            if(this.total >= 0) {
                if(this.axis.stacks["-column"][this.x] != null)
                    return this.total + this.axis.stacks["-column"][this.x].total;
                else
                    return this.total;
            }
        }
        // ...
    }
}

请参阅this updated JSFiddle演示其工作原理。

答案 1 :(得分:2)

请参阅Working fiddle here

使用Pawel Fus(Highcharts)在this Link

提供的解决方案
 yAxis: {
        stackLabels: {
            enabled: true,
            align: 'center',
                      formatter: function() {
                var sum = 0;
                var series = this.axis.series;

                for (var i in series) {
                    if (series[i].visible && series[i].options.stacking == 'normal') 
                        sum += series[i].yData[this.x];
                }
                if(this.total > 0 ) {
                    return Highcharts.numberFormat(sum,1); 
                } else {
                    return '';    
                }
            }
        }
    }

答案 2 :(得分:1)

这可以使用yAxis.stackLabels.formatter并循环遍历系列数据项(以及在哪个轴上应用过滤器来应用标签)来完成。这是一个完整的(非常详细的)示例:

yAxis: {
  stackLabels: {
    enabled: true,
    align: 'center',
    formatter: function() {
      console.log(this);
      var theIndex = this.x;
      var theSeries = this.axis.series;
      var theSum = 0;

      for (var i = 0; i < theSeries.length; ++i) {
        theSum = theSum + theSeries[i].yData[theIndex]; //console.log(theSeries[i].yData[theIndex]);
      }
      if (this.isNegative == false) {
        return theSum;
      }
    }
  }
},

formatter内,我得到了积分的索引(x),供以后用于挑选正确的数据点。然后设置循环遍历所有系列项目。最后,我从系列对象中获取yData点并将它们相加以获得适当的xAxis索引。下一步是仅将滤波器应用于正轴位置。功能齐全的jsFiddle。请注意,您将不得不使用小数精度进行一些工作,我将其留给您。

答案 3 :(得分:0)

由Nishith改进Pawel Fuslinked above的答案,以容纳缺失的数据点以及负和(在这种情况下,总和显示在给定x轴索引的条形下方) :

yAxis: {
        stackLabels: {
            enabled: true,
            formatter: function() {
                var sum = 0;
                var series = this.axis.series;

                for (var i in series) {
                    if (series[i].visible 
                    && series[i].options.stacking == 'normal' 
                    && this.x in series[i].yData) 
                        sum += series[i].yData[this.x];
                }
                if (sum >= 0 && this.isNegative == false
                    || sum < 0 && this.isNegative == true) {
                    return Highcharts.numberFormat(sum,1); 
                } else {
                    return '';    
                }
            }
        }
    }

See JSFiddle here