d3 圆圈在点击缩放时移动位置
d3 circles shifting position on click-to-zoom
我正在尝试使用一堆数据作为圆圈对 d3 图形实现缩放。数据由 1 个大圆圈和绘制在其中的许多小圆圈组成。我想点击较小的圆圈并放大它们。我正在使用 zoomable circle packing demo 的缩放变体。我不想直接使用演示代码,但我已经让它大部分工作了。
最初所有的圆圈都在正确的位置。但是,当我单击较小的圆圈时,它们会在缩放之前移动位置。当我点击白色圆圈向后缩放时,您可以看到它们现在已永久移动。当它缩放时,圆圈不会像在演示中那样放大到视口的中心。
我注意到当我注释掉转换线时
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; });
}
}
看来您在混合定位方法。您设置了初始 cx
和 cy
,但随后您放大了 transform
。重新分解一下以使用 transform
完成所有定位修复它。我还发现您应该启动视图并对 d.cx
和 d.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。
我正在尝试使用一堆数据作为圆圈对 d3 图形实现缩放。数据由 1 个大圆圈和绘制在其中的许多小圆圈组成。我想点击较小的圆圈并放大它们。我正在使用 zoomable circle packing demo 的缩放变体。我不想直接使用演示代码,但我已经让它大部分工作了。
最初所有的圆圈都在正确的位置。但是,当我单击较小的圆圈时,它们会在缩放之前移动位置。当我点击白色圆圈向后缩放时,您可以看到它们现在已永久移动。当它缩放时,圆圈不会像在演示中那样放大到视口的中心。
我注意到当我注释掉转换线时
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; });
}
}
看来您在混合定位方法。您设置了初始 cx
和 cy
,但随后您放大了 transform
。重新分解一下以使用 transform
完成所有定位修复它。我还发现您应该启动视图并对 d.cx
和 d.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。