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

In D3 how to enable zooming only for particular path?

我创建了一个d3geomap。在那里,我通过使用 d3.behaviour.zoom().

启用了 zooming 功能

实际上,zooming 部分正在工作 fine.But 我的问题是我只需要缩放背景层。

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

请帮我解决这个问题。另外,我添加了fiddle link below.Kindly看看并帮助我。

Fiddle Link - http://jsfiddle.net/sam0kqvx/39/

缩放行为按照您的指示进行。在你的 fiddle:

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

请注意,缩放和平移是在整个 svg 上执行的。您需要定义另一个具有 .countries 而没有 .dots 的变量,并且仅在 .countries

上执行缩放

首先,仅对包含 .countries

<g> 应用缩放
     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

这是您 fiddle 中的 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