【问题标题】:How to sort c3.js bar chart如何对 c3.js 条形图进行排序
【发布时间】:2018-04-03 15:51:21
【问题描述】:

我期待使用 c3.js 对条形图中的条形(不是堆积条形)进行排序。但是找不到合适的方法,下面提到了一个选项,但不适用于条形图。

data: {
    order: 'asc'
}

在我的例子中,所有数据都是动态的,并通过 c3.js 呈现以制作条形图。我正在寻找类似https://bl.ocks.org/mbostock/raw/3885705/的排序

【问题讨论】:

标签: javascript d3.js nvd3.js c3.js


【解决方案1】:

您的 jsfiddle 走在正确的轨道上,但由于传递给 c3.generate() 的数据是一组数据集,因此您不能只调用 data.sort()。

编辑

对于这种特定情况,如果您的数据采用您在 cmets 中描述的形式,这将是一种合适的方法。

我主要使用数组函数,如切片、拼接、映射和排序。如果您正在操作和绘制数据,这些是您熟悉的关键功能。 mozzila docs 是一个很好的起点。

你还应该注意哪些函数修改了它们被调用的数组,哪些返回了一个新数组;无意中更改数据通常会导致难以发现的错误。

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>

【讨论】:

  • 感谢您的帮助。我尝试了另一个更简单的,仅适用于 chrome jsfiddle.net/sipu/nr0zc3h6。但我有这样的数据 var data = [["a", "b", "c"],['data1', "30"," 200"," 100"]]。我希望数据应该像这样存储 data = [["a", "c", "b"],['data1', "30"," 100"," 200"]]。所以请帮帮我
  • 最简单的方法是将 x 和 y 数据组合成一个数据点数组 - 每个数据点表示为像 {x:"a", y:"30"} 这样的对象或一个数组 ["a","30"] 并使用约定,以便您知道哪个元素包含 x,哪个元素包含 y。然后,如果您使用对象或函数 (a,b) { return a[1] - b[1]} 用于数组,则可以将排序函数修改为 function (a,b) { return a.y - b.y}。不要忘记在排序之前删除“data1”列名,然后将其重新添加。这应该足以让您到达您需要的位置。
  • 您的 jsfiddle (jsfiddle.net/sipu/nr0zc3h6) 没有考虑到数组中的第一个元素是数据的名称这一事实,因此会导致问题。我已经编辑了我的帖子以考虑您的输入数据格式
  • 非常好,排序函数的逻辑很好,并且该功能可以添加到 c3 库中,那些正在寻找这个选项的人。非常感谢乔恩 :)。我也很好奇有些人是怎么做到的在不详细说明的情况下对问题投反对票。
  • 写出好的问题可能很困难,但值得付出努力,因为好的问题通常会带来好的答案。 Stackoverflow 有一个有用的指南,可以帮助避免将来投反对票:stackoverflow.com/help/how-to-ask
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 1970-01-01
  • 2017-12-06
  • 2020-09-01
  • 2018-07-03
  • 2013-02-12
  • 1970-01-01
相关资源
最近更新 更多