所以,老师要求我们编写一个 d3 程序,绘制英国地图并根据给定的提要绘制城镇,我编写了代码,但地图无法加载。
我使用了 d3js,但我只得到了重新加载按钮和我想要多少个城镇的选择。 你能帮我找出问题出在哪里吗?
这是我编写的代码
<!DOCTYPE html>
<html>
<head>
<title>UK Towns Map</title>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js">
</script>
<style>
.town-circle {
fill: blue;
opacity: 0.7;
}
</style>
</head>
<body>
<div id="tooltip"
style="position: absolute; visibility: hidden; background: white; padding: 5px; border: 1px solid #ccc;"></div>
<h1>UK Towns Map</h1>
<button id="reloadButton">Reload Data</button>
<input type="range" id="townCountSlider" min="1" max="500" value="50">
<span id="townCountLabel">Towns: 50</span>
<div id="mapContainer"></div>
<script>
const mapWidth = 800;
const mapHeight = 600;
const svg = d3.select("#mapContainer")
.append("svg")
.attr("width", mapWidth)
.attr("height", mapHeight);
function drawUKMap() {
const projection = d3.geoIdentity().scale(2000).translate([mapWidth / 2, mapHeight / 2]);
const path = d3.geoPath().projection(projection);
d3.json("https://raw.githubusercontent.com/janasayantan/datageojson/master/world.json").then(function (uk) {
const ukMap = svg.append("g");
ukMap.selectAll("path")
.data(uk.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "lightgray")
.attr("stroke", "white");
});
}
function plotTowns(townData) {
svg.selectAll(".town-circle").remove();
svg.selectAll(".town-circle")
.data(townData)
.enter()
.append("circle")
.attr("class", "town-circle")
.attr("cx", (d) => d.longitude)
.attr("cy", (d) => d.latitude)
.attr("r", (d) => Math.sqrt(d.population) * 0.01)
.on("mouseover", function (d) {
tooltip.style("visibility", "visible")
.html(d.name)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px");
})
.on("mousemove", function (d) {
tooltip.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px");
})
.on("mouseout", function () {
tooltip.style("visibility", "hidden");
})
.transition()
.duration(1000) // Animation duration in milliseconds
.attr("r", 20); // Final circle radius
};
function loadData() {
const townCount = document.getElementById("townCountSlider").value;
document.getElementById("townCountLabel").textContent = `Towns: ${townCount}`;
d3.json(`http://34.38.72.236/Circles/Towns/${townCount}`)
.then(function (data) {
drawUKMap();
plotTowns(data);
})
.catch(function (error) {
console.error("Error loading data:", error);
});
}
loadData();
d3.select("#reloadButton").on("click", loadData);
d3.select("#townCountSlider").on("input", loadData);
</script>
</body>
</html>
我提出的第一个建议是将您的承诺更改为回调。下面的函数代码是我的第一个建议:
function drawUKMap(callback) {
const projection = d3.geoIdentity().scale(4).translate([mapWidth / 2, mapHeight / 2]);
const path = d3.geoPath().projection(projection);
d3.json("https://raw.githubusercontent.com/janasayantan/datageojson/master/world.json", function (error, uk) {
if (error) return callback(error);
const ukMap = svg.append("g");
ukMap.selectAll("path")
.data(uk.features)
.enter()
.append("path")
.attr("d", path)
.attr("fill", "lightgray")
.attr("stroke", "white");
callback(null);
});
}
具体来说,交换这个:
d3.json("https://raw.githubusercontent.com/janasayantan/datageojson/master/world.json").then(function (uk) {
为此:
d3.json("https://raw.githubusercontent.com/janasayantan/datageojson/master/world.json", function (error, uk) {
if (error) return callback(error);
我还建议将比例从 2000 降低到 4。希望这会有所帮助。