2015-03-03 81 views
1

我试图用一堆数据作为圆形在d3图形上实现缩放。数据由1个大圆圈和许多小圆圈组成。我想点击较小的圆圈并放大。我正在使用来自zoomable circle packing demo的变焦变体。我不想直接使用演示代码,但我主要工作。d3圆形点击变焦位置

最初所有的圈子都处于正确的位置。然而,当我点击较小的圈子时,他们在缩放之前移位。当我点击白色圆圈放大时,可以看到它们现在已经永久移位了。当它缩放时,圆圈不会像放在演示中那样放大视口的中心。

我注意到,当我注释掉变换线

node.attr("transform", function(d) { return "translate(" + (xscale(d.cx) - v[0]) * k + "," + (yscale(d.cy) - v[1]) * k + ")"; }); 

的圆圈,现在保持在正确的位置。它们的尺寸应该尽可能大,但是现在它们只是在它们变大时才合并成另一个,因为我不再翻译它们。所以这个问题必须是我的转换属性,但我无法弄清楚它是什么。或者,也许这是我最初的看法?当我取消注释zoomTo(view)时,圆圈会立即移动到不正确的位置。

我如何获得他们的职位留在正确的位置?我如何让圆圈缩放到视点的中心?我以为我非常密切地关注了这个演示代码,但它并不是很正确。有任何想法吗?

我也想让轴放大,但我还没有得到那么深入我的问题。

这是我的jsfiddle

而且我充分的javascript代码

function loadPlateDesign(){ 
var width = 400; 
var height = 400; 
var padding = 55; 
var plateid = 7443; 
var plateCen = {'ra': 230.99167, 'dec': 42.68736 }; 

var data = [{'name':7443,'color': 'white', 'cx': 0.0, 'cy': 0.0, 'r': 200}, 
    {'color': 'red', 'cx': 8.23066, 'cy': -134.645, 'ra':231.1,'dec':42.1,'name': '1901', 'r': 10.0, 
    'children':[{'color': 'red', 'cx': 8.23066, 'cy': -134.645, 'ra':231.1,'dec':42.1,'name': 'a', 'r': 2.0}]}, 
    {'color': 'blue', 'cx': -167.524, 'cy': -90.009, 'name': '711', 'r': 5.0}]; 

var xscale = d3.scale.linear().domain([330.,-330.]).range([0,400]); 
var yscale = d3.scale.linear().domain([330.,-330.]).range([0,400]); 

// initial focus and view 
var focus = {'name':7443,'color': 'white', 'cx': 0.0, 'cy': 0.0, 'r': 200}; 
var view = [xscale(0.0),yscale(0.0),200*2]; 

// make the main svg element  
var svg = d3.select('#platedesign').append('svg') 
    .attr('width',width+padding) 
    .attr('height',height+padding); 

// add the plate and ifu data 
var ifus=svg.selectAll('circle').data(data).enter().append('circle') 
    .attr('id',function(d){return d.name;}) 
    .attr('cx',function(d,i){return xscale(d.cx);}) 
    .attr('cy',function(d,i){return yscale(d.cy);}) 
    .attr('r',function(d,i){return d.r;}) 
    .style('fill',function(d,i){return d.color;}) 
    .style('stroke','black') 
    .on('click',function(d){ 
     if (focus != d) zoom(d), d3.event.stopPropagation(); 
    }); 

// add the axes 
var rascale = d3.scale.linear().domain([plateCen.ra+1.5,plateCen.ra-1.5]).range([0,400]); 
var decscale = d3.scale.linear().domain([plateCen.dec+1.5,plateCen.dec-1.5]).range([0,400]); 
xaxis = d3.svg.axis().scale(rascale).orient('bottom'); 
yaxis = d3.svg.axis().scale(decscale).orient('right').ticks(5); 
svg.append('g').attr('class','x axis') 
    .attr('transform','translate(0,'+(height+5)+')') 
    .call(xaxis) 
    .append('text') 
    .attr('x',width/2) 
    .attr('y',35) 
    .style('text-anchor','middle') 
    .text('RA'); 

svg.append('g').attr('class','y axis') 
    .attr('transform','translate('+(width+5)+',0)') 
    .call(yaxis) 
    .append('text') 
    .attr('transform','rotate(90)') 
    .attr('x',height/2) 
    .attr('y',-35) 
    .style('text-anchor','middle') 
    .text('Dec'); 

var node = svg.selectAll("circle"); 
//zoomTo(view); 

function zoom(d){ 
    console.log('zooming to', d.name); 
    var focus0 = focus; focus=d; 
    var newview = [xscale(d.cx), yscale(d.cy), d.r*2+20]; 

    var transition = d3.transition() 
     .duration(d3.event.altKey ? 7500 : 750) 
     .tween('zoom', function(d){ 
      var i = d3.interpolateZoom(view, newview); 
      return function(t) {zoomTo(i(t)); }; 
     }); 

} 

function zoomTo(v) { 
    var k = height/v[2]; view = v; 
    console.log(height, v); 
    node.attr("transform", function(d) { return "translate(" + (xscale(d.cx) - v[0]) * k + "," + (yscale(d.cy) - v[1]) * k + ")"; }); 
    ifus.attr("r", function(d) { return d.r * k; }); 
} 

}

回答

0

看起来你混合定位方法。你设置了一个初始的cxcy,但是你放大一个transform。用transform进行重新分解以完成所有定位,修复了它。我还发现你应该启动视图并在d.cxd.cy而不是xscale(d.cx)上进行缩放计算。

function zoom(d){ 
    console.log('zooming to', d.name); 
    var focus0 = focus; focus=d; 
    var newview = [d.cx, d.cy, d.r*2+20];  
    var transition = d3.transition() 
     .duration(d3.event.altKey ? 7500 : 750) 
     .tween('zoom', function(d){ 
      var i = d3.interpolateZoom(view, newview); 
      return function(t) {zoomTo(i(t)); }; 
     });  
} 

function zoomTo(v) { 
    var k = height/v[2]; view = v; 
    console.log(height, v); 
    node.attr("transform", function(d) { return "translate(" + xscale((d.cx - v[0]) * k) + "," + yscale((d.cy - v[1]) * k) + ")"; }); 
    ifus.attr("r", function(d) { return d.r * k; }); 
} 

更新fiddle

+0

太好了。它几乎可以工作。当它第一次运行时,当您单击缩放时,整个元素会在放大较小的圆之前左右移动。然而,在此之后,过渡在大圈和小圈之间来回平滑。这是因为当你将newview坐标改回原生坐标时,原始视图坐标也必须改变,看起来你忘了这么做。将视图更改为[0,0,200 * 2]可解决问题。非常感谢! – havok2063 2015-03-03 16:09:27

+0

@ havok2063,很好,很抱歉。 – Mark 2015-03-03 16:26:03