如何在chartjs中排序、插入和更新完整数据集?完整、数据、如何在、chartjs

2023-09-08 09:00:33 作者:旧伤 -Too ha

I have a few issues with chartjs which simple update method won't solve.

I wonder if there is an option to:

painlessly sort the datasets; insert some data in between two points; reload the whole chart without replacing the canvas with a completely new chart? chart.js 饼图显示百分比 饼图

解决方案

There is no option built in, but it is pretty easy to write your own using the addData, removeData methods that Chart.js provides.

var MyBarChartMethods = {
    // sort a dataset
    sort: function (chart, datasetIndex) {
        var data = []
        chart.datasets.forEach(function (dataset, i) {
            dataset.bars.forEach(function (bar, j) {
                if (i === 0) {
                    data.push({
                        label: chart.scale.xLabels[j],
                        values: [bar.value]
                    })
                } else 
                    data[j].values.push(bar.value)
            });
        })

        data.sort(function (a, b) {
            if (a.values[datasetIndex] > b.values[datasetIndex])
                return -1;
            else if (a.values[datasetIndex] < b.values[datasetIndex])
                return 1;
            else
                return 0;
        })

        chart.datasets.forEach(function (dataset, i) {
            dataset.bars.forEach(function (bar, j) {
                if (i === 0)
                    chart.scale.xLabels[j] = data[j].label;
                bar.label = data[j].label;
                bar.value = data[j].values[i];
            })
        });
        chart.update();
    },
    // reload data
    reload: function (chart, datasetIndex, labels, values) {
        var diff = chart.datasets[datasetIndex].bars.length - values.length;
        if (diff < 0) {
            for (var i = 0; i < -diff; i++)
                chart.addData([0], "");
        } else if (diff > 0) {
            for (var i = 0; i < diff; i++)
                chart.removeData();
        }

        chart.datasets[datasetIndex].bars.forEach(function (bar, i) {
            chart.scale.xLabels[i] = labels[i];
            bar.value = values[i];
        })
        chart.update();
    }
}

which you call like so (where myBarChart is your chart)

// sort
MyBarChartMethods.sort(myBarChart, 0)
// reload - same number of values
MyBarChartMethods.reload(myBarChart, 0, ["J", "F", "M", "A", "M", "J", "J"], [1, 2, 3, 4, 5, 6, 7])
// reload - more values
MyBarChartMethods.reload(myBarChart, 0, ["J", "F", "M", "A", "M", "J", "J", "A"], [1, 2, 3, 4, 5, 6, 7, 8])
// reload - less values
MyBarChartMethods.reload(myBarChart, 0, ["J", "F", "M", "A", "M"], [1, 2, 3, 4, 5])

Inserting 2 points is special case of reload, so you can use the same function (or write your own based on that easily)

Fiddle - http://jsfiddle.net/Lkdxxkfa/