Javascript 访问topojson对象以更改d3.js中的地图国家属性

Javascript 访问topojson对象以更改d3.js中的地图国家属性,javascript,d3.js,topojson,Javascript,D3.js,Topojson,我正在构建一个web应用程序来显示世界各国之间的不同趋势和统计数据。使用d3,我能够加载topojson文件并投影世界地图 matchPath函数用于将路径数据与countryStatistics进行匹配,以便在鼠标悬停某个国家时显示 function matchPath(pathId){ //to see id property of country currently being hovered over console.log("pathID:" + pathId)

我正在构建一个web应用程序来显示世界各国之间的不同趋势和统计数据。使用d3,我能够加载topojson文件并投影世界地图

matchPath函数用于将路径数据与countryStatistics进行匹配,以便在鼠标悬停某个国家时显示

function matchPath(pathId){
    //to see id property of country currently being hovered over
  console.log("pathID:" + pathId)
    //loop through all countryStatistics and return the country with matching id number
  for(var i = 0; i < countryStatistics.length; i++){
    if(pathId == countryStatistics[i].idTopo){
      return countryStatistics[i];
    }
  }
}
问题是:这是可行的,但只在一个方向上。我可以从每个路径获取我的统计数据。。。但我无法根据数据访问和操作各个路径

我想做的是,有一个按钮,可以从countryStatistics中选择某个属性,构建域/范围比例,并根据数据值设置颜色渐变。我一直坚持的步骤是获取stat数据和path数据接口

我看到两种可能的解决方案

1:有一种方法可以在渲染期间将地形路径数据连接到统计数据,我可以调用函数重新绘制sgv

2:我构建了一个包含所有路径数据和统计数据的新对象。在这种情况下,我是否可以取出topojson.objects.countries数据并忽略其余数据

我应该如何做到这一点?如果有任何建议,下一步将不胜感激


我在这个项目中所处的位置

TopoJSON是一个非常强大的工具。它有自己的CLI命令行界面来生成自己的TopoJSON文件

该CLI允许您使用要合并的拓扑和数据创建唯一的文件

尽管它在v3.0.2版本中,但在我看来还是很清晰的。这是一个如何通过公共id属性将csv文件与json合并的示例

来自的简化版本https://bl.ocks.org/luissevillano/c7690adccf39bafe583f72b044e407e8 注意:正在使用TopoJSON CLI v1 topojson\ -e data.csv\ -id属性CUSEC,cod\ -p人口=+t1_1,面积=+Shape_面积 -o cv.json\ -cv/shapes/census.json 有一个data.csv文件和一个census.json文件,其中包含一个cod列和一个名为CUSEC的属性。 -使用-id属性可以指定合并中将使用哪些属性。 -使用property-p可以动态创建新属性

这是一个解决方案,您可以使用一个唯一的文件和一个唯一的请求来处理整个数据。这一最佳方案并不总是可能的,因此下一个解决方案可能是另一个

回到JavaScript,您可以创建一个新变量,该变量可以通过以下方式通过公共属性访问。将您的数据转换为以下格式:

// countryStatistics
{
  "idTopo": "004",
  "country": "Afghanistan",
  "countryCode": "afg",
  // ..
},
以及您的TopoJSON文件的结构:

{"type":"Polygon","arcs":[[0,1,2,3,4,5]],"id":"004"},
{"type":"MultiPolygon","arcs":[[[6,7,8,9]],[[10,11,12]]],"id":"024"} // ...



[
    004:{
      "idTopo": "004",
      "country": "Afghanistan",
      "countryCode": "afg",
      //...
  },
    008: {
      //...
    }
]
这种情况的常见解决方案是创建可由该idTopo访问的数组变量:

然后,该变量将具有下一个结构:

{"type":"Polygon","arcs":[[0,1,2,3,4,5]],"id":"004"},
{"type":"MultiPolygon","arcs":[[[6,7,8,9]],[[10,11,12]]],"id":"024"} // ...



[
    004:{
      "idTopo": "004",
      "country": "Afghanistan",
      "countryCode": "afg",
      //...
  },
    008: {
      //...
    }
]
从这里,您可以通过其idTopo属性访问属性,如下所示:

dataById['004'] // {"idTopo":"004","country":"Afghanistan","countryCode":"afg" ...}
您可以决定遍历地形数据,并将这些属性添加到每个要素:

var countries = topojson
  .feature(data, data.objects.countries)
  .features.map(function(d) {
    d.properties = dataById[d.id];
    return d
  });
或者在需要时使用此阵列

// ...
.on("mouseover", function(d) {
  d3.select(this).classed("hovered", true);
  console.log(dataById[d.id]);
});

这似乎是朝着正确方向迈出的一大步。我现在在topojson对象中绑定了countryStatistics,可以在渲染期间调用它们。databyd被设置为其自己的idTopo属性,然后在初始topojson加载期间合并为属性的对象。明亮的现在开始以可视化方式绑定数据。