D3.js - 使用 canvas 缩放网络图,然后拖动节点
D3.js - Zoom network graph with canvas and then drag node
我已经使用 canvas 使用 this example (Force Layout with Canvas) with functionality to drag (Circle Dragging II) and to zoom (Canvas geometric zooming) 实现了一个网络图,全部更新到 V4。
问题是当我缩放或拖动 canvas 并应用时:
canvas.translate(d3.event.translate[0], d3.event.translate[1]);
canvas.scale(d3.event.scale, d3.event.scale);
节点对象以某种方式未相应更新。它们在 canvas.restore();
之前绘制得很好,但是当我尝试使用鼠标定位节点时:
function getDragSubject() {
for (var i = nodes.length - 1, node, x, y; i >= 0; --i) {
node = nodes[i];
x = node.x - d3.event.x;
y = node.y - d3.event.y;
if (x * x + y * y < radius * radius) return node;
}
}
没有任何反应。
我最终这样做了:
function getDragSubject() {
for (var i = nodes.length - 1, node, x, y; i >= 0; --i) {
node = nodes[i];
x = node.x * scale + translation[0] - d3.event.x;
y = node.y * scale + translation[1] - d3.event.y;
if (x * x + y * y < (radius * scale) * (radius * scale)) return node;
}
}
保存并添加翻译和比例,以便我可以在 canvas drag/zoom 之后正确地 select 它们,但这对我来说似乎不是正确的方法。此外,当我在拖动后重绘 canvas 时,我遇到了节点正确定位的问题。
function draw() {
// draw links
context.strokeStyle = '#ccc';
context.beginPath();
links.forEach(function(d) {
context.moveTo(d.source.x * scale + translation[0], d.source.y * scale + translation[1]);
context.lineTo(d.target.x * scale + translation[0], d.target.y * scale + translation[1]);
});
context.stroke();
// draw nodes
context.fillStyle = 'steelblue';
context.beginPath();
nodes.forEach(function(d) {
context.moveTo(d.x * scale + translation[0], d.y * scale + translation[1]);
context.arc(d.x * scale + translation[0], d.y * scale + translation[1], radius * scale, 0, 2 * Math.PI);
});
context.fill();
}
无论如何,这对我来说不合适。
有人对改进或修改有建议吗?
所以我想可以在 post 中找到解决方案:Mouse coordinates don't match after Scaling and Panning canvas。绘图功能不应更新 - 与以前保持一致。
function draw() {
// draw links
context.strokeStyle = '#ccc';
context.beginPath();
links.forEach(function(d) {
context.moveTo(d.source.x, d.source.y);
context.lineTo(d.target.x, d.target.y);
});
context.stroke();
// draw nodes
context.fillStyle = 'steelblue';
context.beginPath();
nodes.forEach(function(d) {
context.moveTo(d.x, d.y);
context.arc(d.x, d.y, radius, 0, 2 * Math.PI);
});
context.fill();
}
应更新拖动处理函数:
var rect = canvas.getBoundingClientRect();
function onDrag() {
d3.event.subject.fx = ((d3.event.sourceEvent.pageX - rect.left) - translation[0]) / scale;
d3.event.subject.fy = ((d3.event.sourceEvent.pageY - rect.top) - translation[1]) / scale;
}
我已经使用 canvas 使用 this example (Force Layout with Canvas) with functionality to drag (Circle Dragging II) and to zoom (Canvas geometric zooming) 实现了一个网络图,全部更新到 V4。
问题是当我缩放或拖动 canvas 并应用时:
canvas.translate(d3.event.translate[0], d3.event.translate[1]);
canvas.scale(d3.event.scale, d3.event.scale);
节点对象以某种方式未相应更新。它们在 canvas.restore();
之前绘制得很好,但是当我尝试使用鼠标定位节点时:
function getDragSubject() {
for (var i = nodes.length - 1, node, x, y; i >= 0; --i) {
node = nodes[i];
x = node.x - d3.event.x;
y = node.y - d3.event.y;
if (x * x + y * y < radius * radius) return node;
}
}
没有任何反应。
我最终这样做了:
function getDragSubject() {
for (var i = nodes.length - 1, node, x, y; i >= 0; --i) {
node = nodes[i];
x = node.x * scale + translation[0] - d3.event.x;
y = node.y * scale + translation[1] - d3.event.y;
if (x * x + y * y < (radius * scale) * (radius * scale)) return node;
}
}
保存并添加翻译和比例,以便我可以在 canvas drag/zoom 之后正确地 select 它们,但这对我来说似乎不是正确的方法。此外,当我在拖动后重绘 canvas 时,我遇到了节点正确定位的问题。
function draw() {
// draw links
context.strokeStyle = '#ccc';
context.beginPath();
links.forEach(function(d) {
context.moveTo(d.source.x * scale + translation[0], d.source.y * scale + translation[1]);
context.lineTo(d.target.x * scale + translation[0], d.target.y * scale + translation[1]);
});
context.stroke();
// draw nodes
context.fillStyle = 'steelblue';
context.beginPath();
nodes.forEach(function(d) {
context.moveTo(d.x * scale + translation[0], d.y * scale + translation[1]);
context.arc(d.x * scale + translation[0], d.y * scale + translation[1], radius * scale, 0, 2 * Math.PI);
});
context.fill();
}
无论如何,这对我来说不合适。
有人对改进或修改有建议吗?
所以我想可以在 post 中找到解决方案:Mouse coordinates don't match after Scaling and Panning canvas。绘图功能不应更新 - 与以前保持一致。
function draw() {
// draw links
context.strokeStyle = '#ccc';
context.beginPath();
links.forEach(function(d) {
context.moveTo(d.source.x, d.source.y);
context.lineTo(d.target.x, d.target.y);
});
context.stroke();
// draw nodes
context.fillStyle = 'steelblue';
context.beginPath();
nodes.forEach(function(d) {
context.moveTo(d.x, d.y);
context.arc(d.x, d.y, radius, 0, 2 * Math.PI);
});
context.fill();
}
应更新拖动处理函数:
var rect = canvas.getBoundingClientRect();
function onDrag() {
d3.event.subject.fx = ((d3.event.sourceEvent.pageX - rect.left) - translation[0]) / scale;
d3.event.subject.fy = ((d3.event.sourceEvent.pageY - rect.top) - translation[1]) / scale;
}