javascript 如何翻译 d3.js 节点?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10098450/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 08:42:03  来源:igfitidea点击:

How do I translate d3.js nodes?

javascripteventsd3.jsgeometryforce-layout

提问by Alex Reynolds

I have a d3 force-directed graph that contains a group of nodes:

我有一个包含一组节点的 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);

This renders fine.

这很好。

I'd now like to translate (move) these nodes 200 pixels to the right when I show a detail divwith the id detail_container.

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

I tried the following, but nothing happens to the nodes when I show detail_container(other than showing the detail div):

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

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

The d3.selectAll("g.node")statement contains the node data, which I can confirm by looking at the data in the console:

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

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

As another approach, I attached the zoom/pan behavior to my graph:

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

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");

This works fine. However, this interacts with the mouse, not with events that occur in my program, so is there a programmaticway to call the zoom/pan behavior, so that I can accomplish the translation I want?

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

回答by mbostock

If you just want to move the nodes to the right, then you can accomplish that by setting a transform; only use the zoom behavior if you want interactive panning and zooming.

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

It's not clear to me why nothing is happening when you select the nodes and set a transform, but one problem I see is that by setting the transform attribute on the nodes directly, you're overwriting the x & y position set by the force layout. So, you probably want to put all of the nodes inside another G element, so that you can offset all of them by changing the transform on the container rather than the individual nodes. The DOM would look like this:

我不清楚为什么当您选择节点并设置变换时什么也没有发生,但我看到的一个问题是,通过直接在节点上设置变换属性,您会覆盖由力布局设置的 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>

So then, if you want to shift all the nodes to the right by 200px, it's just:

那么,如果您想将所有节点向右移动 200px,只需:

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

And to revert the shift, remove the container's transform:

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

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

If you wanted to be reallyfancy, another way of achieving this effect would be to change the center of gravity of the force layout, and then reheat the graph when you show or hide the details DIV. This will cause the nodes to smoothly shift into a new position to make way for the details container. You can see an example of this in Shan Carter's visualization, Four Ways to Slice Obama's 2013 Budget Proposal: click the "Types of Spending" button and watch the circles recenter. Or, see this example on custom gravity.

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