动态D3力图

时间:2017-07-13 11:57:27

标签: javascript json d3.js

我正在尝试从表单的JSON文件动态创建图表:

{"nodes": [{"category": "...", "group": 1, "uid": 0, "number": 1, "complaints": [" ...,..."], "name": "..."}], "links": ['source':"",'target':"",'value':""]}

我可以正确地绘制图形,但是在添加新节点时,边缘没有正确形成,节点的半径也没有(它们根据JSON中的数字元素而改变)I无法找到任何代码,也没有教程记录如何在d3中执行此操作。但是,当您刷新页面时,图表会按照我的意愿显示。

这是我到目前为止所提出的代码,以便尝试这样做。我觉得需要做一些微小的改变才能使其发挥作用,但我无法弄清楚它是什么。当我刷新页面时它显示为我希望它的事实告诉我重启功能有问题。

<html>
    <head>
        <style>
            .node {
                stroke: #fff;
                stroke-width: 1.5px;
            }
            .link {
                stroke: #999;
                stroke-opacity: .6;
            }
            d3-tip {
                line-height: 1;
                color: black;
            }
        </style>
        <script src="https://d3js.org/d3.v3.min.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script type='text/javascript' src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"> </script>
    </head>

    <b>
    </b>



    <script>

        $.ajaxSetup({cache: false});
        var json;
        getJSON();
        function getJSON(){
                $.ajax({
                    'async': false,
                    'global': false,
                    'url': "/categories.json",
                    'dataType': "json",
                    'success': function (data) {
                        json = data;
                        console.log("Updating JSON")
                    }
                });
                return json;
        }

        window.setInterval(function(){
            getJSON();
            restart();
        }, 5000);


        var width = 500,
            height = 500;

        var color = d3.scale.category20();

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

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

        var tip = d3.tip()
            .attr('class', 'd3-tip')
            .offset([-10, 0])
            .html(function (d) {
            return  d.name + "</span>";
        })
        svg.call(tip);

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

        var link = svg.selectAll(".link")
            .data(json.links)
            .enter().append("line")
            .attr("class", "link")
            .style("stroke-width", function (d) {
            return Math.sqrt(d.value);
        });

        var node = svg.selectAll(".node")
            .data(json.nodes)
            .enter().append("circle")
            .attr("class", "node")
            .attr("r", function(d) {
                if(d.number >= 20){
                    return 50;
                }
                if(d.number > 1){
                    return ((d.number*1.3)+10);
                }else{
                    return d.number+4
                }

            })
            .style("fill", function (d) {
            return color(d.group);
        })
        .call(force.drag)
        .on('mouseover', tip.show)
        .on('mouseout', tip.hide);

        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 restart() {

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

          tip = d3.tip()
            .attr('class', 'd3-tip')
            .offset([-10, 0])
            .html(function (d) {
            return  d.name + "</span>";
          })
          svg.call(tip);

          link = svg.selectAll(".link")
            .data(json.links)
            .enter().append("line")
            .attr("class", "link")
            .style("stroke-width", function (d) {
            return Math.sqrt(d.value);
          });;

          // Apply the general update pattern to the nodes.
          node = svg.selectAll(".node")
            .data(json.nodes)
            .enter().append("circle")
            .attr("class", "node")
            .attr("r", function(d) {
                if(d.number >= 20){
                    return 50;
                }
                if(d.number > 1){
                    return ((d.number*1.3)+10);
                }else{
                    return d.number+4
                }

            })
            .style("fill", function (d) {
            return color(d.group);
          })
          .call(force.drag)
          .on('mouseover', tip.show)
          .on('mouseout', tip.hide);

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

          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;
            })
            node.attr("cy", function (d) {
                return d.y;
            });
          });


        }
    </script>

</html>

1 个答案:

答案 0 :(得分:1)

这是一个minimal working example on plunker,包含2个节点和1个使用json格式的链接。

我不完全确定你的目标是使用restart(),我假设你正在从文件中加载一次数据?在任何情况下,它不必在力布局上具有两次完全相同的逻辑。您可以在函数中添加/更新/删除逻辑d3,然后在数据更改时调用该函数。 tick函数也只需要指定一次。

我注释掉了工具提示代码,因为我也不想调试它,但我认为链接的资源不是https! http://blockbuilder.org/search是搜索可能有助于找到好例子的d3示例的良好资源。

如果您对答案感到满意,请将其标记为已接受的答案并进行投票。