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

Gow*_*kar 2 javascript d3.js

我创建了一个d3 geomap. 因为我zooming使用d3.behaviour.zoom().

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

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

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

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

ahm*_*med 5

缩放行为按照您的要求执行。在你的小提琴中:

function zoom() {
          svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        }
Run Code Online (Sandbox Code Playgroud)

请注意,缩放和平移是在整个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()
Run Code Online (Sandbox Code Playgroud)

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

    function zoom() {
      d3.select(this).attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
    }
Run Code Online (Sandbox Code Playgroud)

这是你更新的小提琴

笔记:

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

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

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

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

这是它的小提琴

如果圆圈大小可变:

您可以将“真实半径”存储为一个单独的属性并替换6/d3.event.scaletrueR/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;
        });
    }
Run Code Online (Sandbox Code Playgroud)

更新小提琴