使用坐标在 d3.js 中的 json 文件创建多行

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

我正在尝试绘制多条线,这些线将使用位于此处的 json 文件中的坐标创建地图。

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

我可以创建 svg,但无法显示线条。下面是我到目前为止用来创建 svg 并尝试绘制线条的代码。这是我第一次使用 d3 和 JSON 文件,因此不胜感激。

<!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 在enter/update/exit 循环中使用数据绑定。数据数组中的一项旨在对应于 DOM 中的一个元素(为简单起见,此处忽略 parent/child 关系)。

您的数据数组如下[streets] - 这是一个包含一项的数组(另一个数组,streets)。由于输入循环旨在为数据数组中的每个项目创建 DOM 中的一个元素,其中还没有相应的元素(在您的情况下,与选择器 .link 匹配的元素)。这只能在 DOM 中创建一个元素 - 您的数据数组中只有一项:streets.

不是将 streets 嵌套在数组中,而是直接将其传递给 .data():对于其中的每个项目,您希望绘制一条线。现在我们将数据数组中的一项对应于 DOM 中的一个元素 - 正如预期的那样。

每个元素(数组本身)的数据将是您的数据数组中的一项,例如:

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

这是您使用 .attr("...",function(d) {...})

访问的内容

它没有 x1、x2、y1 或 y2 属性,因此您不能使用:

function(d) { return d.x1; }

但是,您可以使用:

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

这是您工作中数据的一个子集,示例略有修改(已升级到 d3v5 - v3 和 4/5/6 之间存在重大差异;但是,此特定代码段将按原样工作对于 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>