在D3中如何只为特定路径启用缩放?

时间:2015-02-27 11:22:47

标签: javascript d3.js

我创建了d3 geomap。我使用zooming启用了d3.behaviour.zoom()功能。

实际上,zooming部分工作正常。但我的问题是我只需要缩放背景图层。

我的意思是我创建了一个world map。在每个国家/地区,我创建了一个circle。因此,在缩放时,我需要增加世界地图大小而不是circle。我需要始终显示相同大小的circle

请帮我解决这个问题。另外,我在下面添加了fiddle链接。好好看看并帮助我。

小提琴链接 - http://jsfiddle.net/sam0kqvx/39/

1 个答案:

答案 0 :(得分:3)

缩放行为会执行您告诉它的操作。在你的小提琴:

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

请注意,缩放和翻译是在整个svg上执行的。您需要定义另一个.countries而不是.dots的变量,并仅在.countries上执行缩放

首先,仅对包含<g>

.countries应用缩放
     var countries = svg.append("g") //apply zoom here.
        .call(d3.behavior.zoom().scaleExtent([1, 8])
        .on("zoom", zoom))
       .selectAll(".countries")
              .data(topojson.feature(world, world.objects.countries).features)
              .enter()

然后,在zoom函数中,仅缩放和翻译所选元素this

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

这是您更新的fiddle

注意:

禁用圆圈的缩放行为也会禁用平移,这意味着用户可以从圆圈下方滑动地图。你也需要处理这个问题。

=============

另一种解决方案是在缩放功能中反转缩放圆圈尺寸,如评论中所述。

    function zoom() {
      svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        svg.selectAll("circle").attr("r", 6/d3.event.scale);
    }

以下是fiddle

如果圆圈尺寸可变:

您可以存储“真实半径”是一个单独的属性,并将6/d3.event.scale替换为trueR/d3.event.scale

以下是您的小提琴中的2个更新。

//Store the original raduis is a "trueR" attributes
svg.selectAll(".dots")
        .data(topojson.feature(world, world.objects.countries).features)
        .enter()
        .append("circle")
      .attr("r",function(d,i){
          radius = Math.random()*20;
          return radius;

      })
      .attr("trueR", function(d){ return d3.select(this).attr("r")})
        .attr("fill","black")
        .attr("transform",function(d){                 
             var p = projection(d3.geo.centroid(d));
             return "translate("+p+")";
         });


//Use "trueR" in the zoom() function
    function zoom() {
      svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        svg.selectAll("circle").attr("r", function(d){
              return (d3.select(this).attr("trueR"))/d3.event.scale;
        });
    }

Update fiddle