在d3

时间:2016-01-23 23:54:06

标签: javascript d3.js

我使用强制布局算法绘制图形。但我希望用户能够禁用强制布局算法并能够移动节点。我遵循示例here(P用于固定)作为构建我的代码的基础。

但是,我希望用户能够理解基于力的算法之美,因此只有在用户按下按钮后才能启用拖动和固定"使拖拽"。

以下是我正在使用的代码......

<!DOCTYPE html>
<html lang="en">
<style>

    .node {
      stroke: #fff;
      stroke-width: 1.5px;
    }

    .link {
      stroke: #999;
      stroke-opacity: .6;
    }


</style>
<head>
    <meta charset="UTF-8">
    <title>Spatial Social Network</title>

    <script src="//d3js.org/d3.v3.min.js"></script>
</head>
<body>
    <h1>The network</h1>

    <script>
        var width = 500,
            height = 500;

        var color = d3.scale.category20();


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

         var force = d3.layout.force()
                .charge(-120)
                .linkDistance(30)
                .size([width, height]);

        /*Drag and pin*/
        var node_drag = d3.behavior.drag()
            .on("dragstart", dragstart)
            .on("drag", dragmove)
            .on("dragend", dragend);
        function dragstart(d, i) {
            alert("I am here");
            force.stop() // stops the force auto positioning before you start dragging
        }
        function dragmove(d, i) {
            d.px += d3.event.dx;
            d.py += d3.event.dy;
            d.x += d3.event.dx;
            d.y += d3.event.dy;
        }
        function dragend(d, i) {
            d.fixed = true; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
            force.resume();
        }
        function releasenode(d) {
            d.fixed = false; // of course set the node to fixed so the force doesn't include the node in its auto positioning stuff
            //force.resume();
        }
        /*Drag and pin*/

        svg.append('text')
            .attr("x", 2)
            .attr("y", 20)
            .text("Force Layout")
            .attr("font-family", "sans-serif")
            .attr("font-size", "20px")
            .attr("fill", "red");


        d3.json("jsonGraph.json", function(error, graph) {
            if (error) throw error;


            //console.log(graph.nodes);

            force
                .nodes(graph.nodes)
                .links(graph.links)
                .start();

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


            var node = svg.selectAll(".node")
                .data(graph.nodes)
                .enter().append("circle")
                .attr("class", "node")
                .attr("r", 5)
                .style("fill", function(d) { return color(d.class); })
                .call(force.drag);                

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

            force.on("tick", function() {
                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("cx", function(d) { return d.x; })
                .attr("cy", function(d) { return d.y; });
            });



        });

        function MakeDraggable()
        {
            alert("here");
            d3.json("jsonGraph.json", function(error, graph) {
                if (error) throw error;


                force
                    .nodes(null)
                    .links(null)
                    .start();

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

                var node = svg.selectAll(".node")
                    .data(graph.nodes)
                    .enter().append("circle")
                    .attr("class", "node")
                    .attr("r", 5)
                    .style("fill", function(d) { return color(d.class); })
                    //.call(force.drag);
                    .call(node_drag)
                    .on('dblclick', releasenode);

                //force.stop();

            });
        }



    </script>

     <input type="button" name="MakeDraggable" value="Make Draggable!" onClick="MakeDraggable()"></input> 

</body>
</html> 

不幸的是,即使在按下按钮后,行为似乎也没有任何改变&#34; Make Draggable!&#34;。

这是我用来阅读图表的json文件:

{
"directed": false,
"graph": {
    "name": "Fun Graph"
},
"nodes": [
    {
        "class": "A",
        "id": "A"
    },
    {
        "class": "B",
        "id": "C"
    },
    {
        "class": "B",
        "id": "B"
    },
    {
        "class": "B",
        "id": "E"
    },
    {
        "class": "B",
        "id": "D"
    },
    {
        "class": "A",
        "id": "G"
    },
    {
        "class": "B",
        "id": "F"
    },
    {
        "class": "A",
        "id": "I"
    },
    {
        "class": "B",
        "id": "H"
    },
    {
        "class": "A",
        "id": "K"
    },
    {
        "class": "B",
        "id": "J"
    },
    {
        "class": "B",
        "id": "M"
    },
    {
        "class": "A",
        "id": "L"
    },
    {
        "class": "A",
        "id": "O"
    },
    {
        "class": "A",
        "id": "N"
    }
],
"links": [
    {
        "source": 0,
        "target": 8
    },
    {
        "source": 0,
        "target": 9
    },
    {
        "source": 0,
        "target": 2
    },
    {
        "source": 0,
        "target": 11
    },
    {
        "source": 0,
        "target": 4
    },
    {
        "source": 1,
        "target": 7
    },
    {
        "source": 1,
        "target": 11
    },
    {
        "source": 2,
        "target": 11
    },
    {
        "source": 2,
        "target": 12
    },
    {
        "source": 3,
        "target": 4
    },
    {
        "source": 3,
        "target": 5
    },
    {
        "source": 3,
        "target": 6
    },
    {
        "source": 4,
        "target": 7
    },
    {
        "source": 4,
        "target": 11
    },
    {
        "source": 4,
        "target": 12
    },
    {
        "source": 5,
        "target": 7
    },
    {
        "source": 5,
        "target": 8
    },
    {
        "source": 6,
        "target": 11
    },
    {
        "source": 6,
        "target": 12
    },
    {
        "source": 7,
        "target": 13
    },
    {
        "source": 7,
        "target": 8
    },
    {
        "source": 9,
        "target": 14
    },
    {
        "source": 10,
        "target": 11
    },
    {
        "source": 10,
        "target": 14
    },
    {
        "source": 12,
        "target": 13
    }
],
"multigraph": false
}

我是D3的新手,不知道我哪里出错了。

  [1]: http://www.coppelia.io/2014/07/an-a-to-z-of-extra-features-for-the-d3-force-layout/

1 个答案:

答案 0 :(得分:2)

单击按钮,您无需重新创建/重新加载完整的力布局:

function MakeDraggable()
        {
            alert("here");
            d3.json("jsonGraph.json", function(error, graph) {
                if (error) throw error;


                force
                    .nodes(null)
                    .links(null)
                    .start();

这可以通过以下方式完成:

function MakeDraggable() {
  svg.selectAll(".node").call(node_drag);//attach the drag behavior
}

工作演示here

希望这有帮助!