0

When I'm drawing BOX Plot chart with Highchart like this : JSFiddle

chart: {
        type: 'boxplot',

    }

where category 2 "Merchant 2" is shown on x-axis even though we don't have data for it.

How can we avoid rendering categories on x-axis when they don't have data in box plot ?

Thank you

Enigma
  • 749
  • 1
  • 13
  • 35

1 Answers1

1

There's no built in mechanism in Highcharts that'll filter out and hide "unused" categories.

Workaround:

breaks functionality allows to hide regions on axes. Here's an algorithm that finds the categories that don't have any points above them and applies breaks:

    render: function() {
      if (redrawEnabled) {
        redrawEnabled = false;

        var emptyCategories = [],
          series = this.series,
          xAxis = this.xAxis[0],
          categories = xAxis.categories.slice(),
          categoryFlags = new Array(categories.length).fill(false), // indicates if any point has a value for category with the given index
          breaks = [],
          correspondingPoint;


        // find out which categories are 'used'
        for (var i = 0; i < categories.length; i++) {

          for (var ii = 0; ii < series.length; ii++) {
            if (!series[ii].visible) {
              continue;
            }

            correspondingPoint = series[ii].data.find((point) => point.x === i);
            if (correspondingPoint) {
              categoryFlags[i] = true;
              break;
            }
          }
        }

        // create and apply breaks
        categoryFlags.forEach(function(flag, index) {
          if (!flag) {
            breaks.push({
              from: index - 0.5,
              to: index + 0.5
            });
          }
        });

        //console.log(breaks)
        xAxis.update({
          breaks: breaks
        });
      }
      redrawEnabled = true;
    }

Live demo: http://jsfiddle.net/BlackLabel/fubwdm4x/

The key to understand how this solution works is that the categories are basically just information how to format axis' labels and position ticks. The tickInterval is always 1 and ticks are moved -0.5 to the left. So if you have categories like this: ['Category 1', 'Category 2', 'Category 3'] the positions of ticks are: -0.5, 0.5, 1.5 and 2.5.


API reference: https://api.highcharts.com/highcharts/yAxis.breaks

Kamil Kulig
  • 5,756
  • 1
  • 8
  • 12
  • Thanks for solution - This is really working good for me with one exception that - this solution actually shows -1, -1.5 or -2 on x-axis when we hide any category (by turning legend off) - Any workaround for that ? or is it inevitable ? – Enigma Apr 26 '18 at 04:47
  • You're right, thanks for pointing that out. A small improvement helped: I changed the event from `load` to `redraw` and added a small mechanism that prevents infinite recursive loop in it (`update` calls `redraw` - `redrawEnabled` flags solves this problem). I updated the fiddle that I posted in my answer. – Kamil Kulig Apr 26 '18 at 19:26
  • Thank you so much Kamil Kulig. Much appreciated. – Enigma Apr 27 '18 at 05:21
  • @KamilKulig, I added one more category and series in chart and tried your JS fiddle. Now, category[1] is getting display if you select series(Mange). Could you please let me know how to hide category[i] when select series(mango). Please refer updated JS fiddle http://jsfiddle.net/fubwdm4x/14/ – Jitendra Apr 27 '18 at 08:00
  • Another updated was needed. I changed the `points` property to `data` because it contains all the points - even the ones that are not visible. I also added one `if` statement that ignores currently hidden series. Please refer to the fiddle in my answer. – Kamil Kulig Apr 27 '18 at 14:28
  • @KamilKulig Thank you that looks very promising and we are way ahead with this solution. many thanks – Enigma Apr 30 '18 at 10:55