d3在点击缩放时转移位置

时间:2015-03-03 05:15:01

标签: d3.js 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 + ")"; });

圆圈现在保持在正确的位置。他们的尺寸按照他们应该的规模扩大,但现在他们只是随着他们变大而彼此合并,因为我不再翻译它们。所以问题必须是我的transform属性中的东西,但我无法弄清楚它是什么。或许这可能是我最初的看法?当我取消注释zoomTo(视图)时,圆圈会立即移动到不正确的位置。

如何让他们的职位保持在正确的位置?如何让圆圈缩放到视点的中心?我以为我非常密切地关注了演示代码,但它并没有正常工作。有任何想法吗?

我也希望轴也能放大,但我还没有完成我的问题。

这是我的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; });
}

}

1 个答案:

答案 0 :(得分: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