user2414849
user2414849

Reputation: 31

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

Upvotes: 3

Views: 1018

Answers (1)

Brant Olsen
Brant Olsen

Reputation: 5664

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.

Upvotes: 1

Related Questions