var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return d.NAME+ ': '+
d.murder +' ('+ Math.round(d.murder_rate)+' per 100k)'+
'
2015 Population: '+ d.pop_2015+ '
';
});
var svg = d3.select('.svg-container').append('svg')
.attr('xmlns', 'http://www.w3.org/2000/svg')
.attr('version', '1.1')
.attr('viewBox', '0 0 900 500')
.attr('preserveAspectRatio', 'xMidYMid meet');
svg.call(tip);
var projection = d3.geoAlbersUsa();
var path = d3.geoPath().projection(projection);
d3.queue()
.defer(d3.csv, 'cities-over-250k.csv')
.defer(d3.json, 'us-states-simplified.json')
.defer(d3.csv, 'crime-in-us-2015.csv')
.await(dataReady);
var _cities = {}, _states = {}, _crime = {};
const color = d3.scaleThreshold()
.domain([1,4,8,15,20,30,40,50,60])
.range([
'rgb(255,245,240)',
'rgb(254,224,210)',
'rgb(252,187,161)',
'rgb(252,146,114)',
'rgb(251,106,74)',
'rgb(239,59,44)',
'rgb(203,24,29)',
'rgb(165,15,21)',
'rgb(103,0,13)',
]);
function dataReady(error, cities, states, crime) {
if (error) throw error;
_crime = crime;
_cities = cities;
_states = states;
cities.map(function (row) {
var crimeCity = crime.find(function (item) {
return row.NAME === item.city;
});
if (crimeCity) {
row.pop_2015 = crimeCity.pop_2015;
row.murder = crimeCity.murder;
row.murder_rate = crimeCity.murder_rate;
}
return row;
});
renderMap(_cities, _states, _crime);
}
function drawMapCircles(cities) {
var circleGroup = svg.selectAll('circle')
.data(cities)
.enter()
.append('g')
.attr('transform', function(d) {
return 'translate('+ projection([d.longitude, d.latitude])+')';
})
.attr('class', 'city');
circleGroup
.append('circle')
.style('fill', d => color(d.murder_rate))
.style("stroke", "grey")
.style('fill-opacity', .8)
.attr('r', function (d) {
return d.murder_rate ? d.murder_rate * 0.5 : 0;
})
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
.append('title')
.text(function(d) {
return d.NAME+ ' -'+
'\nMurders: '+d.murder+' ('+Math.round(d.murder_rate)+' for every 100k),'+
'\n2015 Population: '+ d.pop_2015;
});
}
function renderMap(cities, states, crime) {
svg.selectAll('*').remove(); // clear for re-render
cities = cities.filter(function(d) {
return projection([d.longitude, d.latitude]);
});
svg.selectAll('.states')
.data(topojson.feature(states, states.objects.states).features)
.enter()
.append('path')
.attr('class', 'states')
.attr('d', path)
drawMapCircles(cities);
}