【问题标题】:Find centroid of topoJSON path and use it to position a circle in D3查找 topoJSON 路径的质心并使用它在 D3 中定位一个圆
【发布时间】:2016-03-09 11:13:24
【问题描述】:

在我的数据中,我有与国家相关的值。我为每个国家/地区创建了比例圆圈,现在想使用 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

【问题讨论】:

    标签: d3.js topojson


    【解决方案1】:

    一种方法是这样的:

      // 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 工具提示和文本标签)
    【解决方案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获取

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-14
    • 2012-08-17
    • 2015-06-01
    • 2016-02-04
    • 2021-02-07
    • 2020-10-01
    相关资源
    最近更新 更多