Swaroop
Swaroop

Reputation: 541

Stop zooming of bubbles in D3 World Map

I am currently working on a D3 world map in which I have brought in a zoom functionality up-to the boundary level of any country or county based on its click.

I have Added Bubbles pointing the counties in Kenya,which gets enlarged on the zoom functionality that I have added.But I want to stop the zooming of bubbles,on zooming of the Map.

Here is a plunker for my current work.

https://plnkr.co/edit/nZIlJxvU74k8Nmtpduzc?p=preview

And below is the code for zooming and zoom out

function clicked(d) {

   var conditionalChange = d;
   if(d.properties.hasOwnProperty("Country")){

       var country = d.properties.Country;
       var obj = data.objects.countries.geometries;
         $.each(obj, function(key, value ) {
            if(countries[key].properties.name == "Kenya")
                {
            conditionalChange = countries[key].geometry;
                        }
            });
   }
  d = conditionalChange;
  if (active.node() === this) return reset();
  active.classed("active", false);
  active = d3.select(this).classed("active", true);

  var bounds = path.bounds(d),
      dx = bounds[1][0] - bounds[0][0],
      dy = bounds[1][1] - bounds[0][1],
      x = (bounds[0][0] + bounds[1][0]) / 2,
      y = (bounds[0][1] + bounds[1][1]) / 2,
      scale = 1.2/ Math.max(dx / width, dy / height),
      translate = [width / 2 - scale * x, height / 2 - scale * y];

  g.transition()
      .duration(750)
      .style("stroke-width", 1/ scale + "px")
      .attr("transform", "translate(" + translate + ")scale(" + scale + ")");
}

function reset() {
  active.classed("active", false);
  active = d3.select(null);

  g.transition()
      .duration(750)
      .style("stroke-width", "1px")
      .attr("transform", "");
}

Upvotes: 2

Views: 347

Answers (1)

Andrew Reid
Andrew Reid

Reputation: 38151

You are scaling the entire g element, this effectively zooms the map. Everything will increase in size; however, for the map lines you have adjusted the stroke to reflect the change in g scale factor:

 g.transition()
      .duration(750)
      .style("stroke-width", 1/ scale + "px")
      .attr("transform", "translate(" + translate + ")scale(" + scale + ")");

To keep the circles the same size, you have to do the same adjustment for your circles by modifying the r attribute for each circle according to the g scale factor:

   g.selectAll(".city-circle")
     .transition()
     .attr("r", 5 / scale )
     .duration(750);

Though, since you don't actually apply the class city-circle on your circles you'll need to do that too when you append them:

.attr("class","city-circle")

And, just as you reset the stroke width on reset, you need to reset the circles' r :

  g.selectAll(".city-circle")
     .transition()
     .attr("r", 5)
     .duration(750);

Together that gives us this.

Upvotes: 3

Related Questions