【问题标题】:Datum-Data difference in map behavior in d3d3中地图行为的基准数据差异
【发布时间】:2021-11-21 16:36:38
【问题描述】:

我对 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文件中指定了样式):

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

感谢您的帮助!

【问题讨论】:

    标签: javascript json d3.js topojson


    【解决方案1】:

    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>

    【讨论】:

    • 很有意思,谢谢你的回答!所以 - 数据之所以有效,是因为只有一个对象,而且基本上只有一个“路径”元素可以绑定,对吧?当您将对象包装在一个数据数组中时,该数组仍然有一个数据。我理解对吗?谢谢!