首页 > 解决方案 > d3中地图行为的基准数据差异

问题描述

我对 d3js 很陌生,并试图了解使用数据和基准将数据附加到元素之间的区别。我已经在网上阅读了相当多的材料,我想我理论上理解发生了什么,但我仍然缺乏直观的理解。具体来说,我有一个使用 topojson 创建地图的案例。我正在使用 d3js v7。

在第一个实例中,我有以下代码在 div 中创建地图(假设高度、宽度、投影等设置正确):

var svg = d3.select("div#map").append("svg")
    .attr("width", width)
    .attr("height", height)
    .attr("transform", "translate(" + 15 + "," + 0 + ")"); 

var path = d3.geoPath()
          .projection(projection);

var mapGroup = svg.append("g");

d3.json("json/world-110m.json").then(function(world){
  console.log(topojson.feature(world, world.objects.land))

  mapGroup.append("path") 
     .datum(topojson.feature(world, world.objects.land))
     .attr("class", "land") 
     .attr("d", path); 

});

topojson 功能的控制台日志如下所示: 在此处输入图像描述

并且地图很好(在css文件中指定了样式):在此处输入图像描述

但是,如果我将基准更改为数据,地图就会消失。我正在努力提高我对它是如何工作的理解,并且在阅读了我可以在网上找到的内容后,我有点挣扎。有人可以解释在这种情况下使用的数据和基准之间的区别以及为什么一个有效而另一个无效?

谢谢你的帮助!

标签: javascriptjsond3.jstopojson

解决方案


data()和之间有几个区别datum(),但对于您的问题范围,主要区别在于data()只接受 3 件事:

  • 数组;
  • 一个函数;
  • 什么都没有(在这种情况下,它是一个吸气剂);

如您所见,topojson.feature(world, world.objects.land)是一个对象。因此,您需要在data()这里使用的所有内容(同样,不是惯用的 D3,我只是在解决您的具体问题)是用数组包装它:

.data([topojson.feature(world, world.objects.land)])

这是您使用的代码data()

var svg = d3.select("div#map").append("svg")
  .attr("width", 500)
  .attr("height", 300)
  .attr("transform", "translate(" + 15 + "," + 0 + ")");

var path = d3.geoPath();

var mapGroup = svg.append("g");

d3.json("https://raw.githubusercontent.com/d3/d3.github.com/master/world-110m.v1.json").then(function(world) {

  const projection = d3.geoEqualEarth()
    .fitExtent([
      [0, 0],
      [500, 300]
    ], topojson.feature(world, world.objects.land));

  path.projection(projection);

  mapGroup.append("path")
    .data([topojson.feature(world, world.objects.land)])
    .attr("class", "land")
    .attr("d", path);

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<script src="https://unpkg.com/topojson@3"></script>
<div id="map"></div>


推荐阅读