Question

I'm trying to plot a circle on a map using d3 and topojson, but I can't figure it out. Here is my code

var width = 960,
height = 500;

var projection = d3.geo.mercator()
    .center([0, 5 ])
    .scale(900)
    .rotate([-180,0]);

var svg = d3.select("#map").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("class", "svg-map");

var path = d3.geo.path()
    .projection(projection);

var g = svg.append("g");
d3.json("/static/lib/topojson/world-110.json", function(error, topology) {
    svg.append("path")
      .datum(topojson.feature(topology, topology.objects.countries))
      .attr("d", d3.geo.path().projection(d3.geo.mercator()));

    var coordinates = projection([10,20])
    svg.append('svg:circle')
        .attr('cx', coordinates[0])
        .attr('cy', coordinates[1])
        .attr('r', 5);
});
Was it helpful?

Solution

The issue you're seeing (or not seeing) is because you have defined a projection in this line:

var projection = d3.geo.mercator()
    .center([0, 5 ])
    .scale(900)
    .rotate([-180,0]);

Which you use to transform your coordinates. Then, the projections for paths of the topojson data are set with this:

.attr("d", d3.geo.path().projection(d3.geo.mercator()));

So, the topojson renders using a mercator projection with no transforms where as your circle renders using a mercator projection that has been transformed.

I'm not entirely sure how you want you're final map to look, but assuming that it's a world map with a dot in Africa just comment out the centre, scale and rotate lines in the projection definition as in:

var projection = d3.geo.mercator();
    //.center([0, 5 ])
    //.scale(900)
    //.rotate([-180,0]);

And replace the d3.geo.path in the svg.append block with path as in:

.attr("d", d3.geo.path().projection(d3.geo.mercator()));

to

.attr("d", path);

Oh, and if you haven't you'll need to give the circle some fill, so something like

.style("fill", "red")

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top