再次在dc.js中订购条形图标签

时间:2019-05-27 02:09:59

标签: javascript d3.js bar-chart dc.js crossfilter

我知道关于SO的特定主题有很多问题,但是没有一种解决方案适合我的情况。

这是我的数据:

var theData = [{
  "value": "190.79",
  "age_days": "22",
  "criteria": "FX"
}, {
  "value": "18.43",
  "age_days": "22",
  "criteria": "FX"
}, {...}]

我像这样将数据放入存储桶中:

var getAge = (d) => {
  if ((d.age_days) <= 7) {
    return (["1w", "2w", "1m", "3m", "6m", "1y", "All"]);
  } else if ((d.age_days) <= 14) {
    return (["2w", "1m", "3m", "6m", "1y", "All"]);
  } else if ((d.age_days) <= 30) {
    return (["1m", "3m", "6m", "1y", "All"]);
  } else if ((d.age_days) <= 90) {
    return (["3m", "6m", "1y", "All"]);
  } else if ((d.age_days) <= 180) {
    return (["6m", "1y", "All"]);
  } else if ((d.age_days) <= 360) {
    return (["1y", "All"]);
  } else {
    return (["All"]);
  }
};

var ndx = crossfilter(theData);
var dims = {};
var groups = {};

dims.age = ndx.dimension(getAge,true);
groups.age = {};
groups.age.valueSum = dims.age.group().reduceSum((d) => d.value);

然后我尝试使用伪造的组方法订购组:

var sort_group = (source_group, order) => { 
    return {
        all: () => {
            let g = source_group.all();
            let map = {};
            g.forEach(function (kv) {
                map[kv.key] = kv.value;
            });
            return order
                .filter((k) => map.hasOwnProperty(k))
                .map((k) => {
                    return {key: k, value: map[k]}
                });
        }
    };
};
var the_order = ["1w", "2w", "1m", "3m", "6m", "1y", "All"];
var the_sorted_age_group = sort_group(groups.age.valueSum, the_order);

然后我使用创建barChart

theAgeChart
  .height(200)
  .width(400)
  .dimension(dims.age)
  .group(the_sorted_age_group)
  .valueAccessor((d) => d.value)
  .x(d3.scaleBand())
  .xUnits(dc.units.ordinal);

但是仍然可以使用默认排序:

enter image description here

我创建了一个包含所有内容的jsFiddle here

如何使我的条形分类,如我所希望的那样?

1 个答案:

答案 0 :(得分:1)

当elasticX为true或未设置x缩放域时,坐标网格混合将生成X域

        if (_chart.elasticX() || _x.domain().length === 0) {
            _x.domain(_chart._ordinalXDomain());
        }

(source)

这完全有道理,但是在生成域时总是对其进行排序:

_chart._ordinalXDomain = function () {
    var groups = _chart._computeOrderedGroups(_chart.data());
    return groups.map(_chart.keyAccessor());
};

(source)

我猜我们可以考虑在ordering为空时不对域进行排序。

无论如何,一种解决方法是自行设置域:

.x(d3.scaleBand().domain(the_order))

您不需要对条形图的组进行排序。 (对于折线图,组的顺序必须与比例域一致,但对于条形图而言并不重要。)

设置域后,它也可以工作:

.group(groups.age.valueSum)

correctly sorted bars

Fork of your fiddle.

我想这个故事的寓意是自动生成图表很复杂。大多数时候,确实希望对X域进行排序,但是允许用户提供自己的排序的最佳方法是什么?

我不会说这是最好的方法,但是有一种方法可以使它起作用。

相关问题