寻找TopoJSON路径的质心并将其用于在D3中定位圆形

5

我的数据中有与国家相关联的数值。我已经为每个国家创建了缩放圆,并希望使用cx和cy将它们定位在每个国家的中心。

我使用topoJSON生成了一张地图,其中包含国家代码“ids”,而我的数据(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

2个回答

6
一种实现方法如下所示:
  // 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定位来实现这个?(我想使用这些尺寸来定位我的div工具提示和文本标签) - user3821345

2
我会计算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...
});

完整的示例可以在http://bl.ocks.org/pnavarrc/14ed098d4072be2715db找到。

感谢提供的示例!不过我仍然在将其转换为GeoJSON时遇到了困难https://plnkr.co/edit/f5Ps9afPdqdSCk3zUoiv?p=info,出现了“feature isn't a function”的错误。我是不是引用了错误的对象?https://github.com/mbostock/topojson/wiki/API-Reference - user3821345

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接