In my data I have values associated with countries. I have created scaled circles for each country and would now like to position them at the centre of each country using cx and cy.
I have generated a map using topoJSON that has country-code 'ids' and I have matching country-codes in my data (cd).
{"type": "Polygon",
"id": 604,
"arcs": [
[133, -473, -448, -378, -374, -413]
]
},
Using D3's path.centroid(feature), how can I find the centroid of each topoJSON path?
g.selectAll("circle")
.data(cd)
.enter()
.append("circle")
.attr("class", "bubble")
.attr("cx", 50)
.attr("cy", 50)
.attr("r", function(d) {
return r(+d.Value)
})
g.selectAll("path")
.data(topojson.object(topology, topology.objects.countries)
.geometries)
.enter()
.append("path")
.attr("d", path)
Full code here Plunker
One way to do it would be like this:
// bind the map data
var paths = g.selectAll("path")
.data(topojson.object(topology, topology.objects.countries)
.geometries)
.enter()
.append("path")
.attr("d", path);
g.selectAll("circle")
.data(cd)
.enter()
.append("circle")
.attr("class", "bubble")
.attr("r", function(d){
return r(+d.Value);
})
// using the map data
// position a circle for matches in cd array
.attr("transform", function(d) {
for (var i = 0; i < paths.data().length; i++){
var p = paths.data()[i];
if (p.id === d["country-code"]){
var t = path.centroid(p);
return "translate(" + t + ")";
}
}
});
Updated plunker
For Comments
In the situation you describe, I always stash the x/y position in my data array:
g.selectAll("circle")
.data(cd)
.enter()
.append("circle")
.attr("class", "bubble")
.attr("r", function(d){
return r(+d.Value);
})
.attr("cx", function(d) {
for (var i = 0; i < paths.data().length; i++){
var p = paths.data()[i];
if (p.id === d["country-code"]){
var t = path.centroid(p);
d.x = t[0];
d.y = t[1];
return d.x;
}
}
})
.attr("cy", function(d){
return d.y;
})
The objects in your cd
array will now have additional properties of x/y pixel positions.
Updated plunker two.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With