我在项目中使用位于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)}
});
}
这似乎适用于密苏里州等一些州,但像华盛顿这样的其他州也失败了,因为我的SVG数据解析非常简陋。 d3本身是否支持这样的东西?
答案 0 :(得分:54)
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 :(得分:0)
来自here
解决方案是在选择项上使用.datum()方法。
var element = d3.select("#element");
var centroid = path.centroid(element.datum());