d3 中地图行为的基准数据差异

Datum-Data difference in map behavior in d3

我是 d3js 的新手,正在尝试了解使用数据和数据将数据附加到元素之间的区别。我已经在网上阅读了一些 material,我想我在理论上理解发生了什么,但我仍然缺乏直观的理解。具体来说,我有一个案例,我正在使用 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 文件中指定了样式):

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

感谢您的帮助!

data()datum() 之间存在一些差异,但是对于 你的问题的范围 主要区别在于 data() 接受只有 3 件事:

  • 一个数组;
  • 一个函数;
  • 无(在这种情况下,它是 getter);

如你所见,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>