Hug*_*lpz 5 node.js jsdom d3.js
以下代码适用于Chromium:
var node = window.d3.selectAll('#L1 > *:nth-child(2)');
var bbox = node.node().getBBox();
console.log(bbox) // {height: 44, width: 44, y: -13, x: 144}
Run Code Online (Sandbox Code Playgroud)
但不适用于nodejs + jsdom:
"TypeError: Object [ PATH ] has no method 'getBBox' "
Run Code Online (Sandbox Code Playgroud)
M. Bostock指出JSDOM 不支持 getBBox()
用什么D3js替代品来获得的边界框#L1 > *:nth-child(2)?
过去的努力使我到了这里:getBBox()基于小提琴

直接挖掘元素的路径数据d="..."应该可以。svg 线基本上是一组x,y点。假设绝对坐标没有平移,也没有大贝塞尔曲线x,这是我的 D3js 生成的 svg 线的情况,我在这些数据中找到了和 的最小值和最大值y。
为此,我获取d="..."svg 行或多行代码。为了简单起见,我粗鲁地删除了可能的相对跳转,例如h30因为v20我在 D3js 输出中从未看到过任何跳转,然后清除字母(又名svg commands:M、L、H、V、C、S、Q、T、A、Z),简化空格和换行,然后除以剩余空格。我得到了一个干净的坐标数组。
需要注意的是,我的选择器直接定位单个非翻译路径。
var getBBox = function(selector){
var xmin, xmax, ymin, ymax,p;
// clean up path
var t = d3.select(selector).attr("d"); // get svg line's code
console.log(t)
t = t.replace(/[a-z].*/g," ") // remove relative coords, could rather tag it for later processing to absolute!
.replace(/[\sA-Z]+/gi," ").trim().split(" "); // remove letters and simplify spaces.
console.log(t)
for(var i in t){ // set valid initial values
if(t[i].length>1){
p = t[i].split(",");
xmin = xmax = p[0]; ymin = ymax = p[1]; }
}
for(var i in t){ // update xmin,xmax,ymin,ymax
p = t[i].split(",");
if(!p[1]){ p[0]=xmin; p[1] = ymin;} // ignore relative jumps such h20 v-10
xmin = Math.min(xmin, p[0]);
xmax = Math.max(xmax, p[0]);
ymin = Math.min(ymin, p[1]);
ymax = Math.max(ymax, p[1]);
} return [[xmin,ymax],[xmax,ymin]]; // [[left, bottom], [right, top]] as for https://github.com/mbostock/d3/wiki/Geo-Paths#bounds
}
var bb = getBBox("path");
Run Code Online (Sandbox Code Playgroud)
对于多个路径的组,您可能需要遍历 svg DOM 以循环该组的每个单个路径,以便更新 xmin、ymin、xmax、ymax。
要处理翻译的元素,请进一步调整。
可能存在其他更好的方法。请记住检查getBBox()和getBoundingClientRect()在您的上下文中是否可用,因为它们是原生的并且非常方便。
| 归档时间: |
|
| 查看次数: |
1340 次 |
| 最近记录: |