Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

D3 adding element to zoomed map

I have a map where circles (origin of people) appear when clicking on a legend.

Additionally, it is possible to zoom in, and then, circles (and country path) are transformed (using d3.behavior.zoom).

Though, if I first zoom in, and then click on the legend, circles do not appear at the right places. How can I solve this problem and append them at the right coordinates (within the zoomed map).

Any ideas? I'm sure the solution is not that difficult, but I'm stucked.

See (http://wahrendorf.de/circlemapping/world_question.html) for an example.

Thanks,

Morten

like image 914
user2414849 Avatar asked Jun 25 '26 17:06

user2414849


1 Answers

You need to take into account d3.event.translate and d3.event.scale when you draw the circles. The easiest way to do this is to factor out your zoom function so that it may be called by the circle drawing function.

var translate = [0,0];
var scale = 1;
var zoom_function = function() {
    canvas.selectAll("path")
             .attr("transform","translate("+translate.join(",")+")scale("+scale+")");

    canvas.selectAll("circle.origin")
             .attr("transform","translate("+translate.join(",")+")scale("+scale+")")
             .attr("r", function(d) { return radius/scale; });
};
var zoom = d3.behavior.zoom().scaleExtent([1,6])
           .on("zoom",function() {
              translate = d3.event.translate;
              scale = d3.event.scale;
              zoom_function();
});

// ... The rest of the code ...

canvas.append("text")
      .text("show circles")
      .attr("x", 30 ) .attr("y", 480 )
      .attr("dy", ".35em")
      .on("click", function(d)  {
          /// load data with long/lat of circles
          d3.csv("./World_files/places_q.csv", function(error, origin) {
              canvas.selectAll("circle.origin").remove();
              canvas.selectAll("circle.origin")
            .data(origin)
                    .enter()
                    .append("circle")
                    .attr("cx", function(d) {return projection([d.originlong, d.originlat])[0];})
                    .attr("cy", function(d) {return projection([d.originlong, d.originlat])[1];})
                    .attr("r", 2)
                    .style("fill", "red")
                    .style("opacity", 0.5)
                    .attr("class", "origin");
              // Call the zoom function here to fix the placement of the circles.
              zoom_function();
          });
    });

You will need to track the last known d3.event.translate and d3.event.scale values since they will be undefined when you are drawing the circles.

like image 103
Brant Olsen Avatar answered Jun 27 '26 07:06

Brant Olsen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!