有没有办法放大D3力布局图?

Leg*_*end 80 javascript jquery zoom d3.js force-layout

D3 在此处具有力导向布局.有没有办法将缩放添加到此图表?目前,我能够捕获鼠标滚轮事件,但我不确定如何编写重绘功能本身.有什么建议?

    var vis = d3.select("#graph")
        .append("svg:svg")
        .call(d3.behavior.zoom().on("zoom", redraw)) // <-- redraw function
        .attr("width", w)
        .attr("height", h);
Run Code Online (Sandbox Code Playgroud)

nra*_*itz 97

2014年4月4日更新

另请参阅Mike Bostock关于D3 v.3和相关示例中的更改的答案.我想这可能取代下面的答案.

2014年2月18日更新

我想如果你想让整个SVG平移和缩放,@ ahaarnos的答案更可取.g如果你在同一个SVG中有非缩放元素,那么下面我的答案中的嵌套元素实际上是必需的(原始问题中不是这种情况).如果确实将行为应用于g元素,则需要背景rect或类似元素来确保g接收指针事件.

原始答案

我根据zoom-pan-transform示例进行了这项工作- 你可以在这里看到我的jsFiddle:http://jsfiddle.net/nrabinowitz/QMKm3/

它比我希望的要复杂一点 - 你必须嵌套几个g元素才能使它工作,将SVG的pointer-events属性设置为all,然后附加一个背景矩形来接收指针事件(否则它只在指针结束时有效)节点或链接).该redraw功能较为简单,只需设置在最里面的一个变换g:

var vis = d3.select("#chart")
  .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');

vis.append('svg:rect')
    .attr('width', w)
    .attr('height', h)
    .attr('fill', 'white');

function redraw() {
  console.log("here", d3.event.translate, d3.event.scale);
  vis.attr("transform",
      "translate(" + d3.event.translate + ")"
      + " scale(" + d3.event.scale + ")");
}
Run Code Online (Sandbox Code Playgroud)

这有效地缩放了整个SVG,因此它也可以缩放笔画宽度,例如放大图像.

还有另一个例子说明了一种类似的技术.

  • +1美丽的方法.非常感谢您的宝贵时间. (4认同)
  • @EricStob - 这可能是一个新问题.但请参阅http://jsfiddle.net/56RDx/2/ - 这只是通过缩放比例的倒数重新调整字体大小. (2认同)

aaa*_*nic 18

嵌套<g>的原因是什么?

下面的代码对我来说效果很好(只有一个<g>,没有随机的大白<rect>:

var svg = d3.select("body")
    .append("svg")
      .attr({
        "width": "100%",
        "height": "100%"
      })
      .attr("viewBox", "0 0 " + width + " " + height )
      .attr("preserveAspectRatio", "xMidYMid meet")
      .attr("pointer-events", "all")
    .call(d3.behavior.zoom().on("zoom", redraw));

var vis = svg
    .append('svg:g');

function redraw() {
  vis.attr("transform",
      "translate(" + d3.event.translate + ")"
      + " scale(" + d3.event.scale + ")");
}
Run Code Online (Sandbox Code Playgroud)

然后将svg中的所有元素附加到vis元素中.


Dav*_*arx 14

提供的答案适用于D3 v2但不适用于v3.我已经将响应合成为一个干净的解决方案,并使用此处提供的答案解决了v3问题:为什么d3.js v3在实现缩放时打破了我的力图,而v2没有?

首先是主要代码.这是@ahaarnos回答的清理版本:

    var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height)
            .call(d3.behavior.zoom().on("zoom", redraw))
        .append('g');

    function redraw() {
      svg.attr("transform",
          "translate(" + d3.event.translate + ")"
          + " scale(" + d3.event.scale + ")");
    }   
Run Code Online (Sandbox Code Playgroud)

现在你有平移和缩放,但是你将无法拖动节点,因为平移功能将覆盖拖动功能.所以我们需要这样做:

var drag = force.stop().drag()
.on("dragstart", function(d) {
    d3.event.sourceEvent.stopPropagation(); // to prevent pan functionality from 
                                            //overriding node drag functionality.
    // put any other 'dragstart' actions here
});
Run Code Online (Sandbox Code Playgroud)

这里的@nrabinowitz'小提琴被修改为使用这个更清晰的缩放实现,但说明了D3v3如何打破节点拖拽:http://jsfiddle.net/QMKm3/718/

以下是与D3v3一起修改的相同小提琴:http://jsfiddle.net/QMKm3/719/