D3js强制有向图动画和重载问题

时间:2016-05-14 00:12:39

标签: d3.js graph force-layout

下面的代码生成一个力导向图,但有几个问题。

  1. 喜欢如何控制开场动画速度
  2. 如何更改拖动速度
  3. 每次我尝试拖动某个元素时会出现主要问题,它会自动重新加载。
  4. 我不确定我做错了什么。

    var width = $(window).width(),
            height = 700;
    
    var force = d3.layout.force()
            .size([width, height])
            .on("tick", tick2);
    
    
    
    
    var svg = d3.select("body .banner").append("svg")
            .attr("width", width)
            .attr("height", height);
    //.on("click", explicitlyPosition);
    
    var link = svg.selectAll(".link"),
            node = svg.selectAll(".node");
    
    function tick2() {
        link
                .attr("x1", function (d) {
                    return width * 0.5;
                })
                .attr("y1", function (d) {
                    return height * 0.5;
                })
                .attr("x2", function (d) {
                    return width * 0.5;
                })
                .attr("y2", function (d) {
                    return height * 0.5;
                });
    
        d3.selectAll("circle")
                .attr("cx", function (d) {
                    return width * 0.5;
                })
                .attr("cy", function (d) {
                    return height * 0.5;
                });
    
        d3.selectAll("text")
                .attr("x", function (d) {
                    return width * 0.5;
                })
                .attr("y", function (d) {
                    return height * 0.5;
                });
        tick();
    }
    function tick() {
        link.transition()
                .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;
                });
    
        d3.selectAll("circle").transition()
                .attr("cx", function (d) {
                    return d.x;
                })
                .attr("cy", function (d) {
                    return d.y;
                });
    
        d3.selectAll("text").transition()
                .attr("x", function (d) {
                    return d.x;
                })
                .attr("y", function (d) {
                    return d.y;
                });
    }
    
    var graph = {
        "nodes": [
            {"name": "You", "val": "You", "x": width * 0.50, "y": height * 0.5, "fixed": false},
            {"name": "SaaS", "val": 768, "x": width * 0.40, "y": height * 0.14, "fixed": true},
            {"name": "Education", "val": 1021, "x": width * 0.65, "y": height * 0.10, "fixed": true},
            {"name": "E-Commerce", "val": 1345, "x": width * 0.75, "y": height * 0.35, "fixed": true},
            {"name": "Food Tech", "val": 512, "x": width * 0.70, "y": height * 0.72, "fixed": true},
            {"name": "Healthcare", "val": 246, "x": width * 0.57, "y": height * 0.70, "fixed": true},
            {"name": "Fashion Industry", "val": 657, "x": width * 0.30, "y": height * 0.80, "fixed": true},
            {"name": "Hardware", "val": 145, "x": width * 0.30, "y": height * 0.65, "fixed": true},
            {"name": "Fintech", "val": 1160, "x": width * 0.25, "y": height * 0.18, "fixed": true},
            {"name": "Series A", "val": 392, "x": width * 0.85, "y": height * 0.13, "fixed": true},
            {"name": "Series B", "val": 873, "x": width * 0.80, "y": height * 0.60, "fixed": true},
            {"name": "2014", "val": 592, "x": width * 0.125, "y": height * 0.25, "fixed": true},
            {"name": "2015", "val": 630, "x": width * 0.19, "y": height * 0.45, "fixed": true}
        ],
        "links": [
            {"source": 0, "target": 1},
            {"source": 0, "target": 2},
            {"source": 0, "target": 3},
            {"source": 3, "target": 9},
            {"source": 3, "target": 10},
            {"source": 0, "target": 4},
            {"source": 0, "target": 5},
            {"source": 0, "target": 6},
            {"source": 0, "target": 7},
            {"source": 0, "target": 8},
            {"source": 8, "target": 11},
            {"source": 8, "target": 12}
        ]
    };
    
    
    
    
    link = link.data(graph.links)
            .enter().append("line")
            .attr("class", "link");
    
    node = node.data(graph.nodes)
            .enter().append("g")
            .call(force.drag);
    
    node.append("circle")
            .attr("class", "node")
            .attr("r", function (d) {
                you_val = (d.val === "You") ? 1500 : d.val;
                return ((you_val) / 30) < 15 ? 15 : ((you_val) / 30);
            });
    
    node.append("text")
            .attr("x", 0)
            .attr("dy", ".35em")
            .attr("text-anchor", "middle")
            .attr("fill", "#9a9a9a")
            .attr("font-size", "12px")
            .attr("font-weight", "600")
            .text(function (d) {
                return d.val;
            });
    
    node.append("text")
            .attr("x", 0)
            .attr("dy", function (d) {
                you_val = (d.val === "You") ? 1500 : d.val;
                var rad = ((you_val) / 30) < 15 ? 15 : ((you_val) / 30);
                return (rad + 15) + "px";
            })
            .attr("text-anchor", "middle")
            .attr("fill", "#9a9a9a")
            .attr("font-size", "12px")
            .text(function (d) {
                return d.name;
            });
    
    force
            .nodes(graph.nodes)
            .links(graph.links)
            .start();
    

1 个答案:

答案 0 :(得分:0)

我不明白为什么你有两个滴答功能。

  1. 如何更改拖动速度
  2. 每次我尝试拖动某个元素时会出现主要问题,它会自动重新加载。
  3. 只需要一个这样的滴答功能:

    function tick2() {
        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;
                });
    
        d3.selectAll("circle")
                .attr("cx", function (d) {
                    return d.x;
                })
                .attr("cy", function (d) {
                    return d.y;
                });
    
        d3.selectAll("text")
                .attr("x", function (d) {
                    return d.x;
                })
                .attr("y", function (d) {
                    return d.y;
                });
    }
    

    在你的情况下,你有两个tick函数,两者都有一个非常不同的逻辑。

    3)如何控制开场动画速度

    您已将节点指定为x和y

    赞:{"name": "You", "val": "You", "x": width * 0.50, "y": height * 0.5, "fixed": true}

    在这种情况下,力布局不计算x和y,因为你说它是一个固定的节点,这意味着它不能通过力布局移动。

    如果您希望布局在加载时有动画来计算自己的位置,请阅读这个真棒tutorial

    工作代码here