[Chartjs]-Chart.js not resorting rows based on plugin after using update function

1👍

The sorting is quite complexe because you can’t simply change the data, you need to know the order for the labels as well. You find my code in the JSBin. I hope this is what you want.

Complete code:

let chartOptions = {
  scales: {
    xAxes: [{
      stacked: true
    }],
    yAxes: [{
      stacked: true
    }]
  }
}

let chartData = {
  labels: ["FirstValue", "SecondValue", "ThirdValue", "FourthValue"],
  datasets: [{
    label: 'FirstDataset',
    data: [12, 55, 33, 85],
    backgroundColor: 'red'
  },{
    label: 'SecondDataset',
    data: [95, 15, 73, 5],
    backgroundColor: 'blue'
  },{
    label: 'ThirdDataset',
    data: [38, 17, 73, 45],
    backgroundColor: 'green'
  },{
    label: 'FourthDataset',
    data: [49, 89, 33, 85],
    backgroundColor: 'orange'
  }]
}

let sortedData = sortData(chartData)

let ctx = document.getElementById("myChart");
let stackedBar = new Chart(ctx, {
  type: 'bar',
  data: sortedData,
  options: chartOptions
});

function sortData(chartData) {
  console.log('#############')
  console.log('beforeSort', chartData)
  let arraySum = []
  let sortedData = {}
  sortedData.labels = []
  sortedData.datasets = []

  // Calculate the total sum of all datasets for each label
  for (let i = 0; i < chartData.labels.length; i++) {
    let dataSum = 0
    chartData.datasets.map(obj => {
      dataSum += obj.data[i]
    })
    arraySum.push(dataSum)
  }
  //console.log("Data sum", arraySum)

  // Get a lookup-table with the order of the labels
  let arrayLookupTable = []
  for (let i = 0; i < chartData.labels.length; i++) {
    let index = arraySum.indexOf(Math.max.apply(null,arraySum))
    arrayLookupTable.push(index)
    arraySum[index] = -1
  }
  //console.log("arrayLookupTable", arrayLookupTable)

  // Assign the sorted labels
  for (let i = 0; i < chartData.labels.length; i++) {    
    sortedData.labels.push(chartData.labels[arrayLookupTable[i]])
  }

  // Assign the sorted datasets
  for (let i = 0; i < chartData.datasets.length; i++) {
    sortedData.datasets.push(chartData.datasets[i])
    //previous line copies complete dataset with old data which gets sorted in the next line
    sortedData.datasets[i].data = changeDataOrder(sortedData.datasets[i].data, arrayLookupTable)
  }

  console.log("afterSort", sortedData)
  return sortedData
}

function changeDataOrder(previousDataArray, arrayLookupTable) {
  //console.log('changeDataOrder', previousDataArray, arrayLookupTable)
  let newDataArray = []
  for (let i = 0; i < arrayLookupTable.length; i++) {
    newDataArray.push(previousDataArray[arrayLookupTable[i]])
  }
  return newDataArray
}

function updateChart() {
  chartData.datasets.forEach(function(element) {
    element.data = r(chartData.labels.length);
  });

  let updatedChart = sortData(chartData)
  stackedBar.config.data.labels = updatedChart.labels; //labels have to be updated separately
  stackedBar.update();
}

function r(length) {
  let values = [];
  for (i = 0; i < length; i++) { 
    values.push(Math.floor(Math.random() * 100));
  }
  return values;
}

Leave a comment