我有this d3.js强制布局,其中节点是带有相关文本的矩形。每当拖动节点时,位置都是固定的,就像在迈克的example中一样。
我希望节点在拖动时捕捉到不可见的网格。这样他们整齐地对齐。因此我将此添加到拖动事件中:
var grid = 50;
d3.select(this)
.attr("x", function(d) { return Math.round(d3.event.x/grid)*grid; })
.attr("y", function(d) { return Math.round(d3.event.y/grid)*grid; });
不知怎的,这没有按预期工作。我想这与力布局的滴答功能有关。但我不确定,因此force.stop(),force.start()调用以查看是否有帮助。
我还尝试将rect和text嵌套在g元素中,并使用transform(translate)来定位节点。但也没有成功。
答案 0 :(得分:3)
https://jsfiddle.net/e5fxojvm/
function dblclick(d) {
d3.select(this).classed("fixed", d.fixed = false);
}
function dragstarted(d) {
d3.select(this)
.classed("fixed", d.fixed = true);
}
function dragged(d,i) {
//force.stop();
var grid = 50;
var nx = Math.round(d3.event.x/grid)*grid;
var ny = Math.round(d3.event.y/grid)*grid;
d.px = nx;
d.py = ny;
}
function dragended(d) {
//force.start();
console.log(this);
}
节点的坐标取自dx和dy,用于节点数组中的每个数据点,因此,虽然您更新了屏幕上元素的x和y属性,但是下一个tick会将其重置为dx和dy,从而产生这种小动作你在你的演示中看到了(虽然在节点修复后它不再移动)
您需要对节点位置数据(d.x和d.y)进行离散化 - 不仅仅是节点DOM元素的位置属性,对于固定节点而言,这似乎是通过d.px和d.py(前一个节点坐标)完成的。 tick中的固定节点似乎通过将它们设置为d.px和d.py(https://github.com/mbostock/d3/blob/master/d3.js#L6299)来计算d.x和d.y?