【问题标题】:How can I change the sort order of a D3 ordinal scale?如何更改 D3 序数比例的排序顺序?
【发布时间】:2014-05-08 05:29:07
【问题描述】:

我一直在使用 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,所以你可以尝试一下。

【问题讨论】:

  • 如果我理解您要正确执行的操作(我不确定我是否正确),您需要考虑元素的 previous 索引,不是新的:jsfiddle.net/gfsAL/1
  • 是的,没错。您已经有效地向我展示了我哪里出错了:我试图将 old_i 固定到 each(d) 而不是 each(this)。非常感谢 Lars - 如果您这样提出,我会认为这是一个答案。
  • 从技术上讲,您也可以使用数据而不是 DOM 来保存它。我会添加它作为答案。

标签: d3.js


【解决方案1】:

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

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

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

完整示例here。请注意,我还在更新时重新绑定数据 - 这是在更改回原始数据时使其正常工作所必需的,因为如果您仅更改比例,索引不会更改。

【讨论】:

  • 谢谢拉尔斯。遗憾的是它没有那么优雅(例如,不能对条形和轴标签使用定义的过渡),但它可以工作,这是主要的。
猜你喜欢
  • 2019-02-22
  • 2017-06-30
  • 2012-01-16
  • 1970-01-01
  • 2014-05-09
  • 2016-08-08
  • 1970-01-01
  • 2011-06-20
  • 1970-01-01
相关资源
最近更新 更多