简体   繁体   English

D3.js-使用画布缩放网络图,然后拖动节点

[英]D3.js - Zoom network graph with canvas and then drag node

I have implemented a network graph using canvas using this example (Force Layout with Canvas) with functionality to drag (Circle Dragging II) and to zoom (Canvas geometric zooming) all updated to V4. 我已使用此示例(使用“画布进行强制布局”)使用画布实现了网络图并具有将其拖动(圆拖动II)缩放(画布几何缩放)功能全部更新到V4的功能。

The problem is that when I zoom or drag the canvas and applying: 问题是当我缩放或拖动画布并应用时:

canvas.translate(d3.event.translate[0], d3.event.translate[1]);
canvas.scale(d3.event.scale, d3.event.scale);

The nodes objects are somehow not updated accordingly. 节点对象不知何故没有相应地更新。 They are drawn just fine before the canvas.restore(); 它们在canvas.restore();之前绘制得很好canvas.restore(); , but when I try to target a node with the mouse using: ,但是当我尝试使用以下鼠标来定位节点时:

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;
    }
}

Nothing happens. 什么都没发生。

I end up doing this: 我最终这样做:

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;
    }
}

Saving and adding the translations and scale so that I can properly select them after canvas drag/zoom, but it doesn't seems to be the right way to me. 保存并添加翻译和缩放比例,以便在拖动/缩放画布后可以正确选择它们,但这对我来说似乎不是正确的方法。 Also when I am redrawing the canvas after dragging I am having issues with the nodes properly positioning. 另外,当我在拖动后重新绘制画布时,节点的正确定位也存在问题。

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();
}

Anyway this doesn't look right to me. 无论如何,这对我来说并不正确。

Anyone with suggestions about improving or modifying? 有人对改进或修改有建议吗?

So I guess the solution could be found in this post: Mouse coordinates don't match after Scaling and Panning canvas . 所以我想可以在这篇文章中找到解决方案: 缩放和平移canvas之后,鼠标坐标不匹配 Draw function shouldn't be updated - stays the same as before. 绘图功能不应更新-与以前相同。

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();
}

Dragging handler function should be updated: 拖动处理程序功能应更新:

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM