2014-10-07 53 views
0

我需要在浏览器中模拟鼠标拖动事件来拖动d3强制节点。我正在使用这个解决方案来解决webcola force layout求解器中的一个约束错误。d3 /可编程节点使用initMouseEvent拖动

可口可乐主页:http://marvl.infotech.monash.edu/webcola/

类似的问题被问过,但不是我的应用程序 How to programmatically trigger a D3 drag event?

这里令人满意的回答是我到目前为止有:

http://jsfiddle.net/7oc0ez6q/14/

鼠标事件似乎在某种程度上起作用,但不是我想要的。我期望从下面的代码中可以看出,在每个tick中,每个节点都应该在x和y中拖动几个像素,因为xTest和yTest值会递增。

取而代之的是,当鼠标移动到结果框架中时,只有一个节点在一个圆圈中意外移动。显然,我不了解如何使用这些假鼠标事件。

感谢您的帮助。

var graph = { 
    "nodes":[ 
     {"name":"a","width":60,"height":40}, 
     {"name":"b","width":70,"height":190}, 
     {"name":"c","width":60,"height":40}, 
     {"name":"d","width":60,"height":80}, 
     {"name":"e","width":60,"height":40} 
    ], 
    "links":[ 
     {"source":1,"target":2}, 
     {"source":2,"target":0}, 
     {"source":2,"target":3}, 
     {"source":2,"target":4} 
    ], 
    "constraints":[ 
     {"type":"alignment", 
     "axis":"x", 
     "offsets":[ 
     {"node":"1", "offset":"0"}, 
     {"node":"2", "offset":"0"}, 
     {"node":"3", "offset":"0"} 
     ]}, 
     {"type":"alignment", 
     "axis":"y", 
     "offsets":[ 
     {"node":"0", "offset":"0"}, 
     {"node":"1", "offset":"0"}, 
     {"node":"4", "offset":"0"} 
     ]} 
    ] 
} 


var width = 350, 
     height = 320 

    var color = d3.scale.category20(); 

    var d3cola = cola.d3adaptor() 
     .linkDistance(120) 
     .avoidOverlaps(true) 
     .size([width, height]); 

    var svg = d3.select("body").append("svg") 
     .attr("width", width) 
     .attr("height", height); 

     graph.nodes.forEach(function (v) { v.x = 400, v.y = 50 }); 
     d3cola 
      .nodes(graph.nodes) 
      .links(graph.links) 
      .constraints(graph.constraints) 
      .start(10,10,10); 

     var link = svg.selectAll(".link") 
      .data(graph.links) 
      .enter().append("line") 
      .attr("class", "link"); 


     var node = svg.selectAll(".node") 
      .data(graph.nodes) 
      .enter().append("rect") 
      .attr("class", "node") 
      .attr("width", function (d) { return d.width; }) 
      .attr("height", function (d) { return d.height; }) 
      .attr("rx", 5).attr("ry", 5) 
      .style("fill", function (d) { return color(1); }) 
      .call(d3cola.drag); 



     var label = svg.selectAll(".label") 
      .data(graph.nodes) 
      .enter().append("text") 
      .attr("class", "label") 
      .text(function (d) { return d.name; }) 
      .call(d3cola.drag); 

     node.append("title") 
      .text(function (d) { return d.name; }); 

     var xTest=1; 
     var yTest=1; 

     d3cola.on("tick", function() { 

      xTest+=5; 
      yTest+=5; 

      link.attr("x1", function (d) { return d.source.x; }) 
       .attr("y1", function (d) { return d.source.y; }) 
       .attr("x2", function (d) { return d.target.x; }) 
       .attr("y2", function (d) { return d.target.y; }); 

      node.attr("x", function (d) { return d.x - d.width/2; }) 
       .attr("y", function (d) { return d.y - d.height/2; }); 

      label.attr("x", function (d) { return d.x; }) 
       .attr("y", function (d) { 
        var h = this.getBBox().height; 
        return d.y + h/4; 
       }); 

      progDrag(); 

     }); 



function progDrag() { 

    var evObjStart = document.createEvent('MouseEvents'); 
    var evObj = document.createEvent("MouseEvents"); 
    var evObjEnd = document.createEvent("MouseEvents"); 

    node.each(function (el) { 

     console.log(evObj); 

     evObjStart.initMouseEvent("mousedown", true, true, window, 1, xTest, yTest, xTest, yTest, false, false, false, false, 0, null); 
     evObj.initMouseEvent("mousemove", true, true, window, 1, xTest, yTest, xTest, yTest, false, false, false, false, 0, null); 
     //evObjEnd.initMouseEvent("mouseup", true, true, window, 1, xTest, yTest, xTest, yTest, false, false, false, false, 0, null); 

     this.dispatchEvent(evObjStart); 
     this.dispatchEvent(evObj);    
     //this.dispatchEvent(evObjEnd); 

    }); 

} 
+1

[Here's something](http://jsfiddle.net/meetamit/7oc0ez6q/18/)。不完美,但到达那里... – meetamit 2014-10-08 04:24:16

+0

@meetamit谢谢,看起来像这个假的拖动过程中用真实鼠标的任何用户活动将导致不可预知的行为。 – glyph 2014-10-09 15:06:41

回答

1

您可以使用下面的函数

function createCustomMouseEvent (type,x,y) { 
    var event = document.createEvent("MouseEvents"); 
    event.initMouseEvent(type, true, (type != "mousemove"), window, 0, x, y, x, y, false, false, false, false, 0, document.body.parentNode); 
    return event; 
} 

,然后D3选择元素创建自定义鼠标事件并分派鼠标按下,鼠标移动和MouseUp事件以编程方式实现拖动功能

var node = d3.select('.node').node(); var x = 0.1, y = 0.1; node.dispatchEvent(createCustomMouseEvent('mousedown', x,y,false)); node.dispatchEvent(createCustomMouseEvent('mousemove', x,y,false)); node.dispatchEvent(createCustomMouseEvent('mouseup', x,y,false));