iplus26
iplus26

Reputation: 2647

stackLabels configuration in Highcharts

I am working with highcharts and having some problems with stackLabels configuration of highcharts. I was asked to display a bar chart with "score/full score" format, e.g. 6 out of 10 should be like

⬛︎⬛︎⬛︎⬛︎⬛︎⬛︎⬜︎⬜︎⬜︎⬜︎ 6/10

And I faked it with stacked bar chart with 6 for the first part of the bar and 4 for the second part.

[Solved] However, I don't know how to display 6/10 in stackLabels (It seems that I can only use {total} in it, while I can use {point.y}/{point.fullscore} in dataLabels).

[Unsolved] And also, when I use the basic bar chart, dataLabels automatically adjust its position (In my case, dataLabels will show on the left of the right edge of the bar). However, how should I force the stackLabels to display?

This answer points out that there is no enough space for stackLabels to display, and the solution is to make max value bigger and leave some space for it. However, the solution is not that elegant to me, and also since my bar chart is horizontal and the label should be long.

enter image description here

Any help will be appreciated! Thanks in advance!

Upvotes: 2

Views: 4374

Answers (3)

Paweł Fus
Paweł Fus

Reputation: 45079

To answer second question:

You can set yAxis.stackLabels.crop to false, so labels will be rendered always. Those labels won't show up inside the plotting area, but will be rendered somewhere outside. stackLabels are not dataLabels - dataLabels have option justify, which forces labels to be rendered inside the plotting area.

However, in Highcharts you can get access to those labels, and move them (that's why crop needs to be set to false - to render labels anyway), here is simple POC:

function updateStacks() {
  var chart = this,
    H = Highcharts,
    padding = 15,
    item,
    bbox;

  for (var stackName in chart.yAxis[0].stacks) {
    for (var itemName in chart.yAxis[0].stacks[stackName]) {
      item = chart.yAxis[0].stacks[stackName][itemName]; // get stack item
      bbox = item.label.getBBox(true); // get label's bounding box

      // if label is outside, translate it:
      if (bbox.width + bbox.x > chart.plotWidth) {
        // add some poding, for a better look&feel:
        item.label.translate(-bbox.width - padding);
      }
    }
  }
}

Now simply use that method in load and redraw events, here you are:

chart: {
  type: 'bar',
  events: {
    redraw: updateStacks,
    load: updateStacks
  }
},

And live demo: http://jsfiddle.net/awe4abwk/ - let me know if something is not clear.

PS: Your answer with formatter for stackLabels is good!

Upvotes: 2

iplus26
iplus26

Reputation: 2647

Okay, I've found the solution for the first question: How to show the specific series values in stackLabels? from this answer.

In my case, the code should be:

yAxis: {
  stackLabels: {
    formatter: function() {
      return [this.axis.series[1].yData[this.x], '/', this.total].join('');
    },
    enabled: true,
  }
}

If you have better solution, post it! And I still have no idea about how to find it in the docs, maybe I should dig more...

Upvotes: 1

J-D
J-D

Reputation: 1575

Use formatter to change default stack label. You can access axis label with this.axis.

stackLabels: {

    enabled: true,
    formatter: function() {
        return (this.axis.series[1].yData[this.x] / this.total * 100).toPrecision(2) + '%';
       //Make your changes here to reflect your output. This is just a sample code
    }
}

Now to always show stack labels you have two options which are described here.

Link

Upvotes: 1

Related Questions