d3.js 地图:使用 geojson 文件和 CSV 数据

Posted

技术标签:

【中文标题】d3.js 地图:使用 geojson 文件和 CSV 数据【英文标题】:d3.js maps: using a geojson file AND CSV data 【发布时间】:2020-07-19 20:33:35 【问题描述】:

我无法在 d3.js 中获取地图以响应 csv(或 tsv)中保存的数据。我正在使用 geojson 文件,并成功地显示了伊利诺伊州的县界。但是,地图不响应 tsv 文件中的数据。

我怀疑问题可能出在我将数据 - data() - 绑定到路径的位置。马克·博斯托克使用 .data(topojson.feature(us, us.objects.counties).features),但这是基于我不完全理解的函数结构:function ready([us]) 我怀疑有问题的代码行是.data(values[0].features, values[population])

这是我的全部代码,它生成了一张伊利诺伊州县的地图,但没有其他内容。为了排除故障,我已将数据剥离为填充颜色。

我的 json 文件在这里:https://raw.githubusercontent.com/cyrusobrien/cyrusobrien/master/documents/illinois_ods.geojson,数据在这里:https://raw.githubusercontent.com/cyrusobrien/cyrusobrien/master/html/countytest.tsv

很抱歉没有在 jfiddle 上发帖,但是(我认为)我在那里遇到了域冲突问题。

<html lang="en">
<head>
    <meta charset="utf-8">
    <title>My map</title>
    <script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
    <style></style>
</head>
<body>
<div id="container" class="svg-container"></div>
<script type="text/javascript">
    var w = 900;
    var h = 500;
    var svg = d3.select("div#container").append("svg").attr("preserveAspectRatio", "xMinYMin meet").style("background-color","#c9e8fd")
        .attr("viewBox", "0 0 " + w + " " + h)
        .classed("svg-content", true);

    // load data

    var population = d3.map();


    var promises = [
        d3.json("/documents/illinois_ods.geojson"),
        d3.tsv("/html/countytest.tsv", function(d)  population.set(d.NAME, +d.color); )];



    var projection = d3.geoMercator().translate([w/2, h/2]).scale(2900).center([-89.3985,40.6331]);
    var path = d3.geoPath().projection(projection);

//draw map
    Promise.all(promises).then(function(values)
        svg.selectAll("path")
            .data(values[0].features, values[population])
            .enter()
            .append("path")
            .attr("d", path)
            .attr("fill",function (d) d.color = population.get(d.NAME); )
    );

</script>
</body>
</html>

如果相关,我会在本地机器上使用 webstorm 和 jekyll 运行它。

感谢您的帮助!

【问题讨论】:

【参考方案1】:

加载数据

Promise.all() 返回一个已履行承诺的数组。要使用它们,您可以直接从 values 数组中访问它们。

一个方便的做法是array destructuring:这就是 Bostock 对他的function ready([us]) 所做的事情。在这种情况下,您可以执行以下操作:

Promise.all(promises).then(function([illinois, data])
    enter code here
);

处理数据

在您的代码中,您似乎正在尝试对两个数据集同时使用data(),这在 D3 中不起作用。我们可以通过循环合并两个数据集,在 GeoJSON 中按名称查找伊利诺伊州的相关“部分”,并附加相关数据。

之后,您只操作一个数据:已合并的illinois 数据。

const parts = illinois.features
parts.forEach(geoJsonObject => 
  const linkedData = data.find(d => d === geoJsonObject.name)
  geoJsonObject.properties.data = linkedData
)
// .. use illinois, access data with properties.data:
svg.selectAll("path")
  .data(illinois.features)
  .enter()
  .append("path")
  .attr("d", path)
  .attr("fill", d => d.properties.data.color)

现在将所有内容都放在data 属性中有点笨拙,但我假设您还有除颜色之外的其他数据。如果没有,请随意将颜色直接附加到对象。

【讨论】:

以上是关于d3.js 地图:使用 geojson 文件和 CSV 数据的主要内容,如果未能解决你的问题,请参考以下文章

班加罗尔geojson地图与d3 js

d3.js地图图表绘制矩形

D3.js 地理

GeoJson 世界数据库 [关闭]

使用 D3.js 仅渲染 topojson 地图的一部分

使用d3.js调用地图api 进行数据可视化