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