I'm creating a map using two data files. One data file has the latitude and longitude of locations. The other data file has the population of those locations. Both have a column with the location code. So long as both files contain all of the same codes, this works. However, my population dataset only has information for some of the location codes. So I'm getting an error:
test.html:75 Uncaught TypeError: Cannot read property 'pop' of undefined
How can I avoid this error?
My full code is below.
Here is also a Plunker with all of the CSVs/files: https://plnkr.co/edit/pvPv2To72OiSOPaz
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.states {
fill: #eee;
stroke: #999;
stroke-linejoin: round;
}
</style>
<body>
<div class="g-chart"></div>
</body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/geo-albers-usa-territories@0.1.0/dist/geo-albers-usa-territories.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/queue-async/1.0.7/queue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.19/topojson.min.js"></script>
<script>
var margin = { top: 10, left: 10, bottom: 10, right: 10 },
width = window.outerWidth,
width = width - margin.left - margin.right,
mapRatio = .5,
height = width * mapRatio;
var projection = geoAlbersUsaTerritories.geoAlbersUsaTerritories()
.scale(width)
.translate([width / 2, height / 2]);
var path = d3.geoPath()
.projection(projection);
var map = d3.select(".g-chart").append("svg")
.style('height', height + 'px')
.style('width', width + 'px')
.call(d3.zoom().on("zoom", function () {
map.attr("transform", d3.event.transform)
d3.selectAll()
}))
.append("g");
queue()
.defer(d3.json, "us.json")
.defer(d3.csv, "locations.csv")
.defer(d3.csv, "populations.csv")
.await(ready);
function ready(error, us, loc, pop) {
if (error) throw error;
const data = pop.sort((a, b) => +b.population - +a.population)
console.log('populations', data)
const locations = loc.filter(d => d.latitude !== '' && d.longitude !== '')
const maxPop = d3.max(data, d => +d.population)
console.log('maxPop', maxPop)
const newDict = {};
data.forEach(function (d) {
d.population = +d.population;
newDict[d.location_code] = { pop: d.population };
})
map.append("g")
.attr("class", "states")
.selectAll("path")
.data(topojson.feature(us, us.objects.states).features)
.enter().append("path")
.attr("d", path);
const location_data = locations.sort((a, b) => newDict[b.code].pop - newDict[a.code].pop)
location_data.forEach(function (d) {
d.pop = newDict[d.code].pop
})
console.log('location_data', location_data)
map.append('g')
.attr('class', 'location')
.selectAll("circle")
.data(location_data)
.enter()
.append("circle")
.attr("cx", function (d) {
return projection([d.longitude, d.latitude])[0];
})
.attr("cy", function (d) {
return projection([d.longitude, d.latitude])[1];
})
.attr('r', 10)
.style("fill", "navy")
.style("opacity", 0.5)
}
from Create map that combines data from two files with common column - but data doesn't match one to one
No comments:
Post a Comment