Решение предложено на форуме поддержки Highcharts:
In order to achieve desired behaviour, you can create 2D array of your data, map it that every point should contain y value and color, then rotate your array and sort each row, then rotate it back and save to original series array last step would 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) => a.y < b.y ? 1 : (a.y > b.y ? -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);