Search code examples
highchartsangular-highcharts

Highcharts Boxplot - box with lower, upper quartile and median is not displaying when min and max are null of a category


navigate to below fiddle and find first category is not showing boxplot. my expectation is that highcharts should show q1,q3 and median box. is there a way to render boxplot without min and max?

https://jsfiddle.net/rammohanreddy201/ga20p14y/28/

Highcharts.chart('container', {

chart: {
    type: 'boxplot'
},

title: {
    text: 'Highcharts Box Plot Example'
},

legend: {
    enabled: false
},

xAxis: {
    categories: ['1', '2', '3', '4', '5'],
    title: {
        text: 'Experiment No.'
    }
},

yAxis: {
    title: {
        text: 'Observations'
    },
    plotLines: [{
        value: 932,
        color: 'red',
        width: 1,
        label: {
            text: 'Theoretical mean: 932',
            align: 'center',
            style: {
                color: 'gray'
            }
        }
    }]
},

series: [{
    name: 'Observations',
    data: [
        [null, 801, 848, 895, null],
        [733, 853, 939, 980, 1080],
        [714, 762, 817, 870, 918],
        [724, 802, 806, 871, 950],
        [834, 836, 864, 882, 910]
    ],
    tooltip: {
        headerFormat: '<em>Experiment No {point.key}</em><br/>'
    }
}, {
    name: 'Outliers',
    color: Highcharts.getOptions().colors[0],
    type: 'scatter',
    data: [ // x, y positions where 0 is the first category
        [0, 644],
        [4, 718],
        [4, 951],
        [4, 969]
    ],
    marker: {
        fillColor: 'white',
        lineWidth: 1,
        lineColor: Highcharts.getOptions().colors[0]
    },
    tooltip: {
        pointFormat: 'Observation: {point.y}'
    }
}]

});


Solution

  • The implemented logic for the boxplot series requires 6 or 5 values in the array or in the data config objects - x,low,q1,median,q3,high. More: https://api.highcharts.com/highcharts/series.boxplot.data and https://www.highcharts.com/docs/chart-and-series-types/box-plot-series

    However, setting the low and high to the same value as q1 makes that their lines are invisible (are covered by the q1 line), so it could be a good workaround to your requirement. So the data config should look like this:

    data: [
      [801, 801, 848, 895, 801],
      [733, 853, 939, 980, 1080],
      [714, 762, 817, 870, 918],
      [724, 802, 806, 871, 950],
      [834, 836, 864, 882, 910]
    ],
    

    Next it will be nice to hide those values in the tooltip. We can use the formatter callback to achieve it:

      tooltip: {
        formatter(tooltip) {
          let point = this.point;
          if (point.low === point.q1 || point.high === point.q1) {
            point.low = null;
            point.high = null;
          }
          return tooltip.defaultFormatter.call(this, tooltip);
        }
      },
    

    Demo: https://jsfiddle.net/BlackLabel/rd4aLgne/

    API: https://api.highcharts.com/highcharts/tooltip.formatter