d3 v4 / v5树形拖放到链接节点无法正常工作

时间:2018-10-26 16:58:17

标签: javascript d3.js

首先,对不起我的英语不好。

我想做的是:处理所有节点(根节点除外)的拖放操作,如果它们链接到另一个父节点,则更新其父节点。

我的代码中发生了问题:我可以第一次拖动节点并将其拖放到任何地方。但是,当我第二次单击以再次拖动时,它转换为它的原始位置。当我尝试将一个节点链接到其他父节点时,svg路径被绘制在一个奇怪的位置。

我适应d3v5的

Code(老实说,我不会因为面临这个问题而使用d3v3,除非没有解决方案)。 Similar question是我在SO中找到的,但该解决方案无法正常工作。 Tutorial拖放我尝试在代码中复制的d3v5,但没有成功。

我的代码:https://jsfiddle.net/mewlee/0w5jzhnf/48/

function initiateDrag(d, domNode) {
       draggingNode = d;
       d3.select(domNode).select('.ghostCircle').attr('pointer-events', 'none');
       d3.selectAll('.ghostCircle').attr('class', 'ghostCircle show');
       d3.select(domNode).attr('class', 'node activeDrag');

       svgGroup.selectAll("g.node").sort(function(a, b) { // select the parent and sort the path's
           if (a.id != draggingNode.id) return 1; // a is not the hovered element, send "a" to the back
           else return -1; // a is the hovered element, bring "a" to the front
       });

        // if nodes has children, remove the links and nodes
        if (nodesDragDrop.length > 1) {
            // remove link paths
            links = nodesDragDrop.slice(1);
            nodePaths = svgGroup.selectAll("path.link")
                .data(links, function(d) {
                    return d.id;
                }).remove();
            // remove child nodes
            nodesExit = svgGroup.selectAll("g.node")
                .data(nodesDragDrop, function(d) {
                    return d.id;
                }).filter(function(d, i) {
                    if (d.id == draggingNode.id) {
                        return false;
                    }
                    return true;
                }).remove();
        }
        // remove parent link
        var parent = d3.hierarchy(draggingNode.parent);
        parentLink = parent.descendants().slice(1);

    svgGroup.selectAll('path.link').filter(function(d,i){
        if(d.id==draggingNode.id){          
            return true;
        }
        return false;
    }).remove();

    dragStarted = false;
} 
var dragListener = d3.drag()
    .on("start", function(d) {
        if (d == raiz) {
            return;
        }
        dragStarted = true;
        nodesDragDrop = d.descendants();
        d3.event.sourceEvent.stopPropagation();
        // it's important that we suppress the mouseover event on the node being dragged. Otherwise it will absorb the mouseover event and the underlying node will not detect it
        var atual = d3.select(this);
        deltaX = atual.attr("x")-d3.event.x;
        deltaY = atual.attr("y")-d3.event.y;
    })
    .on("drag", function(d) {
         var node = d3.select(this);

         node.attr('x',d.x = d3.event.dx+deltaX);
         node.attr('y',d.y = d3.event.dy+deltaY);
        if (d == raiz) {
            return;
        }
        if (dragStarted) {
            domNode = this;
            initiateDrag(d, domNode);
        }

        d.x0 += d3.event.dy;
        d.y0 += d3.event.dx;
        node.attr("transform", "translate(" + d.y0 + "," + d.x0 + ")");
        updateTempConnector();
    }).on("end", function(d) {
        if (d == raiz) {
            return;
        }
        domNode = this;
        if (selectedNode) {
            // now remove the element from the parent, and insert it into the new elements children
            var index = draggingNode.parent.children.indexOf(draggingNode);
            if (index > -1) {

                draggingNode.parent.children.splice(index, 1);
            }
            if (typeof selectedNode.children !== 'undefined' || typeof selectedNode._children !== 'undefined') {
                if (typeof selectedNode.children !== 'undefined') {
                    selectedNode.children.push(draggingNode);

                } else {
                    selectedNode._children.push(draggingNode);
                }
            } else {
                selectedNode.children = [];
                selectedNode.children.push(draggingNode);
            }
            // Make sure that the node being added to is expanded so user can see added node is correctly moved
            expand(selectedNode);
            endDrag();
        } else {
            endDrag();
        }
    });

function endDrag() {
    selectedNode = null;

    d3.selectAll('.ghostCircle').attr('class', 'ghostCircle');
    d3.select(domNode).attr('class', 'node');
    // now restore the mouseover event or we won't be able to drag a 2nd time
    d3.select(domNode).select('.ghostCircle').attr('pointer-events', '');
    updateTempConnector();
    if (draggingNode !== null) {
        construir(raiz);
        draggingNode = null;
    }
}

PS .:可能由于d3.nest在根d3.hierarchy中使用问题,因为“无用”的根节点;并且请不要生我的气,我知道代码很大:(

预先感谢

0 个答案:

没有答案