Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery 用于触摸设备的D3树中的拖放功能_Jquery_Ajax_D3.js - Fatal编程技术网

Jquery 用于触摸设备的D3树中的拖放功能

Jquery 用于触摸设备的D3树中的拖放功能,jquery,ajax,d3.js,Jquery,Ajax,D3.js,我已经创建了D3树。拖放功能适用于台式机和笔记本电脑。D3中是否有支持触摸设备的拖放功能 D3参考站点-对于触摸设备有相同的问题,拖放不适用于此代码 var nodeEnter = node.enter().append("g").call(dragListener).attr( "class", "node").attr("transform", function(d) { return "translate(" + source.y0 + "," +

我已经创建了D3树。拖放功能适用于台式机和笔记本电脑。D3中是否有支持触摸设备的拖放功能

D3参考站点-对于触摸设备有相同的问题,拖放不适用于此代码

var nodeEnter = node.enter().append("g").call(dragListener).attr(
            "class", "node").attr("transform", function(d) {
        return "translate(" + source.y0 + "," + source.x0 + ")";
    }).on("mouseenter", nodeMouseover).on("mouseleave", node_onMouseOut)
            .on('click', click).attr('id', function(d) {
                return d.nodeId;
            });

dragListener = d3.behavior.drag()
    .on("dragstart", function(d) {
        if (d == root) {
            return;
        }
        dragStarted = true;
        nodes = tree.nodes(d);
        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 d3.select(this).attr('pointer-events', 'none');
    })
    .on("drag", function(d) {
        if (d == root) {
            return;
        }
        if (dragStarted) {
            domNode = this;
            initiateDrag(d, domNode);
        }

        // get coords of mouseEvent relative to svg container to allow for panning
        relCoords = d3.mouse($('svg').get(0));
        if (relCoords[0] < panBoundary) {
            panTimer = true;
            pan(this, 'left');
        } else if (relCoords[0] > ($('svg').width() - panBoundary)) {

            panTimer = true;
            pan(this, 'right');
        } else if (relCoords[1] < panBoundary) {
            panTimer = true;
            pan(this, 'up');
        } else if (relCoords[1] > ($('svg').height() - panBoundary)) {
            panTimer = true;
            pan(this, 'down');
        } else {
            try {
                clearTimeout(panTimer);
            } catch (e) {

            }
        }

        d.x0 += d3.event.dy;
        d.y0 += d3.event.dx;
        var node = d3.select(this);
        node.attr("transform", "translate(" + d.y0 + "," + d.x0 + ")");
        updateTempConnector();
    }).on("dragend", function(d) {
        if (d == root) {
            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);
            sortTree();
            endDrag();
        } else {
            endDrag();
        }
    });
var nodeEnter=node.enter().append(“g”).call(dragListener).attr(
“类”、“节点”).attr(“转换”,函数(d){
返回“translate”(“+source.y0+”,“+source.x0+”);
}).on(“mouseenter”,nodeMouseover)。on(“mouseleave”,node_onMouseOut)
.on('click',click).attr('id',函数(d){
返回d.nodeId;
});
dragListener=d3.behavior.drag()
.on(“dragstart”,功能(d){
if(d==根){
返回;
}
dragStarted=真;
节点=树。节点(d);
d3.event.sourceEvent.stopPropagation();
//在被拖动的节点上抑制mouseover事件非常重要。否则它将吸收mouseover事件,并且底层节点将不会检测到它d3。选择(this).attr('pointer-events','none');
})
.开启(“拖动”,功能(d){
if(d==根){
返回;
}
如果(拖动启动){
domNode=this;
initiateDrag(d,domNode);
}
//获取mouseEvent相对于svg容器的坐标,以允许平移
relCoords=d3.mouse($('svg').get(0));
if(relCoords[0]($('svg').width()-panBoundary)){
panTimer=真;
潘(这个‘右’);
}else if(relCoords[1]($('svg').height()-panBoundary)){
panTimer=真;
平移(这个“向下”);
}否则{
试一试{
clearTimeout(panTimer);
}捕获(e){
}
}
d、 x0+=d3.event.dy;
d、 y0+=d3.event.dx;
var节点=d3。选择(此);
attr(“transform”、“translate”(+d.y0+)、“+d.x0+”);
updateTempConnector();
}).on(“dragend”,功能(d){
if(d==根){
返回;
}
domNode=this;
如果(selectedNode){
//现在从父元素中删除该元素,并将其插入新元素的子元素中
var index=draggingNode.parent.children.indexOf(draggingNode);
如果(索引>-1){
draggingNode.parent.children.splice(索引,1);
}
if(typeof selectedNode.children!='undefined'| | typeof selectedNode.\u children!=='undefined'){
if(所选节点的类型。子节点!=“未定义”){
selectedNode.children.push(拖动节点);
}否则{
选择节点。\u子节点。推送(拖动节点);
}
}否则{
selectedNode.children=[];
selectedNode.children.push(拖动节点);
}
//确保要添加到的节点已展开,以便用户可以看到添加的节点已正确移动
展开(selectedNode);
sortTree();
endDrag();
}否则{
endDrag();
}
});
D3自动创建事件侦听器来处理元素上的拖动手势。支持鼠标事件和触摸事件

注意:确保您使用的是最新版本的D3


拖动
行为支持单击和触摸,但在您给出的示例中,拖放位置由
鼠标悬停
事件给出:

// phantom node to give us mouseover in a radius around it
nodeEnter.append("circle")
    .attr('class', 'ghostCircle')
    .attr("r", 30)
    .attr("opacity", 0.2) // change this to zero to hide the target area
    .style("fill", "red")
    .attr('pointer-events', 'mouseover')
    .on("mouseover", function(node) {
        overCircle(node);
    })
    .on("mouseout", function(node) {
        outCircle(node);
    });
触摸设备上不会触发此
鼠标悬停
事件。 您可以做的是删除鬼影圈,并在
updateTempConnector()
之前的事件“drag”中手动执行计算

我可以提出如下建议:

var draggedNode = d;
var nodes = d3.selectAll("g.node")
.filter(function (d, i) {
    if ((d.id != draggedNode.id) && (!isChildOf(draggedNode, d))) {
        return d;
    }
    return 0;
});

var distances = [];

nodes.each(function (d, i) {
    var distanceX = draggedNode.x0 - d.x;
    var distanceY = draggedNode.y0 - d.y;                       
    var distance = Math.sqrt( Math.pow(distanceX, 2) + Math.pow(distanceY, 2) );
    distances.push({
        distance: distance,
        distanceV: distanceX,   // vertical, <0 when draggedNode is above
        distanceH: distanceY,   // horizontal, <0 when draggedNode is on the left
        d: d
    });
});

// sort by shorter distances
distances.sort(function (a, b) {
    return a.distance - b.distance;
});

selectedNode = distances[0].d;
var-draggedNode=d;
变量节点=d3。选择全部(“g.node”)
.过滤器(功能(d,i){
如果((d.id!=draggedNode.id)&&(!isChildOf(draggedNode,d))){
返回d;
}
返回0;
});
var距离=[];
节点。每个(功能(d,i){
var distanceX=draggedNode.x0-d.x;
var distanceY=draggedNode.y0-d.y;
var距离=Math.sqrt(Math.pow(distanceX,2)+Math.pow(distanceY,2));
推({
距离:距离,,
distanceV:distanceX,//vertical,对于示例,我通过执行以下两项操作来解决它:

第一:在“拖动”事件中,在触发updateTempConnector之前添加:

if ('ontouchstart' in window) {
    goalView.selectedNode = closestNode(d);
}
第二:然后定义以下函数:

var closestNode = function(d){
    var ghostCircleRadius = 30;
    var nodes = tree.nodes(goalView.rootNode).reverse();
    var minDistance = 100000000; //sufficiently large number
    var returnNode = null;
    for (var i = 0; i < nodes.length; i++) {
        var distance = (nodes[i].x0 - d.x0)*(nodes[i].x0 - d.x0) + (nodes[i].y0 - d.y0)*(nodes[i].y0 - d.y0);
        if (distance > 0){
            if (distance < minDistance && distance < ghostCircleRadius*ghostCircleRadius) {
                minDistance = distance;
                returnNode = nodes[i];
            }
        }
    }

    return returnNode;
};
var closestNode=函数(d){
var ghostCircleRadius=30;
var nodes=tree.nodes(goalView.rootNode).reverse();
var minDistance=100000000;//足够大的数字
var returnNode=null;
对于(var i=0;i0){
if(距离

这基本上是检查最近的节点,并检查我们的拖动节点是否在最接近的节点的鬼圈半径内。

@Glisha拖放功能适用于触摸设备上的Firefox。它不适用于Internet Explorer和Chrome。有任何建议请问您使用哪一版本的d3?请试用3.1版。5@Glisha 我正在使用最新版本的d3 tree.3.5.5。它不起作用。我正在触摸笔记本电脑上测试它,我在pad SafariI上指的是这个网站,这在触摸设备上有相同的问题,谢谢。我已经尝试过了,