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); }