D3 Force指示图:为什么不显示链接,为什么模拟在左边?

时间:2017-04-29 08:29:28

标签: javascript d3.js

CODEPEN:

https://codepen.io/anon/pen/OmpYoL

状况:

目前正在学习D3,试图创建一个力导向图。

我遵循了本教程:

http://www.puzzlr.org/force-directed-graph-minimal-working-example/

数据如下:

https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json

CODE:

<script type="text/javascript">         
    d3.json("https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json", function(error, json) {

        if (error) {
          return console.warn(error);
        }

        const data = json;
        const nodes = data.nodes;
        const links = data.links;

        const margin = {
            top: 10,
            right: 85,
            bottom: 65,
            left: 70
        }

        const w = 1250 - margin.left - margin.right;
        const h = 500 - margin.top - margin.bottom;

        const svg = d3.select("#results")
            .append("svg")
            .attr("width",  w + margin.left + margin.right)
            .attr("height", h + margin.top + margin.bottom);

        const simulation = d3.forceSimulation()
            .nodes(nodes);

        simulation
            .force("charge_force", d3.forceManyBody())
            .force("center_force", d3.forceCenter(w / 2, h / 2));

        const node = svg.append("g")
            .attr("class", "nodes")
            .selectAll("circle")
            .data(nodes)
            .enter()
            .append("circle")
            .attr("r", 5)
            .attr("fill", "red");

        const link_force =  d3.forceLink(links)

        simulation.force("links",link_force)

        const link = svg.append("g")
          .attr("class", "links")
          .selectAll("line")
          .data(links)
          .enter().append("line")
          .attr("stroke-width", 2); 

        simulation.on("tick", tickActions());

        function tickActions() {
            node
                .attr("cx", function(d) { return d.x; })
                .attr("cy", function(d) { return d.y; });

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

    });

</script>

更新: enter image description here

1 个答案:

答案 0 :(得分:2)

为什么链接不显示?

您尚未指定stroke属性

const link = svg.append("g")
          .attr("class", "links")
          .selectAll("line")
          .data(links)
          .enter().append("line")
          .attr('stroke','black') // add this line
          .attr("stroke-width", 2); 

为什么模拟在左边?

因为,tick处理程序无法正常工作

而不是

simulation.on("tick", tickActions());

应该是

simulation.on("tick", tickActions);

<强>段

<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
        <link href="https://fonts.googleapis.com/css?family=Lato" rel="stylesheet">
        <link rel="stylesheet" href="main.css">
        <style>
            body { 
                font-family: Lato;
                background-color: #F5F5F5; 
            }
        </style>
    </head>
    <body>
        <div class="body">
            <div class="container-fluid">
                <h1 class="text-center title">Countries linked by Border</h1>
                <div class="text-center">
                    <div id="results"></div>
                </div>
                <img src="https://image.ibb.co/gMUNBQ/flags.png" alt="flags" border="0"/>
            </div>
        </div>
    </body>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script
  src="https://code.jquery.com/jquery-3.1.1.min.js"
  integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
  crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
    
    <script type="text/javascript">    
        
        d3.json("https://raw.githubusercontent.com/DealPete/forceDirected/master/countries.json", function(error, json) {
            
            if (error) {
              return console.warn(error);
            }
        
            const data = json;
            const nodes = data.nodes;
            const links = data.links;
            
            const margin = {
                top: 10,
                right: 85,
                bottom: 65,
                left: 70
            }
            
            const w = 1250 - margin.left - margin.right;
            const h = 500 - margin.top - margin.bottom;
            
            const svg = d3.select("#results")
                .append("svg")
                .attr("width",  w + margin.left + margin.right)
                .attr("height", h + margin.top + margin.bottom);

            const simulation = d3.forceSimulation()
                .nodes(nodes);
            
            simulation
                .force("charge_force", d3.forceManyBody())
                .force("center_force", d3.forceCenter(w / 2, h / 2));
            
            const node = svg.append("g")
                .attr("class", "nodes")
                .selectAll("circle")
                .data(nodes)
                .enter()
                .append("circle")
                .attr("x", w/2)
                .attr("r", 5)
                .attr("fill", "red");
            
            const link_force =  d3.forceLink(links)
                      
            simulation.force("links",link_force)
            
            const link = svg.append("g")
              .attr("class", "links")
              .selectAll("line")
              .data(links)
              .enter().append("line")
              .attr('stroke','black')
              .attr("stroke-width", 2); 
            
            simulation.on("tick", tickActions);

            
            function tickActions() {
                node
               
                    .attr("cx", function(d) { return d.x; })
                    .attr("cy", function(d) { return d.y; });

                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; });
            }
        
        });
            
    </script>

</html>