Jquery 用于触摸设备的D3树中的拖放功能
我已经创建了D3树。拖放功能适用于台式机和笔记本电脑。D3中是否有支持触摸设备的拖放功能 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 + "," +
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上指的是这个网站,这在触摸设备上有相同的问题,谢谢。我已经尝试过了,