The solution is suggested on the Highcharts support forum:
If you want, you can create your own data. be mapping 0 values to null.
jsfiddle
// Initial data var data = [ [107, 131, 635, 203, 29, 152, 954, 420, 740, 38, 42, 156], [133, 50, 0, 408, 6, 40, 107, 31, 635, 203, 222, 225], [152, 200, 420, 740, 38, 133, 156, 947, 152, 408, 6, 40] ]; var colors = Highcharts.getOptions().colors; // Map array of numbers to array of objects with color property var series = data.map((serieData, index) => { return { name: 'Item ' + index, data: serieData.map((pointData, i) => { return { y: pointData, color: colors[index] } }) } }); // Create rotated array var width = series[0].data.length; var height = series.length; var rotated = []; for (let i = 0; i < height; ++i) { for (let j = 0; j < width; ++j) { rotated[j] = rotated[j] ? rotated[j] : {data: []}; rotated[j].data.push(series[height-i-1].data[width-j-1]) } } // Sort every row of rotated array for (let i = 0; i < width; ++i) { rotated[i].data.sort((a, b) => ay < by ? 1 : (ay > by ? -1 : 0)); } // Rotate back and update series array for (let i = 0; i < width; ++i) { for (let j = 0; j < height; ++j) { series[j] = series[j] ? series[j] : {data: []}; series[j].data[i] = rotated[width-i-1].data[height-j-1] } } // Filter empty elements series = series.map(seriesData => { seriesData.data = seriesData.data.map(pointData => !!pointData.y ? pointData : null); return seriesData; }); // Options var options = { chart: { type: 'bar' }, xAxis: { categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' ] }, legend: { layout: 'vertical', align: 'right', verticalAlign: 'top', x: -40, y: 80, floating: true, borderWidth: 1, }, series: series }; // Create chart var chart = Highcharts.chart('container', options);