【发布时间】:2021-04-09 07:33:59
【问题描述】:
我正在尝试创建一个简单的气泡图,该气泡图使用美国 DHS 数据绘制一个县的许多招生人数的经纬度对。我的 CSV 文件包含县名、经度、纬度、录取类型、录取类别、录取数量和原籍国。我创建了一些复选框,允许用户查看被美国录取的不同类别录取的气泡图。
我了解到,d3geoAlbersUsa 投影将美国地图投影在非洲海岸附近的 [0,0]。从下面的照片(请参阅 Imgur 链接)中,您可以看到我的点似乎绘制在正确的坐标上。但是,背景图是不可见的。当我使用 d3.geoMercator() 并将投影居中 [0,0] 时,我看到了地图。在这两种情况下,我都不知道如何让气泡出现在地图上。
我是 d3 的新手,所以我不知道该怎么做。如何使用带有 d3geoAlbersUsa 投影的长纬度坐标创建气泡图?感谢您的帮助。
这是我的 index.html:
var width = 750
var height = 750
// The svg
var svg = d3.select("#my_dataviz")
.append("svg")
.attr("width", width)
.attr("height", height)
// Map and projection
// Map and projection
// var projection = d3.geoMercator()
// //.center([-100, 30]) // GPS of location to zoom on
// .center([0, 0])
// .scale(200) // This is like the zoom
// .translate([ width/2, height/2 ])
var projection = d3.geoAlbersUsa()
//.center([0,0])
.scale([1000]) // This is like the zoom
.translate([width / 2, height / 2])
var data = d3.csv("sheet.csv", function(data) {
var markers = data.filter(function(d) {
if (
(d["MajorClassAdmission"] == "EmploymentPreference1st" ||
d["MajorClassAdmission"] == "EmploymentPreference2nd" ||
d["MajorClassAdmission"] == "EmploymentPreference3rd") &&
d["CountryofBirth"] == "Bangladesh" && d["Admissions"] != "D" && d["lon"] != "NA" && d["lat"] != "NA") {
return d;
}
})
//console.log(markers)
// Load external data and boot
//d3.json("projectedgeography.json", function(data){
d3.json("projectedgeography.geojson", function(data) {
//d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/world.geojson", function(data){
// Filter data
//data.features = data.features.filter( function(d){return d.properties.name=="USA"} )
//data.features = data.features.filter( function(d){return d.properties.name=="USA"} )
// Create a color scale
var color = d3.scaleOrdinal()
.domain(["EmploymentPreference1st", "EmploymentPreference2nd", "EmploymentPreference3rd"])
.range(["#402D54", "#D18975", "#8FD175"])
// Add a scale for bubble size
var size = d3.scaleLinear()
.domain([1, 100]) // What's in the data
.range([4, 50]) // Size in pixel
//var path = d3.geo.path().projection(projection)
//Draw the map
svg.append("g")
.selectAll("path")
.data(data.features)
.enter()
.append("path")
.style("stroke", "#black")
.style("opacity", .3)
//create a tooltip (hover information)
var Tooltip = d3.select("#my_dataviz")
.append("div")
.attr("class", "tooltip")
.style("opacity", 1)
.style("background-color", "white")
.style("border", "solid")
.style("border-width", "2px")
.style("border-radius", "5px")
.style("padding", "5px")
// Three function that change the tooltip when user hover / move / leave a cell
var mouseover = function(d) {
Tooltip.style("opacity", 1)
}
var mousemove = function(d) {
Tooltip
.html(d.CountyState + "<br>" + "long: " + d.lon + "<br>" + "lat: " + d.lat + "<br>" + "Admissions: " + d.Admissions)
.style("left", (d3.mouse(this)[0] + 10) + "px")
.style("top", (d3.mouse(this)[1]) + "px")
}
var mouseleave = function(d) {
Tooltip.style("opacity", 0)
}
// Add circles:
svg
.selectAll("myCircles")
.data(markers)
.enter()
.append("circle")
.attr("class", function(d) {
return (d.MajorClassAdmission)
})
.attr("cx", function(d) {
return projection([d.lon, d.lat])[0]
})
.attr("cy", function(d) {
return projection([d.lon, d.lat])[1]
})
.attr("r", function(d) {
return d.Admissions
})
.style("fill", function(d) {
return color(d.MajorClassAdmission)
})
.attr("stroke", function(d) {
return color(d.MajorClassAdmission)
})
.attr("stroke-width", 3)
.attr("fill-opacity", .4)
.on("mouseover", mouseover)
.on("mousemove", mousemove)
.on("mouseleave", mouseleave)
// This function is gonna change the opacity and size of selected and unselected circles
function update() {
// For each check box:
d3.selectAll(".checkbox").each(function(d) {
cb = d3.select(this);
group = cb.property("value")
//console.log(group)
// If the box is check, I show the group
if (cb.property("checked")) {
//console.log("checked")
svg.selectAll("." + group).transition().duration(1000).style("opacity", 1).attr("r", function(d) {
return d.Admissions
})
// Otherwise I hide it
} else {
//console.log("unchecked")
svg.selectAll("." + group).transition().duration(1000).style("opacity", 0).attr("r", 0)
}
})
}
// When a button change, I run the update function
d3.selectAll(".checkbox").on("change", update)
// And I initialize it at the beginning
update()
})
})
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<style>
.circle:hover {
stroke: black;
stroke-width: 4px;
}
.legend circle {
fill: none;
stroke: #ccc;
}
.legend text {
fill: #777;
font: 10px sans-serif;
text-anchor: middle;
}
</style>
<!-- Load d3.js and the geo projection plugin -->
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://d3js.org/d3-geo-projection.v2.min.js"></script>
<script src="https://d3js.org/queue.v1.min.js"></script>
<!-- <script src="http://d3js.org/d3.geo.projection.v0.min.js"></script> optional, depending on projection -->
<h1>LPR Top 200 Bangladesh</h1>
<!-- Button -->
<div>
<input type="checkbox" class="checkbox" value="EmploymentPreference1st" checked><label>Employment Preference 1</label>
<input type="checkbox" class="checkbox" value="EmploymentPreference2nd" checked><label>Employment Preference 2</label>
<input type="checkbox" class="checkbox" value="EmploymentPreference3rd" checked><label>Employment Preference 3</label>
</div>
<!-- Create an element where the map will take place -->
<!-- <svg id="my_dataviz" width="500" height="500"></svg> -->
<div id="my_dataviz"></div>
附件是我的数据截图以及使用 d3.geoMercator() 和 d3.geoAlbersUsa() 时气泡图的样子
截图如下:https://imgur.com/gallery/dRghqAf
编辑:看起来我使用了错误的 geojson。我最初是从 US Census 下载 shapefile 并使用 Mapshaper 转换为 geojson 文件。使用那个geojson,我使用了一个投影应用程序来创建一个带有geoalbersUsa 投影的geojson。实际上,我在已经转换为该投影的 geojson 上使用了 d3.geoAlbersUsa()。我误解了 geoAlbersUsa() 的工作原理。使用 Mapshaper 的原始 geojson,我得到了我正在寻找的地图:https://imgur.com/gallery/9sj68SM
【问题讨论】:
-
通常“图书馆”会为您计算十进制度数的投影。不是这样吗?
-
@GetSet 你能详细说明一下吗?如果我使用常规投影(geoMercator),坐标会显示在地图上
-
您的图像显示背景图块,但这不会出现在您的代码中。根据文件名,您似乎也在使用投影几何。您能否澄清我们所有的源数据是否都是经纬度对?此外,您仅对如何绘制点以外的特征进行了评论,您能否确认用于绘制这些特征的投影和路径?如果使用瓦片或其他背景栅格数据,您能说明一下您是如何做到的吗?
-
如果您可以共享 csv 的 sn-p(不是屏幕截图)和 geojson 文件,那么演示如何在地图中将两者结合起来是最简单的。
标签: javascript svg d3.js data-visualization geo