我正在开发一种互动,当然这不是D3的典型用法,但它对于创建和动画4部分叙述的前三个阶段非常有帮助。在最后阶段,我希望用户能够在几个因素之间进行选择。在每种情况下,排序将导致每个<rect>
处于两个组中的一个组中。从本质上讲,这只是一个分组的条形图。
图片比我想的更好,所以这里有两个例子:http://thatmichael.com/sandbox/immigration/sample.png
麻烦的是两组之间的差距很小。
如果所有<rect>
都在同一个<g>
内,我认为这样会很容易:
d3.select("#theGroup").selectAll("rect")
.sort(function(a, b) {
return d3.ascending(a.party, b.party) || d3.ascending(a.lastName, b.lastName);
});
但我希望保持群体之间的空间,因为看到分裂确实很有帮助。
另一个次优解决方案是以所有可能的方式嵌套数据,然后使用新数据集删除并重绘所有<rect>
s。像这样:
oldSenateByVote = d3.nest()
.key(function(d) {return d.vote;})
.sortKeys(d3.descending)
.entries(oldSenate);
var svg = d3.select("#barWrapper svg")
.attr("width", bar.w)
.attr("height", bar.h);
var g = svg.selectAll("g.groups")
.data(oldSenateByVote)
.enter()
.append("g")
.attr("class", "groups");
g.selectAll("rect")
.data(function(d) {return d.values})
.enter().append("rect")
.transition().duration(1000)
.attr("x", function(d, i) {
return i * (token.w + 1) + bar.paddingLeft;
});
.attr("y", bar.paddingTop)
.attr("width", token.w)
.attr("height", token.h)
.each(function(d, i) {
if (d.party == "R") {
d3.select(this).attr("class", "token gop");
} else {
d3.select(this).attr("class", "token dem");
}
});
但是因为从来没有任何元素进入或退出,所以最好是对象保持不变。
有谁知道这样做的方法?或者至少是假的吗?也许答案是只在一个“组”中为所有<rect>
添加一个类,并使用它来手动移动该组超过10px,尽管这看起来真的很糟糕。