auri.borealis
auri.borealis

Reputation: 61

Highcharts show stacked column total sum always on top (even negatives)

I have a chart with stacked columns. Positive and negative values. Example:

$(function () {
    $('#container').highcharts({
        chart: {
            type: 'column'
        },
        title: {
        text: 'show total sum always on top (also negatives)',
        },
        xAxis: {
            categories: ['positives', 'mixed', 'negatives']
        },
        yAxis: {
            stackLabels: {
                enabled: true,
                align: 'center'
            },
            gridLineWidth: 0,
            minorGridLineWidth: 0,
            plotLines: [{
                        color: '#333',
                        width: 1,
                        dashStyle: 'dash',
                        value: 0
                    }],
          stackLabels: {
            enabled: true,
            align: 'center',
            style: {
              fontWeight: 'normal',
              color: 'red',
              fontSize: '10px'
            },
            
          }
        },
        plotOptions: {
        		series: {
              pointWidth: 40
        		},
            column: {
                stacking: 'normal',
                pointPadding: 0,
                groupPadding: 0,
                dataLabels: {
                    enabled: false,
                    color: '#FFFFFF'
                }
            }
        },
        series: [{
            data: [10, -10, -5]
        }, 
        {
            data: [15, -5, -5]
        },
        {
            data: [10, 20, -5]
        }]
    });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div id="container" style="height: 400px"></div>
<script src="https://code.highcharts.com/highcharts.js"></script>

http://jsfiddle.net/tmrLwj17/1/

What I need to achieve, is that I need to display sum of negatives and positives always on top. It works fine when there are only positive values. I was looking into similar fiddle: http://jsfiddle.net/sph1LjtL/5/ Sum of negatives always are below. I need them on top. Thanks!

expected top labels

Upvotes: 0

Views: 2674

Answers (1)

Kamil Kulig
Kamil Kulig

Reputation: 5826

Refer to this live demo: http://jsfiddle.net/kkulig/0upL93mb/

I compute custom values for labels in chart.events.render because there I'm able to easily access and manipulate y axis stacks (redrawEnabled flag prevents infinite recursive loop - Chart.redraw() calls render event):

Refer to this live demo: http://jsfiddle.net/kkulig/5t9z9sto/

I compute custom values for labels in chart.events.render because there I'm able to easily access and manipulate y axis stacks (redrawEnabled flag prevents infinite recursive loop - Chart.redraw() calls render event):

chart: {
  type: 'column',
  events: {
    render: function() {

      if (redrawEnabled) {
        redrawEnabled = false;

        var stacks = this.yAxis[0].stacks,
          yAxis = this.yAxis[0];

        // show some additional space for the negative column labels
        if (yAxis.max <= 0) {
          yAxis.setExtremes(null, 5);
        }

        for (var prop in stacks['-column']) {
          var negColumn = stacks['-column'][prop],
            posColumn; // corresponding positive column

          if (stacks.column) {
            posColumn = stacks.column[prop]
          }

          if (posColumn) {
            // add custom properties that will be used in stackLabels.formatter
            posColumn.totalToDisplay = posColumn.total + negColumn.total;
            negColumn.hideStackLabel = true;
          } else { // change the position of the negative stack label
            negColumn.label.alignOptions.verticalAlign = 'top';
            negColumn.label.alignOptions.y = -8;
            negColumn.hideStackLabel = false;
          }
        }

        // stackLabels.formatter launches before events.load so the chart needs to be redrawn to launch it again
        this.redraw(true);
        redrawEnabled = true;
      }
    }
  }
}

Then I use them in stackLabels.foramtter:

    formatter: function() {
      return this.hideStackLabel ? '' : this.totalToDisplay || this.total;
    }

Then I use them in stackLabels.foramtter:

    formatter: function() {
      return this.hideStackLabel ? '' : this.totalToDisplay || this.total;
    }

Upvotes: 1

Related Questions