4

我有一个包含一组节点的 d3 力导向图:

var node = vis.selectAll("g.node")
              .data(json.nodes)
              .enter().append("svg:g")
              .attr("class", "node")
              .attr("id", function(d) { return "node" + d.index; })
              .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
              .call(force.drag);

这渲染得很好。

div当我显示带有 id的细节时,我现在想将这些节点向右平移(移动)200 像素detail_container

我尝试了以下操作,但显示时节点没有任何反应detail_container(除了显示细节div):

$('#detail_container').fadeIn('slow', function() {
    d3.selectAll("g.node").attr("transform", function(d) { return "translate(200, 0)"; });
});

d3.selectAll("g.node")语句包含节点数据,我可以通过查看控制台中的数据来确认:

console.log(d3.selectAll("g.node"));

作为另一种方法,我将缩放/平移行为附加到我的图表中:

var vis = d3.select("#position")
            .append("svg:svg")
            .attr("width", w)
            .attr("height", h)
            .attr("pointer-events", "all")
            .append("svg:g")
            .call(d3.behavior.zoom().on("zoom", redraw))
            .append("svg:g");

这工作正常。但是,这与鼠标交互,而不是与我的程序中发生的事件交互,所以是否有一种编程方式来调用缩放/平移行为,以便我可以完成我想要的翻译?

4

1 回答 1

7

如果您只想将节点向右移动,则可以通过设置变换来实现;如果您想要交互式平移和缩放,请仅使用缩放行为。

我不清楚为什么当您选择节点并设置变换时什么都没有发生,但我看到的一个问题是,通过直接在节点上设置变换属性,您正在覆盖力布局设置的 x & y 位置. 因此,您可能希望将所有节点放在另一个 G 元素中,以便您可以通过更改容器上的变换而不是单个节点来抵消所有节点。DOM 看起来像这样:

<g class="nodes">
  <g class="node" transform="translate(42,128)">
    <circle r="2.5">
    <text>First Node</text>
  </g>
  <g class="node" transform="translate(64,501)">
    <circle r="2.5">
    <text>Second Node</text>
  </g>
  …
</g>

那么,如果你想将所有节点向右移动 200px,那就是:

d3.select(".nodes").attr("transform", "translate(200,0)");

要恢复班次,请删除容器的变换:

d3.select(".nodes").attr("transform", null);

如果你想要真正的花哨,实现这种效果的另一种方法是改变力布局的重心,然后在显示或隐藏细节 DIV 时重新加热图形。这将导致节点平滑地转移到一个新位置,为细节容器让路。您可以在 Shan Carter 的可视化中看到一个示例,即切割奥巴马 2013 年预算提案的四种方法:单击“支出类型”按钮并观察圆圈的中心位置。或者,请参阅自定义重力这个示例

于 2012-04-11T02:02:33.817 回答