简体   繁体   中英

Creating multiple lines using json file with coordinates in d3.js

I am trying to draw multiple lines that will create a map using coordinates that are in the json file located here.

https://www.dropbox.com/sh/luuzptywj2d7tv5/AAC23U5xWNzVL7mEPjPf5jPHa?dl=0

I am able to create the svg but I cannot get the lines to appear. Below is the code that I have used so far to create the svg and attempt to draw the lines. This is my first time using d3 and JSON files so any explanation is appreciated.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset = "UTF-8">
        <script src="https://d3js.org/d3.v3.min.js"></script>
        <title></title>
    </head>
    <body>
        <script type = "text/javascript">
            var streets;    // declare global variable
            var w = 960;     // width of svg
            var h = 800;      // height of svg
            var svg = d3.select( "body" )
                    .append( "svg" )
                    .attr( "width", w )
                    .attr( "height", h )
                    .style('background-color', 'black');

            d3.json("/data/streets.json", function(json){
                streets = json; //copy data from json to streets
                console.log(json); // output json to console

                var link = svg.selectAll(".link")
                                .data([streets])
                                .enter().append("line")
                                .attr("class", "link")
                                .style('stroke','green')
                                .style("stroke-width", 5);
                                
                                link.attr("x1", function(d) { console.log(d); return d.x1; })
                                    .attr("y1", function(d) { return d.y1; })
                                    .attr("x2", function(d) { return d.x2; })
                                    .attr("y2", function(d) { return d.y2; });
    
            });
            }
        </script>
    </body>
</html>

D3 uses data binding in the enter/update/exit cycle. One item in the data array is intended to correspond to one element in the DOM (disregarding parent/child here relationships for simplicity).

Your data array is as follows [streets] - this is an array with one item (another array, streets ). As the enter cycle is intended to create one element in the DOM for every item in the data array for which there is no corresponding element already (in your case, elements that match the selector .link ). This can only create one element in the DOM - your data array has only one item in it: streets .

Instead of nesting streets in an array, just pass it to .data() directly: for every item in it, you wish to draw one line. Now we'll have one item in the data array correspond to one element in the DOM - as intended.

The datum for each element (an array itself) will be an item from your data array, eg:

[
    {
        "x": 16.7380009,
        "y": 18.6959991
    },
    {
        "x": 17.6599998,
        "y": 18.7119999
    }
]

This is what you access with .attr("...",function(d) {...})

It doesn't have x1, x2, y1, or y2 properties, so you can't use:

function(d) { return d.x1; }

However, you can use:

function(d) { return d[0].x; }

Here's a subset of your data at work in a slightly modified example (upgraded to d3v5 - there are breaking differences between v3 and 4/5/6; however, this particular snippet will work as is for v3 .

 var streets; // declare global variable var w = 160; // width of svg var h = 160; // height of svg var svg = d3.select("body") .append("svg") .attr( "width", w ) .attr( "height", h ) .style('background-color', 'black') streets = [ [ { "x": 126.7380009, // modified "y": 128.6959991 // modified }, { "x": 17.6599998, "y": 18.7119999 } ], [ { "x": 14.4619999, "y": 18.6550007 }, { "x": 16.7380009, "y": 18.6959991 } ], [ { "x": 12.7938805, "y": 18.6161308 }, { "x": 14.4619999, "y": 18.6550007 } ] ] var link = svg.selectAll(".link") .data(streets) .enter().append("line") .attr("class", "link") .style('stroke','green') .style("stroke-width", 5) .attr("x1", function(d) { return d[0].x; }) .attr("y1", function(d) { return d[0].y; }) .attr("x2", function(d) { return d[1].x; }) .attr("y2", function(d) { return d[1].y; });
 svg { border: 1px solid black; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM