使用initMouseEvent拖动d3 / cola程序节点

时间:2014-10-07 18:50:13

标签: javascript d3.js force-layout

我需要在浏览器中模拟鼠标拖动事件以拖动d3强制节点。我正在使用它作为webcola力布局求解器的约束错误的解决方法。

可乐主页: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 个答案:

答案 0 :(得分: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选择元素并调度mousedown,mousemove和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));