用D3.js计算SVG路径质心

Zik*_*kes 21 javascript svg d3.js

我在项目中使用位于http://upload.wikimedia.org/wikipedia/commons/3/32/Blank_US_Map.svg的SVG 并与d3.js进行交互.我想创建一个单击缩放效果,如http://bl.ocks.org/2206590,但是该示例依赖于存储在JSON对象中的路径数据来计算质心.有没有办法从现有的SVG加载d3中的路径数据来获得质心?

到目前为止我的(hackish)尝试:

  function get_centroid(sel){
    var coords = d3.select(sel).attr('d');
    coords = coords.replace(/ *[LC] */g,'],[').replace(/ *M */g,'[[[').replace(/ *z */g,']]]').replace(/ /g,'],[');
    return d3.geo.path().centroid({
      "type":"Feature",
      "geometry":{"type":"Polygon","coordinates":JSON.parse(coords)}
    });
  }
Run Code Online (Sandbox Code Playgroud)

这似乎适用于一些州,如密苏里州,但像华盛顿这样的其他州失败了,因为我的SVG数据解析是如此简陋.d3本机支持这样的东西吗?

nra*_*itz 57

D3函数似乎都假设您从GeoJSON开始.但是,我实际上并不认为你需要质心 - 你真正需要的是边界框,幸运的是这可以直接从SVG DOM界面获得:

function getBoundingBoxCenter (selection) {
  // get the DOM element from a D3 selection
  // you could also use "this" inside .each()
  var element = selection.node();
  // use the native SVG interface to get the bounding box
  var bbox = element.getBBox();
  // return the center of the bounding box
  return [bbox.x + bbox.width/2, bbox.y + bbox.height/2];
}
Run Code Online (Sandbox Code Playgroud)

实际上,为了缩放,这实际上比真正的质心略好,因为它避免了您可能遇到的一些投影问题.

  • 这可能适用于美国各州等方形,但香蕉形状需要不同的方法。 (2认同)