Highcharts排序堆积的酒吧

时间:2018-02-06 21:09:21

标签: javascript sorting highcharts

我没有看到任何与我在Highcharts中遇到的确切场景相匹配的解决方案,所以我在这里发布我的发现。

我在Highcharts中有一个堆积条形图,需要按最大值到最小值对条形进行排序并保持其类别关系。通常,首选解决方案是在将数据发送到Highcharts之前对数据进行排序,但这不是我方案中的选项。

归功于我找到解决方案的原始海报here

2 个答案:

答案 0 :(得分:1)

在所有setData操作完成后,您应该只执行一次Chart.redraw()http://jsfiddle.net/BlackLabel/2mLg7235/

$.each(series, function(seriesIndex, ser) {
  (...)
  ser.setData(data, false);
});
chartSource.redraw();

在您的代码中,每次setData操作后都会重绘。

在我的例子中,排序功能执行速度快了两倍(由于这个修改)。

答案 1 :(得分:0)

此解决方案在对图表数据进行后处理时执行缓慢。如果我找到加快速度的方法,我会更新这里发布的代码。

http://jsfiddle.net/eecvsj7s/

$(function () {
    var chart;
    var sortData = function(chartSource) {
        var series = chartSource.series;
        var axis = chartSource.xAxis[0];
        var categories = [];

        if($.isArray(series)) {
            var ser = $.grep(series, function(ser, seriesIndex) {
                return ser.visible;
            })[0];
            $.each(ser.data, function(dataIndex, datum) {
                console.log(datum.category + ": " + datum.stackTotal);
                var obj = {
                    name: datum.category,
                    index: dataIndex,
                    stackTotal: datum.stackTotal
                }
                categories.push(obj);
            });
        }

        categories.sort(function(a, b) {
            var aName = a.name.toLowerCase();
            var bName = b.name.toLowerCase();
            var aTotal = a.stackTotal;
            var bTotal = b.stackTotal;
            if(aTotal === bTotal) {
                return ((aName < bName) ? -1 : ((aName > bName) ? 1 : 0));
            } else {
                return ((aTotal > bTotal) ? -1 : ((aTotal < bTotal) ? 1 : 0));
            }
        });

        var mappedIndex = $.map(categories, function(category, index) {
            return category.index;
        });

        categories = $.map(categories, function(category, index) {
            return category.name;
        });

        console.log(categories);
        console.log(mappedIndex);
        axis.setCategories(categories);

        $.each(series, function(seriesIndex, ser) {
            var data = $.map(mappedIndex, function(mappedIndex, origIndex) {
                return ser.data[mappedIndex].y;
            });
            ser.setData(data,false);
        });

        chartSource.redraw();

    };
    $(document).ready(function() {
        chart = new Highcharts.Chart({
            chart: {
                renderTo: 'container',
                type: 'bar'
            },
            title: {
                text: 'Stacked column chart'
            },
            xAxis: {
                categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
            },
            yAxis: {
                min: 0,
                title: {
                    text: 'Total fruit consumption'
                }
            },
            plotOptions: {
                series: {
                    stacking: 'normal',
                    events: {
                        hide: function() { sortData(chart); },
                        show: function() { sortData(chart); }
                    }                        
                }
            },
            series: [{
                name: 'John',
                data: [5, 3, 4, 7, 2]
            }, {
                name: 'Jane',
                data: [2, 2, 3, 2, 1]
            }, {
                name: 'Joe',
                data: [3, 4, 4, 2, 5]
            }]
        }, function(chart) { sortData(chart); });
    });
});