我正在遵循规范的“Let’s Make a Map”教程 - 但为了增加趣味我将其与one about Germany融合 - 所以我正在使用略有不同的数据。
到目前为止,事情已经完成 - barring this minor hiccup - 但现在我来到了“#Displaying Places”这一部分,你应该在地图上显示城市的名字。
问题出现在以下几行:
.text(function(d) {
if (d.properties.name!=="Berlin" &&
d.properties.name!=="Bremen"){
//for some reason this is undefined
console.log(d.properties.name);
return d.properties.name;
}
})
console.log(d.properties.name);
的值总是未定义的,我无法找出原因!
我想这是因为name
超出了d
的范围 - 但我不知道如何修复它。 是吗?如果是这样 - 如何解决它?如果不是 - 真正的问题是什么?
这是我的代码看起来像 - 它非常简洁:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.subunit{fill:#fff;}
.subunit.Nordrhein-Westfalen{ fill: #aba; }
.subunit.Baden-Württemberg{ fill: #bab; }
.subunit.Hessen{ fill: #bcb; }
.subunit.Niedersachsen{ fill: #cbc; }
.subunit.Thüringen{ fill: #cdc; }
.subunit.Hamburg{ fill: #dcd; }
.subunit.Schleswig-Holstein{ fill: #ded; }
.subunit.Rheinland-Pfalz{ fill: #ede; }
.subunit.Saarland{ fill: #efe; }
.subunit.Sachsen-Anhalt{ fill: #fef; }
.subunit.Brandenburg{ fill: #aaa; }
.subunit.Mecklenburg-Vorpommern{ fill: #bbb; }
.subunit.Bayern { fill: #ccc; }
.subunit.Sachsen { fill: #ddd; }
.subunit.Bremen { fill: #eee; }
.subunit.Berlin { fill: #fff; }
.subunit-boundary {
fill: none;
stroke: #777;
stroke-dasharray: 2,2;
stroke-linejoin: round;
}
.place,
.place-label {
fill: #444;
font-size:14px;
}
text {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 20px;
pointer-events: none;
}
</style>
<body>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script>
var width = 960,
height = 1160;
var projection = d3.geo.mercator()
.center([10.5, 51.35])
.scale(3000)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
d3.json("de.json", function(error, de) {
//colouring the different subunits
svg.selectAll(".subunit")
.data(topojson.feature(de, de.objects.subunits).features)
.enter().append("path")
.attr("class", function(d) {
// console.log(d.properties.name);
return "subunit " + d.properties.name;
})
.attr("d", path);
//adding a border to the states
svg.append("path")
.datum(topojson.mesh(de, de.objects.subunits, function(a,b) {
if (a!==b ||
a.properties.name === "Berlin"||
a.properties.name === "Bremen"){
var ret = a;
}
return ret;
}))
.attr("d", path)
.attr("class", "subunit-boundary");
// add small black dots for populated places
svg.append("path")
.datum(topojson.feature(de, de.objects.places))
.attr("d", path)
.attr("class", "place");
//trying to display names of cities
svg.selectAll(".place-label")
.data(topojson.feature(de, de.objects.places).features)
.enter().append("text")
.attr("class", "place-label")
.attr("transform", function(d) {
//small test
//console.log( "translate(" + projection(d.geometry.coordinates) + ")" );
return "translate(" + projection(d.geometry.coordinates) + ")";
})
.attr("dy", ".35em")
.text(function(d) {
if (d.properties.name!=="Berlin" &&
d.properties.name!=="Bremen"){
//for some reason this is undefined
console.log(d.properties.name);
return d.properties.name;
}
})
.attr("x", function(d) {
return d.geometry.coordinates[0] > -1 ? 6 : -6;
})
.style("text-anchor", function(d) {
return d.geometry.coordinates[0] > -1 ? "start" : "end";
});
});
</script>
修改
预期
实际
答案 0 :(得分:4)
在.topojson中你有两个部分:
您可以通过以下方式访问第一个集合:
de.objects.subunits
第二个收集通过:
de.subunits.places
将文件加载到两个不同的变量后使用它:
d3.json("de.json", function(error, de) {
var counti = topojson.feature(de, de.objects.subunits)
var places = topojson.feature(de, de.objects.places)
然后引用内容添加.features
.data(counti.features) // <-- to draw your paths and get the .name: München
或
.data(places.features) // <-- to draw the circles for the cities: "coordinates": [11.573039376427117, 48.131688134368815]
Mike的topojson有:
{
"type": "Feature",
"properties": {
"name": "Ayr"
},
"geometry": {
"type": "Point",
"coordinates": [
-4.617021378468872,
55.44930882146421
]
}
你有:
{
"type": "Feature",
"properties": {},
"geometry": {
"type": "Point",
"coordinates": [
11.573039376427117,
48.131688134368815
]
}
Mike的点属性如下所示:
和点坐标
您的观点属性:
解决方案:
正确的方式
简单方法
现在您正确删除了一列(您有重复的信息)
答案 1 :(得分:1)
@Klaujesi很好地解释了原因。
我只是想解决这个问题。
由于功能内部没有属性,因此您可以从de.objects.subunits
获取属性,如下所示。
.text(function(d, i) {
//here i is the index of the place.
//de.objects.subunits.geometries[i].properties will give you the name that you are looking for.
d.properties = de.objects.subunits.geometries[i].properties;
if (d.properties.name!=="Berlin" &&
d.properties.name!=="Bremen"){
//for some reason this is undefined
console.log(d);
return d.properties.name;
}
})
工作代码here