0
votes

Currently information is only the bottom edge of the bar. But, need to show information on both ends of the bars in stacked grouped bar chart.

I'm using stack labels to show information which has been aligned to show information on the bottom of the bar.

Requirement: Total of the stacked bar needs to be shown at top, whereas the category name needs to be remain at bottom.

I googled about the same, but no help.

Looking for solution. Thanks in advance.

JSFiddle: http://jsfiddle.net/mkdudeja/c5debf6g/6/

$(function () {
    
    var options = {
      chart: {
        type: 'column',
        backgroundColor: '#f6f6f7'
      },
      title: {
        text: ''
      },
      credits: {
        enabled: false
      },
      exporting: {
        enabled: false
      },
      legend: {
        symbolRadius: 2,
        itemStyle: {
          color: '#666',
          fontSize: '1.1rem',
          fontWeight: '400',
          fontFamily: '"Open Sans", Arial, sans-serif'
        }
      },
      xAxis: {
        categories: ['Overall', 'Timing', 'Impact'],
        labels: {
          y: 60,
          style: {
            color: '#333',
            fontSize: '1.3rem',
            fontWeight: '600',
            fontFamily: '"Open Sans", Arial, sans-serif'
          }
        }
      },
      yAxis: {
        min: 0,
        allowDecimals: false,
        lineWidth: 0,
        minorGridLineWidth: 0,
        lineColor: 'transparent',
        minorTickLength: 0,
        tickLength: 0,
        title: {
          text: ''
        },
        labels: {
          enabled: false
        },
        stackLabels: {
          enabled: true,
          verticalAlign: 'bottom',
          crop: false,
          overflow: 'none',
          y: 20,
          formatter: function () {
            const $this = this;
            return '$' + $this.total + 'M' +
              '<br>' + $this.stack;
          },
          style: {
            color: '#666',
            fontSize: '1.1rem',
            fontWeight: '400',
            fontFamily: '"Open Sans", Arial, sans-serif'
          }
        }
      },
      tooltip: {
        formatter: function () {
          const $this = this;
          return '$' + $this.y + 'M' +
            '<br>' + $this.point.params.label;
        }
      },
      plotOptions: {
        column: {
          stacking: 'normal',
          dataLabels: {
            enabled: true,
            color: 'white',
            formatter: function () {
              const $this = this;
              return (($this.y * 100) / $this.total).toFixed(1) + '%';
            }
          }
        }
      },
      series: [{
        type: undefined,
        name: 'Off Track',
        data: [
          {
            y: 12,
            params: {
              label: '12 initiatives'
            }
          },
          {
            y: 5,
            params: {
              label: '5 initiatives'
            }
          },
          {
            y: 4,
            params: {
              label: '4 initiatives'
            }
          }
        ],
        stack: 'Plan',
        color: '#b02c3b'
      }, {
        type: undefined,
        name: 'At Risk',
        data: [
          {
            y: 6,
            params: {
              label: '6 initiatives'
            }
          },
          {
            y: 9,
            params: {
              label: '9 initiatives'
            }
          },
          {
            y: 6,
            params: {
              label: '6 initiatives'
            }
          }
        ],
        stack: 'Plan',
        color: '#fbd155'
      }, {
        type: undefined,
        name: 'On Track',
        data: [
          {
            y: 10,
            params: {
              label: '10 initiatives'
            }
          },
          {
            y: 4,
            params: {
              label: '4 initiatives'
            }
          },
          {
            y: 7,
            params: {
              label: '7 initiatives'
            }
          }
        ],
        stack: 'Plan',
        color: '#35a761'
      }, {
        type: undefined,
        name: 'Off Track',
        data: [
          {
            y: 9,
            params: {
              label: '9 initiatives'
            }
          },
          {
            y: 6,
            params: {
              label: '6 initiatives'
            }
          },
          {
            y: 6,
            params: {
              label: '6 initiatives'
            }
          }
        ],
        stack: 'Forcast',
        color: '#b02c3b',
        showInLegend: false
      }, {
        type: undefined,
        name: 'At Risk',
        data: [
          {
            y: 5,
            params: {
              label: '5 initiatives'
            }
          },
          {
            y: 6,
            params: {
              label: '6 initiatives'
            }
          },
          {
            y: 10,
            params: {
              label: '10 initiatives'
            }
          }
        ],
        stack: 'Forcast',
        color: '#fbd155',
        showInLegend: false
      }, {
        type: undefined,
        name: 'On Track',
        data: [
          {
            y: 7,
            params: {
              label: '7 initiatives'
            }
          },
          {
            y: 6,
            params: {
              label: '6 initiatives'
            }
          },
          {
            y: 8,
            params: {
              label: '8 initiatives'
            }
          }
        ],
        stack: 'Forcast',
        color: '#35a761',
        showInLegend: false
      }]
    };
    

    $('#container').highcharts(options);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>

<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>

Thanks, Manish

1

1 Answers

1
votes

You can place stack labels at top by default and in the render event move the stack names to the bottom:

    chart: {
        ...,
        events: {
            render: function() {
                var labels = this.yAxis[0].stackTotalGroup.element.children;

                for (var i = 0; i < labels.length; i++) {
                    labels[i].children[1].setAttribute('y', 275);
                    labels[i].children[3].setAttribute('y', 275);
                }
            }
        }
    }

Live demo: http://jsfiddle.net/BlackLabel/9raLyx85/

API Reference: https://api.highcharts.com/highcharts/chart.events.render