3
votes

I have a stacked bar chart like this: http://jsfiddle.net/XFX5T/

I would like to know if it's possible to have the total of the negative + positive values as the stacked label.

if the total is positive, show the label at the top of the bar. if the total is negative, show the label at the bottom of the bar.

The grapes column in the example would have 40 as label for instance.

Looked at the documentation but looks like there is nog default config setting for this.

stackLabels: {
   enabled: true,
   style: {
     fontWeight: 'bold',
     color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
   }
 }
3

3 Answers

7
votes

You can try with a stackLabels formatter. For example:

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

    for (var i in series){
      sum+=series[i].yData[this.x];
    }
    if (sum < 0 && this.isNegative || sum >= 0 && !this.isNegative)
      return sum;
  }
...
}
1
votes

One shortcoming of the accepted answer is that it won't work with grouped stacks, because you'll get the total for all stack series, not just the series in each group.

Here is a function that works for grouped stacks (not that it's pretty):

    function() {
        var stackItem = this;
        var allStacks = stackItem.axis.stacks;
        for (var key in allStacks) {
            if (allStacks[key][stackItem.x] == stackItem) {
                var oppositeKey = stackItem.isNegative ? key.slice(1) : '-' + key;
                var oppositeItem = allStacks[oppositeKey] && allStacks[oppositeKey][stackItem.x];
                if (oppositeItem === undefined) {
                    if (stackItem.total != 0.0) {
                        return Highcharts.numberFormat(stackItem.total, 0);
                    }
                } else {
                    var sum = stackItem.total + oppositeItem.total;
                    if (stackItem.isNegative ^ sum > 0) {
                        return Highcharts.numberFormat(sum, 0);
                    }
                }
            }
        }
    };

N.b. I'm passing this from the formatter.

Here is a working example.

0
votes

If you happen to come across this issue, but your x-axis uses type: 'datetime', you can use this two-loop solution for the stackLabels.formatter to make it work:

formatter: function () {
    var sum = 0;
    var series = this.axis.series;

    for (var i = 0; i < series.length; i++){
        for(var j = 0; j < series[i].xData.length; j++) {
            if(series[i].xData[j] == this.x) {
                sum += series[i].yData[j];
                break;
            }
        }
    }

    if(sum < 0 && this.isNegative)
        return sum;
    else if(sum >= 0 && !this.isNegative)
        return sum;

     return;
}

As this JSFiddle demonstrates.