2015-07-19 108 views
1

我现在的更新的解决方案......D3如何以启用平移/缩放的元素为中心?

var myZoom = d3.behavior.zoom() 
       .scaleExtent([.3, 10]) 
       .on("zoom", zoom); 

var container = d3.select("body").append("svg") 
    .attr("width", 500) 
    .attr("height", 500) 
    .style('border', '1px solid black') 
    .call(myZoom); 

var trans1 = 250; 
function sneakyTranslate1() { 
    if(trans1 <= 0) return 0; 
    trans1 = trans1 - .5; 
    return trans1; 
} 
var trans2 = 250; 
function sneakyTranslate2() { 
    if(trans2 <= 0) return 0; 
    trans2 = trans2 - .5; 
    return trans2; 
} 
//I am centering my node here, but if I pan the node it jumps 
var svg = container.append("g").attr("transform", "translate(250,250)"); 

function zoom() { svg.attr("transform", "translate(" + 
    (d3.event.translate[0]+sneakyTranslate1()) + "," + 
    (d3.event.translate[1]+sneakyTranslate2()) + ")scale(" + d3.event.scale + 
    ")"); } 

为了澄清我想开始我的居中单个节点然后让平移和缩放为默认的工作。用户可以在添加更多节点时担心居中和平移。

我目前的解决方案是将我的组翻译成我的节点所在的组。在缩放功能中将该转换的偏移量添加到缩放矢量中,并缓慢减小偏移值并将其恢复为0.

如果有人知道更好的方式来执行此操作或重新设置缩放和x,画这将是有益的。

链接JsFiddle

回答

1

我现在明白你的问题了。我更新了你的jsFiddle here

问题是,即使您翻译的SVG container,你没有翻译变焦(有点奇怪,我知道)。本质上,zoom函数认为你试图放大SVG容器原来的位置(0,0),但因为你将容器移动到其他位置(250,250),所以必须移动myZoom对象,以便它知道从哪里放大。

所以,如果你看到我添加了这个

//I am centering my node here, but if I pan the node it jump 
var svg = container.append("g").attr("transform", "translate(250,250)"); 

// translate zoom function so it knows where to zoom from 
myZoom.translate([250,250]); 

所以它知道翻译的变焦对象的同一位置容器。我也回复了这个。

function zoom() { 
    svg.attr("transform", 
    "translate(" + d3.event.translate + ")" 
    + " scale(" + d3.event.scale + ")"); 
} 

希望这可以解决您的问题。

+0

是否有可能保留泛能力,因为随着树的生长,这一点非常重要? –

+0

我已经找到了解决方案,它是“translate(”+(d3.event.translate [0] +500)+“,”+(d3.event.translate [1] +400)+“)scale(” + d3.event.scale +“)”);如果您更新解决方案,我接受,但您当前的解决方案禁用所有平移。谢谢你的帮助。我也用工作更新了我的小提琴。 –

+0

我相信我太激动了,跳起了枪。这只是一个部分解决方案。我可以创建一个函数,在用户平移缩放时缓慢地将偏移量更改回0,但这看起来像是黑客而不是解决方案。 –