Chart.js stacked bar ordering depending on value

霸气de小男生 提交于 2021-02-10 14:53:21

问题


I have a stacked bar but I want to order the bars based on the summed value of my two datasets. Does any one have any idea how to do this using chart.js functionality?

See here

data: {
        labels: stores,
        datasets: [
        {
            label: 'Rev',
            data: dataPack1,
                        backgroundColor: "rgba(55, 160, 225, 0.7)",
                        hoverBackgroundColor: "rgba(55, 160, 225, 0.7)",
                        hoverBorderWidth: 2,
                        hoverBorderColor: 'lightgrey'
        },
        {
            label: 'Tax1',
            data: dataPack2,
                        backgroundColor: "rgba(225, 58, 55, 0.7)",
                        hoverBackgroundColor: "rgba(225, 58, 55, 0.7)",
                        hoverBorderWidth: 2,
                        hoverBorderColor: 'lightgrey'
        },
        ]
    },

回答1:


If you have a scenario where multiple stacked bars have the same sum total, the accepted answer will duplicate the labels.

This will not duplicate the labels:

        Chart.plugins.register({                                                                                                                                                             
        datasets: [],                                                                                                                                                                    
        getData(labels, datasets) {                                                                                                                                                      
            const sum = [];                                                                                                                                                              
            for (i = 0; i < datasets[0].length; i++) {                                                                                                                                   
                sum.push({                                                                                                                                                               
                    label: labels[i],                                                                                                                                                    
                    data: datasets.map(e => e[i]),                                                                                                                                       
                        get sum() { // ES6 - getter                                                                                                                                      
                            return this.data.reduce((a, b) => a + b);                                                                                                                    
                        }                                                                                                                                                                
                });                                                                                                                                                                      
            }                                                                                                                                                                            
            return sum;                                                                                                                                                                  
        },                                                                                                                                                                               
        beforeInit(chart) {                                                                                                                                                              
            chart.data.datasets.forEach((dataset, datasetIndex) => {                                                                                                                     
                this.datasets.push(dataset.data);                                                                                                                                        
            });                                                                                                                                                                          
            const data_store = this.getData(chart.data.labels, this.datasets).sort((a,b) => b.sum - a.sum);                                                                              

            data_store.forEach((d,i) => {                                                                                                                                                
                chart.data.labels[i] = d.label;                                                                                                                                          
                d.data.forEach((v, vi) => {                                                                                                                                              
                    chart.data.datasets[vi].data[i] = v;                                                                                                                                 
                });                                                                                                                                                                      
            });                                                                                                                                                                          
        }                                                                                                                                                                                
    });   



回答2:


This could be achieved more efficiently and effectively using the following chart plugin :

Chart.plugins.register({
   datasets: [],
   getData(labels, datasets) {
      const sum = [];
      for (i = 0; i < datasets[0].length; i++) {
         sum.push({
            label: labels[i],
            data: datasets.map(e => e[i]),
            get sum() { // ES6 - getter
               return this.data.reduce((a, b) => a + b);
            }
         });
      }
      return sum;
   },
   beforeInit(chart) {
      chart.data.datasets.forEach((dataset, datasetIndex) => {
         this.datasets.push(dataset.data);
      });
      const data_store = this.getData(chart.data.labels, this.datasets),
            sorted = data_store.map(e => e.sum).sort((a, b) => b - a);
      sorted.forEach((n, ni) => {
         data_store.forEach(d => {
            if (d.sum === n) {
               chart.data.labels[ni] = d.label;
               d.data.forEach((v, vi) => {
                  chart.data.datasets[vi].data[ni] = v;
               });
            }
         });
      });
   }
});

* add this plugin at the beginning of your script.

ᴡᴏʀᴋɪɴɢ ᴇxᴀᴍᴘʟᴇ ⧩

Chart.plugins.register({
   datasets: [],
   getData(labels, datasets) {
      const sum = [];
      for (i = 0; i < datasets[0].length; i++) {
         sum.push({
            label: labels[i],
            data: datasets.map(e => e[i]),
            get sum() { // ES6 - getter
               return this.data.reduce((a, b) => a + b);
            }
         });
      }
      return sum;
   },
   beforeInit(chart) {
      chart.data.datasets.forEach((dataset, datasetIndex) => {
         this.datasets.push(dataset.data);
      });
      const data_store = this.getData(chart.data.labels, this.datasets),
         	sorted = data_store.map(e => e.sum).sort((a, b) => b - a);
      sorted.forEach((n, ni) => {
         data_store.forEach(d => {
            if (d.sum === n) {
               chart.data.labels[ni] = d.label;
               d.data.forEach((v, vi) => {
                  chart.data.datasets[vi].data[ni] = v;
               });
            }
         });
      });
   }
});

var numberWithCommas = function(x) {
   return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
};

var dataPack1 = [21000, 22000, 26000, 35000, 55000, 55000, 56000, 59000, 60000];
var dataPack2 = [1000, 1200, 1300, 140000, 1060, 2030, 2070, 4000, 4100];
var stores = ["A", "B", "C", "D", "E", "F", "G", "H", "I"];

var bar_ctx = document.getElementById('bar-chart');
var bar_chart = new Chart(bar_ctx, {
   type: 'bar',
   data: {
      labels: stores,
      datasets: [{
         label: 'Rev',
         data: dataPack1,
         backgroundColor: "rgba(55, 160, 225, 0.7)",
         hoverBackgroundColor: "rgba(55, 160, 225, 0.7)",
         hoverBorderWidth: 2,
         hoverBorderColor: 'lightgrey'
      }, {
         label: 'Tax1',
         data: dataPack2,
         backgroundColor: "rgba(225, 58, 55, 0.7)",
         hoverBackgroundColor: "rgba(225, 58, 55, 0.7)",
         hoverBorderWidth: 2,
         hoverBorderColor: 'lightgrey'
      }]
   },
   options: {
      animation: {
         duration: 10,
      },
      tooltips: {
         mode: 'label',
         callbacks: {
            label: function(tooltipItem, data) {
               return data.datasets[tooltipItem.datasetIndex].label + ": " + numberWithCommas(tooltipItem.yLabel);
            }
         }
      },
      scales: {
         xAxes: [{
            stacked: true,
            gridLines: {
               display: false
            },
         }],
         yAxes: [{
            stacked: true,
            ticks: {
               callback: function(value) {
                  return numberWithCommas(value);
               },
            },
         }],
      },
      legend: {
         display: true
      }
   }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.6/Chart.min.js"></script>
<canvas id="bar-chart" width="600" height="350"></canvas>


来源:https://stackoverflow.com/questions/45820619/chart-js-stacked-bar-ordering-depending-on-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!