D3.js不会拖动+尝试聚焦

时间:2015-09-25 00:06:30

标签: javascript d3.js

我正在进行简单的D3测试,由于某种原因我无法拖动节点。参考这个例子:(http://bl.ocks.org/mbostock/1804919)我想要的是我的每个节点都要启动并保持在它们的起始位置,但是在示例中我希望节点可以拖动,当它们被释放后返回到他们的起点。我错过了什么?

<!DOCTYPE html>
<meta charset="utf-8">
<style>
    .Properties{
        fill: green;
        stroke: black;
        stroke-width: 2px;
    }
    svg {
      background-color: #FFF;
      cursor: default;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      -o-user-select: none;
      user-select: none;
    }
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
        var width = 960, height = 500, colors = d3.scale.category10();
        var svg = null, force = null;
        var circle = null, path = null;
        var nodes = null, links = null;
        var nodesArray = null, linkArray = null;
        var count = 0;
        var element = "body"; var numEdges = 2, numNodes = 5;
        var i = 0; var L = 16, r = 12, lineLimit = 10;
        var d = 2 * r + L;
        var R = (count - 1) * d;
        var m = width / 2;
        var X;
        var drag = d3.behavior.drag();
        svg = d3.selectAll(element).append('svg').attr('width', width).attr('height', height);
        nodes = d3.range(numNodes).map(function () {
            X = m - (R / 2) + (i * d);
            ++i;
            return {
                x: X,
                y: (height) / 3,
                fx: X,
                fy: height / 3,
                id: i-1,
                reflexive: true
            };           
        });
        for (var i = 0; i < numNodes; ++i) {
            d3.select(element).append("h3").text("Node " + i + ": " + nodes[i].id);
        }

        i = -1;
        links = d3.range(numEdges).map(function () {
            i++;
            return {
                //
                source: nodes[i],
                target: nodes[i+1],
                left: false,
                right: true
            }
        });
        for (var i = 0; i < numEdges; ++i) {
            d3.select(element).append("h3").text("Source: " + links[i].source.id + " Target: " + links[i].target.id);
        }

        force = d3.layout.force().size([width, height]).nodes(nodes).links(links).linkDistance(40).linkStrength(0.1).charge(-300);

        linkArray = svg.selectAll('.link').data(links).enter().append('line').attr('class', 'link')
            .attr('x1', function (d) {
                return nodes[d.source.id].x;
            })
            .attr('y1', function (d) { return nodes[d.source.id].y; })
            .attr('x2', function (d) { return nodes[d.target.id].x; })
            .attr('y2', function (d) { return nodes[d.target.id].y; });

        nodeArray = svg.selectAll("circle").data(nodes).enter().append('circle').attr('class', "Properties").attr('r', 12)
            .attr('cx', function (d) { return d.x })
            .attr('cy', function (d) { return d.y })
            .style('cursor', 'pointer').call(drag);

        force.on('tick', tick);
        force.start();

        //Move Nodes towards focus
        function gravity(alpha) {
            return function (d) {
                d.y += (d.fy - d.y) * alpha;
                d.x += (d.fx - d.x) * alpha;
            };
        }

        function tick() {
            alert("in Stepforce" + nodeArray[1].id);

            nodeArray
                .attr('cx', function (d) { return d.x; })
                .attr('cy', function (d) { return d.y; })
                .each(gravity(.2 * e.alpha));

            linkArray.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; });
        }

</script>

1 个答案:

答案 0 :(得分:1)

您错过了拖动事件到drag变量的链接。你必须call functions for the dragstart, drag, and dragend events.

在您的特定情况下,您希望(1)记录圆的初始位置,(2)根据鼠标的位置平移圆,以及(3)当圆圈返回原始位置时拖动结束。

例如:

var drag = d3.behavior.drag()
  .on('dragstart', dragstart) // when the drag starts, call dragstart()
  .on('drag', drag) // during drag, call drag()
  .on('dragend', dragend); // call dragend() on release

var originalPosition;
function dragstart() {
    // store starting coordinates
    originalPosition = d3.mouse(this); // returns array with x and y coords -> [x, y]
}

function drag() {
    var m = d3.mouse(this);
    // make the circle's coordinates match those of the mouse
    d3.select(this)
      .attr('cx', m[0])
      .attr('cy', m[1]);
}

function dragend() {
    // send circle back to original position
    d3.select(this)
      .attr('cx', originalPosition[0])
      .attr('cy', originalPosition[1]);
}

您还可以在更改transition()中的属性之前添加dragend(),以将它们设置回原始位置。此外,您可能希望将圆圈发回原始坐标,而不是拖动开始时鼠标的位置。不过,这应该可以让你开始。