我使用topojson绘制带有D3js的世界地图。我相信这很好用。但是,当我尝试将纬度/经度点投影到地图上时,投影功能正在返回" NaN"对于具有负值的点,对正在工作的点的投影远离国家/地区在世界地图上的位置。
这是我读过的数据: 资产/数据/ gcf.csv
Coords,Country,Frequency
"[38.9597594, 34.9249653]",Turkey,1
"[61.0666922, -107.9917071]",Canada,3
"[52.5001698, 5.7480821]",Netherlands,1
"[42.6384261, 12.674297]",Italy,1
"[39.7837304, -100.4458825]",United States,69
"[59.6749712, 14.5208584]",Sweden,1
"[35.000074, 104.999927]",China,5
"[64.6863136, 97.7453061]",Russian Federation,2
"[36.5748441, 139.2394179]",Japan,1
的index.html
<div id="worldmap"></div>
<script src="../assets/js/graphs/map.js"></script>
资产/ JS /图形/ map.js
var width = 960;
var height = 500;
// set projection
var projection = d3.geo.mercator();
// create path variable
var path = d3.geo.path()
.projection(projection);
// Define the div for the tooltip
var div = d3.select("body").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
d3.json("https://unpkg.com/world-atlas@1/world/110m.json", function(error1, topo) {
if(error1) console.log("Error: topo json not loaded.");
d3.csv("../assets/data/gcf.csv", function(error2, data) {
if(error2) console.log("Error: Coord/frequency data not loaded.");
countries = topojson.feature(topo, topo.objects.countries).features;
projection
.scale(width / 2 / Math.PI)
.translate([(width / 2)-30, (height / 2)+50]);
data.forEach(function(d) {
// + symbol convert from string representation of a number to an actual number
d.Frequency = +d.Frequency;
d.Coords = d.Coords.replace(/[\[\]"]+/g, '');
d.Coords = d.Coords.split(',');
d.Coords = d.Coords.map(x => parseFloat(x));
d.Country = d.Country;
console.log("Country:", d.Country, ". Projection: ", projection(d.Coords)[0], projection(d.Coords)[1]);
});
// create svg variable
var svg = d3.select("#worldmap").append("svg")
.attr("width", width)
.attr("height", height);
svg.append("rect")
.attr("width", "100%")
.attr("height","100%")
.attr("fill","#A2E8E8");
// add countries from topojson
svg.selectAll("path")
.data(countries).enter()
.append("path")
.attr("class", "feature")
.style("fill", "#71945A")
.attr("d", path);
// put boarder around countries
svg.append("path")
.datum(topojson.mesh(topo, topo.objects.countries, function(a, b) { return a !== b; }))
.attr("class", "mesh")
.attr("d", path);
aa = [38.9597594, 34.9249653];
// add circles to svg
svg.selectAll("circle")
.data(data).enter()
.append("circle")
.attr("r", function(d) {
return d.Frequency === 1 ? d.Frequency* 10 : d.Frequency / 2
})
.attr("transform", function(d) {
return "translate(" + projection([
(d.Coords[0]),
(d.Coords[1])
]) + ")";
})
.attr("fill", "red")
.on("mouseover", function(d) {
div.transition()
.duration(200)
.style("opacity", .9);
div .html(d.Country)
.style("left", (d3.event.pageX) + "px")
.style("top", (d3.event.pageY - 28) + "px");
})
.on("mouseout", function(d) {
div.transition()
.duration(500)
.style("opacity", 0);
});
});
});
世界地图样式:
.feature {
fill: none;
stroke: grey;
stroke-width: 1px;
stroke-linejoin: round;
}
.mesh {
fill: none;
stroke: black;
stroke-width: 2px;
stroke-linejoin: round;
}
答案 0 :(得分:1)
您的纬度和经度相反 - d3 geoProjection采用[x,y]或[long,lat]格式的坐标。您正在为投影提供[lat,long]数组,但如果您切换下面的代码:
.attr("transform", function(d) {
return "translate(" + projection([d.Coords[0],d.Coords[1]]) + ")";
})
要:
.attr("transform", function(d) {
return "translate(" + projection([d.Coords[1],d.Coords[0]]) + ")";
})
您将获得所需的地图: