【发布时间】:2015-05-07 23:55:13
【问题描述】:
我在使用 d3 库时遇到了一些问题。
我有一些启用 force.drag() 功能的节点。我希望他们留在某个乡绅里面。我一直在尝试这种方法:
var force = d3.layout.force()
.size([w, h])
.charge(-40)
.linkDistance(getLinkDistance)
.gravity(0.01);
var drag = force.drag()
.on("dragstart", onDragStart)
.on("drag", onDrag);
function onDragStart(d) {
d.fixed = true;
}
function onDrag(d) {
if (d.x < 0)
d.x = 0;
if (d.x > w)
d.x = w;
if (d.y < 0)
d.y = 0;
if (d.y > h)
d.y = h;
}
var newNodes = gnodes.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
.call(drag);
不幸的是,拖动功能似乎忽略了这一点,并且对象仍然能够退出边界并变得不可见。如何防止拖动功能将对象移动到我的限制之外?澄清一下,只有拖动对象必须留在乡绅内,其余的可以随意剥皮。
更新:
如果坐标错误,我已经通过添加 dragend 事件并在那里释放节点来部分解决问题。现在该节点将至少从屏幕外部返回。我仍然无法操纵它的坐标。
var drag = force.drag()
.on("dragstart", onDragStart)
.on("dragend", onDragEnd);
function onDragStart(d) {
d.fixed = true;
}
function onDragEnd(d) {
if (d.x < 0 || d.x > w || d.y < 0 || d.y > h)
d.fixed = false;
}
【问题讨论】:
-
只改变数据是不够的,你还需要用新的位置更新DOM元素。
-
@LarsKotthoff 不应该通过调用 update() 来自动执行 force.drag() 函数吗?
-
拖动函数不会调用任何东西。您可能指的是强制布局的
tick处理函数——原则上是的,但前提是布局仍在运行。 -
@LarsKotthoff 它正在运行,以太如何,坐标不更新。似乎在将节点添加到 svg 之后,节点对象的 x 和 y 参数只是被忽略了。
-
你能发布一个完整的例子来演示这个问题吗?
标签: javascript d3.js force-layout