【问题标题】:Calculate SVG Path Centroid with D3.js使用 D3.js 计算 SVG 路径质心
【发布时间】:2012-08-17 06:04:29
【问题描述】:

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

到目前为止我的(骇人听闻的)尝试:

  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)}
    });
  }

这似乎适用于某些州,例如密苏里州,但其他州(例如华盛顿州)却失败了,因为我的 SVG 数据解析非常初级。 d3 本身是否支持这样的东西?

【问题讨论】:

标签: javascript svg d3.js


【解决方案1】:

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];
}

这实际上比真正的质心稍微好一点,因为它避免了一些投影问题,否则您可能会遇到。

【讨论】:

  • +1 获取详细解决方案并提到您不需要 GeoJSON 来完成此操作
  • +1 信息丰富,关于此处缩放到边界框的优势的额外信息对我正在寻找的解决方案很有价值。
  • 这可能适用于像美国各州这样的方形,但是香蕉形状需要不同的方法。
  • @o-o - 我的意思是,对于缩放到功能的用例,您不需要或不想要真正的质心。此代码并不打算计算真正的质心,而是解决了 OP 的缩放用例。
【解决方案2】:

在我在 Edge 中进行测试之前,接受的答案对我来说非常有用。我无法发表评论,因为我没有足够的业力或其他任何东西,但正在使用此解决方案并发现 Microsoft Edge 存在问题,它不使用 x 或 y,仅使用上/左/下/右等。

所以上面的代码应该是:

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.left + bbox.width/2, bbox.top + bbox.height/2];
}

【讨论】:

    【解决方案3】:

    来自here

    解决方案是对选择使用 .datum() 方法。

    var element = d3.select("#element");
    var centroid = path.centroid(element.datum());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 2021-02-07
      • 2016-02-04
      • 2014-05-02
      • 1970-01-01
      相关资源
      最近更新 更多