我使用 GeoJSON 数据制作了许多调查站点的地图,一切看起来都很好。我还设置了一个鼠标悬停命令,当鼠标悬停在该站点上时,该命令会突出显示该站点。
但是,我正在尝试创建一个工具提示,并在您将鼠标悬停时显示每个站点的名称。我似乎无法访问 GeoJSON 文件的属性部分来获取该数据,当我在控制台中签入时,它只是返回为“未定义”。
我已经在单独的 .html 文档中测试了 GeoJSON,并且在使用 - 直接引用 site_name 时能够访问 site_name
var siteNames = boundaries_json.features.map(function(d) {
return d.properties.site_name; // Access 'site_name' from 'properties'
});
因此,我认为我的问题与代码的鼠标悬停部分有关 -
g.selectAll("path.boundaries")
.data(boundaries_json.features)
.enter()
.append("path")
.attr("fill", "#ccc")
.attr('class', 'map')
.attr("d", geoPath)
.on("mouseover", function(event, d) {
d3.select(this)
.attr("fill", '#808080')
.attr("stroke", "#ff0000")
.attr("stroke-width", "0.3");
d3.select(this).raise();
d3.select("#tooltip")
.style("visibility", "visible")
.text(d.properties.site_name)
.style("top", (d3.event.pageY + 10) + "px")
.style("left", (d3.event.pageX + 10) + "px");
})
.on("mouseout", function(event, d) {
d3.select(this)
.attr("fill", "#ccc")
.attr("stroke", null)
.attr("stroke-width", null);
d3.select("#tooltip").style("visibility", "hidden");
});
我的 GeoJSON 是在 .js 文件中构建的,如下所示 -
var boundaries_json = {
"type": "FeatureCollection",
"name": "ypp_boundaries",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { "site_id": "ST", "site_name": "Stean Moor", "resp_person": "[PLACEHOLDER]", "region_id": "NID", "date_added": "2009-01-01", "area": 132 }, "geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -1.905702715935964, 54.122415089551261 ], [ -1.906621702930786, 54.122290229958068 ], [ -1.906660910431268, 54.122284903740969 ], [ -1.908899235808527, 54.121980752416206 ], [ -1.909164155646383, 54.121944733352379 ], etc etc
为什么我的工具提示无法访问和显示 site_name?
d3
,而您的某些代码则假设使用旧版本。
.on("mouseover", function(event, d) {
的方法签名(其中事件作为第一个参数传递)是“较新的”,但自 v5 以来,使用
d3.event
的方法签名并不存在。 有关 v6 中事件处理如何更改的详细信息,请参阅此处。 综上所述,这是针对最新 d3 版本 (v7.9) 运行的代码:
<!DOCTYPE html>
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.js"></script>
</head>
<body>
<div id="content">
<svg width="800px" height="400px">
<g class="map"></g>
</svg>
</div>
<div
id="tooltip"
style="position: absolute; border: 1px solid steelblue; visibility: hidden"
></div>
<script>
const boundaries_json = {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
site_name: 'Africa',
},
geometry: {
type: 'Polygon',
coordinates: [
[
[-6, 36],
[33, 30],
[43, 11],
[51, 12],
[29, -33],
[18, -35],
[7, 5],
[-17, 14],
[-6, 36],
],
],
},
},
{
type: 'Feature',
properties: {
site_name: 'Australia',
},
geometry: {
type: 'Polygon',
coordinates: [
[
[143, -11],
[153, -28],
[144, -38],
[131, -31],
[116, -35],
[114, -22],
[136, -12],
[140, -17],
[143, -11],
],
],
},
},
{
type: 'Feature',
properties: {
site_name: 'Timbuktu',
},
geometry: {
type: 'Point',
coordinates: [-3.0026, 16.7666],
},
},
],
};
const projection = d3
.geoEquirectangular()
.scale(200)
.translate([200, 150]);
const geoPath = d3.geoPath().projection(projection);
const g = d3.select('#content g.map');
g.selectAll('path.boundaries')
.data(boundaries_json.features)
.enter()
.append('path')
.attr('fill', '#ccc')
.attr('class', 'map')
.attr('d', geoPath)
.on('mouseover', function (event, d) {
d3.select(this)
.attr('fill', '#808080')
.attr('stroke', '#ff0000')
.attr('stroke-width', '0.3');
d3.select(this).raise();
d3.select('#tooltip')
.style('visibility', 'visible')
.text(d.properties.site_name)
.style('top', event.pageY + 10 + 'px')
.style('left', event.pageX + 10 + 'px');
})
.on('mouseout', function (event, d) {
d3.select(this)
.attr('fill', '#ccc')
.attr('stroke', null)
.attr('stroke-width', null);
d3.select('#tooltip').style('visibility', 'hidden');
});
</script>
</body>
</html>