d3.js 地图:使用 geojson 文件和 CSV 数据
d3.js maps: using a geojson file AND CSV data
我无法在 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 and the data is here: 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。
感谢您的帮助!
正在加载数据
Promise.all()
returns 一系列已兑现的承诺。要使用它们,您可以直接从值数组访问它们。
一件方便的事情是 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 中获取地图以响应 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 and the data is here: 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。
感谢您的帮助!
正在加载数据
Promise.all()
returns 一系列已兑现的承诺。要使用它们,您可以直接从值数组访问它们。
一件方便的事情是 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
属性 中有点麻烦,但我假设您有颜色以外的其他数据。如果没有,请随意将颜色直接附加到对象。