-3

I was looking forward to sorting the bars in the bar chart (not stacked bar) using c3.js. But could not find any suitable way, there is an option mentioned below but that's not applicable for the bar chart.

data: {
    order: 'asc'
}

In my case, all data are coming dynamically and rendering through c3.js to make a bar chart.I was looking for a sort like https://bl.ocks.org/mbostock/raw/3885705/

Chirag Patel
  • 373
  • 5
  • 20
user3172663
  • 312
  • 3
  • 14

1 Answers1

2

You were on the right track with your jsfiddle but as the data passed to c3.generate() is an array of datasets then you cannot just call data.sort().

EDIT

For this specific case, where your data is in the form you described in your comments, this would be a suitable method.

I primarily used array functions like slice, splice, map and sort. These are key functions to gain familiarity with if you are manipulating and plotting data. The mozzila docs are a great point to start.

You should also note which functions modify the array they are called on and which return a new array; Mutating your data when you did not intend to can often cause hard-to-spot bugs.

var data = [
  ["a", "b", "c"],
  ['data1', "30", " 200", " 100"]
]

// declare a function to control variable scope
var sortData = function(unsortedData) {

  // deep copy array to avoid modification of input array
  var sorted = unsortedData.map(function(row) {
    // use slice to copy this array
    return row.slice()
  })

  // remove the dataname
  var name = sorted[1].splice(0, 1);

  // produce an array of data points [[x1,y1],[x2,y2]...]
  var datapoints = sorted[1].map(function(d, i) {
    // use index in map function to pull out name
    // return array for datapoint [x,y]
    return [sorted[0][i], d];
  });

  //sort datapoints
  var sortedData = datapoints.sort(function(a, b) {
    return a[1] - b[1];
  });

  // map back into separate x and y data
  sorted[1] = sortedData.map(function(point, i) {
    // assign x value to data[0] element
    sorted[0][i] = point[0];
    // return the y data point
    return point[1];
  });

  // add the dataname back into the y data
  sorted[1] = name.concat(sorted[1]);

  // add the 'x' label name to x-values
  sorted[0].splice(0, 0, 'x')

  // return the sorted array
  return sorted
}

var chart = c3.generate({
  data: {
    x: 'x',
    columns: sortData(data),
    type: 'bar',
  },
  axis: {
    x: {
      type: 'category' // this needed to load string x value
    }
  }
})
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.18/c3.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.18/c3.js"></script>

<div id="chart"></div>
John
  • 1,313
  • 9
  • 21
  • Thank you for your help.I tried another simper one that worked on chrome only jsfiddle.net/sipu/nr0zc3h6. But I have a data like this var data = [["a", "b", "c"],['data1', "30"," 200"," 100"]]. I want the data should be stored like this data = [["a", "c", "b"],['data1', "30"," 100"," 200"]]. So please help me out – user3172663 Oct 23 '17 at 12:08
  • The easiest method is to combine the x and y data into an array of data points - each data point represented as either an object like {x:"a", y:"30"} or as an array ["a","30"] and use a convention so you know which element contains the x and which element contains the y. You can then modify the sort function to be function (a,b) { return a.y - b.y} if you are using objects or function (a,b) { return a[1] - b[1]} for arrays. Don't forget to remove the 'data1' column name before sorting and then add it back in. That should hopefully be enough to get you where you need to be. – John Oct 23 '17 at 12:12
  • Your jsfiddle (jsfiddle.net/sipu/nr0zc3h6) does not take account of the fact that your first element in the array is the name of the data so it will be causing problems. I have edited my post to take account of your input data format – John Oct 23 '17 at 13:11
  • Excellent, great logic for a sort function and the functionality can be added to the c3 lib those who are looking for this option too.Thank you so much Jon :).I am also curious how some guys down-vote the question without going through details. – user3172663 Oct 23 '17 at 15:58
  • Writing good questions can be difficult but it is worth the effort as good questions generally lead to good answers. Stackoverflow has a helpful guide to help avoid down votes in the future: https://stackoverflow.com/help/how-to-ask – John Oct 23 '17 at 21:44