0

我正在开发一个交互,诚然这不是 D3 的典型用途,但它对创建 4 部分叙事的前 3 个阶段并制作动画非常有帮助。在最后阶段,我希望用户能够在几个因素之间进行选择以进行排序。在每种情况下,排序都会导致每个<rect>人都在两个组中的一个中。本质上,这只是一个分组条形图。

我认为图片比文字好,所以这里有两个例子:http ://thatmichael.com/sandbox/immigration/sample.png


问题是两组之间的差距很小。

如果所有的<rect>s 都在同一内部<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>一个“组”中的所有 s 添加一个类,并使用它手动将该组移动超过 10 像素,尽管这看起来真的很hack-ish。

4

0 回答 0