简体   繁体   English

D3选择性变焦

[英]D3 selective Zoom

I am working on a force directed graph layout with some added features: selectable links/nodes, tooltips, fisheye effect, and -- important for my question -- zoom and pan. 我正在研究具有某些附加功能的力导向图布局:可选链接/节点,工具提示,鱼眼效果,以及-对于我的问题很重要-缩放和平移。

Now, the zooming works very well like this: 现在,缩放效果非常好,如下所示:

d3 ... .append('svg:g').call(d3.behavior.zoom().on("zoom", redraw))... 

Where the redraw function looks like this... 重绘功能看起来像这样...

function redraw() {
  trans = d3.event.translate;
  scale = d3.event.scale;
  vis.attr("transform", "translate(" + trans + ")" + " scale(" + scale + ")");
}

However, this method zooms the entire SVG graphic, including font sizes, graph edges, the line stroke-widths surrounding the nodes, etc. 但是,此方法将缩放整个SVG图形,包括字体大小,图形边缘,节点周围的线笔划宽度等。

Is it somehow possible not to zoom certain elements? 是否可以缩放某些元素? The only solution I have seen so far is to put a line like this (took it from here http://jsfiddle.net/56RDx/2/ ) 到目前为止,我所看到的唯一解决方案是放置一条这样的行(从此处获取它: http://jsfiddle.net/56RDx/2/

node.attr("font-size", (nodeFontSize / d3.event.scale) + "px");

in the redraw method, to basically invert the zooming on certain elements on the fly. 在重绘方法中,基本上可以即时反转某些元素的缩放比例。 My problem is however (apart from this being an ugly hack), that my edge-widths are dynamically generated on graph-drawing (according to some graph properties...), so this 'invertion' method does not work... 但是,我的问题是(除了这是一个丑陋的hack),我的边宽是在图形绘制时动态生成的(根据某些图形属性...),因此这种“反转”方法不起作用...

  1. you can add a class to the element you want to trigger the zoom on: 您可以向要触发缩放的元素添加一个类:

     d3 ... .append('svg:g').classed("some_classname", true).call(d3.behavior.zoom().on("zoom", redraw))... 

    then do: 然后做:

     function redraw() { trans = d3.event.translate; scale = d3.event.scale; vis.selectAll("some_classname").attr("transform", "translate(" + trans + ")" + " scale(" + scale + ")"); } 

  2. or you can add a class to all elements you don't want to trigger the zoom on then use the CSS3 :not pseudo-class: 或者,您可以为不想触发缩放的所有元素添加一个类,然后使用CSS3:not伪类:

     function redraw() { trans = d3.event.translate; scale = d3.event.scale; vis.selectAll("*:not(.some_classname)").attr("transform", "translate(" + trans + ")" + " scale(" + scale + ")"); } 

The only solution I could find is an "ugly hack", if (I assume you are) you're trying to not zoom lines for example, the you should try the below, it works for both zooming in and out: 我能找到的唯一解决方案是“丑陋的破解”,例如,如果(我假设您是)尝试不缩放线条,则应尝试以下操作,它既可以放大也可以缩小:

Demo: http://jsfiddle.net/SO_AMK/gJMTb/ 演示: http//jsfiddle.net/SO_AMK/gJMTb/

JavaScript: JavaScript:

function redraw() {
  vis.attr("transform", "translate(" + d3.event.translate + ")" + " scale(" + d3.event.scale + ")");
  vis.attr("font-size", (nodeFontSize / d3.event.scale) + "px");
  vis.selectAll("line.link").style("stroke-width", getStrokeWidth); // Function so it runs for each element individually
}

function getStrokeWidth(){
    if (!this.__data__.stroke) { // Doesn't exist, so set it to the original stroke-width
        this.__data__.stroke = parseFloat(d3.select(this).style("stroke-width"));
        // I found __data__ to be easier than d3's .data()
    }
    return this.__data__.stroke / d3.event.scale + "px";
}

Please see the documentation for details on using a function with style() 请参阅文档以获取有关将函数与style()一起使用的详细信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM