如何更改D3序数量表的排序顺序?

时间:2014-05-07 20:28:24

标签: d3.js

我一直在与Mike Bostock的Sortable Bar Chart合作,这很好地错开了序数轴的排序。

初始排序是从左边开始的(从A,B,C ......开始),但反向是用相同的顺序(A,B,C ......)而不是从左边开始。这意味着字母从看似随机的位置开始移动,眼睛不能像第一种那样容易地跟随它。

我一直试图解决此问题,但我怀疑这可能是序数比例的限制:排序顺序是在设置域时指定的顺序。代码的排序元素位于底部。

var x0 = x.domain(data.sort(this.checked
    ? function(a, b) { return b.frequency - a.frequency; }
    : function(a, b) { return d3.ascending(a.letter, b.letter); })
    .map(function(d) { return d.letter; }))
    .copy();

var transition = svg.transition().duration(750),
    delay = function(d, i) { return i * 50; };

transition.selectAll(".bar")
    .delay(delay)
    .attr("x", function(d) { return x0(d.letter); });

transition.select(".x.axis")
    .call(xAxis)
  .selectAll("g")
    .delay(delay);

x0刻度被创建为x刻度的副本,以便为条形过渡提供静态参考点,因为x在过渡期间被补间。在此过程中,我认为x.domain也设置为目标排序顺序。我认为在设置新域时会重置i值,但它看起来不是:它们会持续通过域顺序的更改。

如何更改排序顺序,以便排序始终以最左边的类别开始?我尝试(不成功)在“g”上创建人工排序顺序,尝试我可以使用线性刻度实现这一目标,但序数量表应该是一个更简洁,更优雅的解决方案!

我已创建a fiddle,因此您可以尝试使用此功能。

1 个答案:

答案 0 :(得分:3)

根据您的规范,转换的开始将由更新前的订单确定。也就是说,更新前索引最低的元素应该是第一个。为此,您只需存储和引用转换的旧索引:

.each(function(d, i) { this.old_i = i; })
// ...
delay = function(d, i) { return this.old_i * 250; }

请注意,在转换两者时,需要保存条形和轴刻度/标签的索引。

完整示例here。请注意,我还会在更新时重新绑定数据 - 这有助于在更改回原始数据时使其工作,因为如果您只更改比例,索引不会发生变化。