如何翻译d3.js节点?

时间:2012-04-11 00:47:31

标签: javascript events d3.js geometry force-layout

我有一个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的详细信息detail_container时,我现在想要将这些节点向右移动(移动)200个像素。

我尝试了以下操作,但是当我显示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");

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

1 个答案:

答案 0 :(得分:7)

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

我不清楚为什么在选择节点和设置变换时没有发生任何事情,但我看到的一个问题是通过直接在节点上设置transform属性,你将覆盖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的可视化中看到一个例子,Four Ways to Slice Obama’s 2013 Budget Proposal:点击“消费类型”按钮,观察圈子重新定位。或者,请参阅this example on custom gravity