找到 topoJSON 路径的质心并用它在 D3 中定位一个圆
Find centroid of topoJSON path and use it to position a circle in D3
在我的数据中,我有与国家相关的值。我为每个国家/地区创建了缩放圆圈,现在想使用 cx 和 cy 将它们定位在每个国家/地区的中心。
我使用具有国家代码 'ids' 的 topoJSON 生成了地图,并且我的数据 (cd) 中有匹配的国家代码。
{"type": "Polygon",
"id": 604,
"arcs": [
[133, -473, -448, -378, -374, -413]
]
},
使用 D3 的 path.centroid(feature),如何找到每个 topoJSON 路径的质心?
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)
完整代码在这里Plunker
我会计算 TopoJSON 特征的 GeoJSON 等价物,并使用 d3.geo.centroid
计算每个特征的地理中心。摘自我前段时间写的一个例子(把每个国家画成一个正方形,面积成比例,以每个国家的质心为中心):
var geojson = topojson.feature(data, data.objects.countries).features;
// Compute the projected centroid, area and length of the side
// of the squares.
geojson.forEach(function(d) {
d.centroid = projection(d3.geo.centroid(d));
// more calculations...
});
一种方法是这样的:
// 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 + ")";
}
}
});
已更新plunker
征求意见
在您描述的情况下,我总是将 x/y 位置存储在我的数据数组中:
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;
})
cd
数组中的对象现在将具有 x/y 像素位置的附加属性。
已更新 plunker two。
在我的数据中,我有与国家相关的值。我为每个国家/地区创建了缩放圆圈,现在想使用 cx 和 cy 将它们定位在每个国家/地区的中心。
我使用具有国家代码 'ids' 的 topoJSON 生成了地图,并且我的数据 (cd) 中有匹配的国家代码。
{"type": "Polygon",
"id": 604,
"arcs": [
[133, -473, -448, -378, -374, -413]
]
},
使用 D3 的 path.centroid(feature),如何找到每个 topoJSON 路径的质心?
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)
完整代码在这里Plunker
我会计算 TopoJSON 特征的 GeoJSON 等价物,并使用 d3.geo.centroid
计算每个特征的地理中心。摘自我前段时间写的一个例子(把每个国家画成一个正方形,面积成比例,以每个国家的质心为中心):
var geojson = topojson.feature(data, data.objects.countries).features;
// Compute the projected centroid, area and length of the side
// of the squares.
geojson.forEach(function(d) {
d.centroid = projection(d3.geo.centroid(d));
// more calculations...
});
一种方法是这样的:
// 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 + ")";
}
}
});
已更新plunker
征求意见
在您描述的情况下,我总是将 x/y 位置存储在我的数据数组中:
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;
})
cd
数组中的对象现在将具有 x/y 像素位置的附加属性。
已更新 plunker two。