如何确定 D3 树节点是否落在 SVG 容器之外
How to determine if D3 tree node falls outside SVG container
我正在使用 D3 树布局的这个实现:
http://bl.ocks.org/robschmuecker/7880033
我已经让我的树响应外部事件,为此,我想知道某个节点当前是否不可见(在 svg 容器之外),以便我可以重新居中它。
经过一些研究,我发现了这个 SO 答案,它看起来正是我需要的:
Getting Screen Positions of D3 Nodes After Transform
当拖动左上角的节点并点击它时,我希望坐标为[0,0]。
但由于某种原因,x 坐标总是有相当大的偏移量是错误的。
在这里做了一个fiddle:
https://jsfiddle.net/syberyan/yd8L4v0q/
我修改了 click() 函数,让它打印目标节点的坐标。
function getElementCoords(element, coords) {
var ctm = element.getCTM(),
x = ctm.e + coords.x*ctm.a + coords.y*ctm.c,
y = ctm.f + coords.x*ctm.b + coords.y*ctm.d;
return {x: x, y: y};
};
function click(d) {
if (d3.event.defaultPrevented) return; // click suppressed
d3.selectAll('.node').each(function (node, i) {
if (d === node) {
let coords = getElementCoords(this, node);
console.log(coords.x, coords.y); // shows coords relative to my svg container
}
});
}
我是 D3 新手所以我可能做错了什么,但是什么?或者也许有更好的方法?
我没有仔细查看链接的问题或您当前的计算。相反,我认为计算可以简化为:
function getElementCoords(element) {
// translate on node
var trans = d3.transform(d3.select(element).attr('transform')).translate,
// transform on parent "zoom" container
transFormParent = d3.transform(d3.select(element.parentNode).attr('transform')),
// translate on zoom container
transParent = transFormParent.translate,
// scale on zoom container
scaleParent = transFormParent.scale,
// final position of node
pos = {
x: trans[0] + transParent[0]/scaleParent[0],
y: trans[1] + transParent[1]/scaleParent[1]
};
return pos;
}
称其为:
function click(d) {
console.log(getElementCoords(this));
}
已更新 fiddle。
编辑
@Christian 在评论中指出,我的数学不对,应该是:
function getElementCoords(element) {
// translate on node
var trans = d3.transform(d3.select(element).attr('transform')).translate,
// transform on parent "zoom" container
transFormParent = d3.transform(d3.select(element.parentNode).attr('transform')),
// translate on zoom container
transParent = transFormParent.translate,
// scale on zoom container
scaleParent = transFormParent.scale,
// final position of node
pos = {
x: trans[0] * scaleParent[0] + transParent[0],
y: trans[1] * scaleParent[1] + transParent[1]
};
return pos;
}
我正在使用 D3 树布局的这个实现:
http://bl.ocks.org/robschmuecker/7880033
我已经让我的树响应外部事件,为此,我想知道某个节点当前是否不可见(在 svg 容器之外),以便我可以重新居中它。
经过一些研究,我发现了这个 SO 答案,它看起来正是我需要的:
Getting Screen Positions of D3 Nodes After Transform
当拖动左上角的节点并点击它时,我希望坐标为[0,0]。 但由于某种原因,x 坐标总是有相当大的偏移量是错误的。 在这里做了一个fiddle:
https://jsfiddle.net/syberyan/yd8L4v0q/
我修改了 click() 函数,让它打印目标节点的坐标。
function getElementCoords(element, coords) {
var ctm = element.getCTM(),
x = ctm.e + coords.x*ctm.a + coords.y*ctm.c,
y = ctm.f + coords.x*ctm.b + coords.y*ctm.d;
return {x: x, y: y};
};
function click(d) {
if (d3.event.defaultPrevented) return; // click suppressed
d3.selectAll('.node').each(function (node, i) {
if (d === node) {
let coords = getElementCoords(this, node);
console.log(coords.x, coords.y); // shows coords relative to my svg container
}
});
}
我是 D3 新手所以我可能做错了什么,但是什么?或者也许有更好的方法?
我没有仔细查看链接的问题或您当前的计算。相反,我认为计算可以简化为:
function getElementCoords(element) {
// translate on node
var trans = d3.transform(d3.select(element).attr('transform')).translate,
// transform on parent "zoom" container
transFormParent = d3.transform(d3.select(element.parentNode).attr('transform')),
// translate on zoom container
transParent = transFormParent.translate,
// scale on zoom container
scaleParent = transFormParent.scale,
// final position of node
pos = {
x: trans[0] + transParent[0]/scaleParent[0],
y: trans[1] + transParent[1]/scaleParent[1]
};
return pos;
}
称其为:
function click(d) {
console.log(getElementCoords(this));
}
已更新 fiddle。
编辑
@Christian 在评论中指出,我的数学不对,应该是:
function getElementCoords(element) {
// translate on node
var trans = d3.transform(d3.select(element).attr('transform')).translate,
// transform on parent "zoom" container
transFormParent = d3.transform(d3.select(element.parentNode).attr('transform')),
// translate on zoom container
transParent = transFormParent.translate,
// scale on zoom container
scaleParent = transFormParent.scale,
// final position of node
pos = {
x: trans[0] * scaleParent[0] + transParent[0],
y: trans[1] * scaleParent[1] + transParent[1]
};
return pos;
}