D3:是否可以阻止对象退出边界?

时间:2015-05-07 23:55:14

标签: javascript d3.js force-layout

我在使用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;
}

1 个答案:

答案 0 :(得分:1)

刚刚解决了这个问题。出现时,需要修复px和py坐标:

var drag = force.drag()
    .on("dragstart", onDragStart)
    .on("drag", onDrag);

function validate(x, a, b) {
    if (x < a) x = a;
    if (x > b) x = b;
    return x;
}

function onDragStart(d) {
    d.fixed = true;
}

function onDrag(d) {
   d.px = validate(d.px, 0, w);
   d.py = validate(d.py, 0, h);
}