var svg_map; var path_map; var zoom_map; var g_map; var dist_map; var state_map; var loaded_map_data; var width_map = 588, height_map = 445; var active; $(function() { if(typeof d3 === 'undefined') { var preview_html = 'House Map'; preview_html += '

To see an interactive version of our map please upgrade your browser to one of the following:
Google Chrome | Mozilla Firefox | Microsoft Internet Explorer

'; $('#map_canvas').html(preview_html); } else { active = d3.select(null); generate_map(); } }); function generate_map() { var projection = d3.geo.albersUsa() .scale(810) .translate([(width_map / 2) + 5, (height_map / 2) - 40]); zoom_map = d3.behavior.zoom() .translate([0, 0]) .scale(1) .scaleExtent([1, 8]) .on("zoom", zoomed); path_map = d3.geo.path() .projection(projection); if(width_map >= height_map) { var percent_width = 100; var percent_height = (height_map / width_map) * percent_width; } else { var percent_height = 100; var percent_width = (width_map / height_map) * percent_height; } svg_map = d3.select("#map_canvas").append("svg") /*.attr("width", width_map) .attr("height", height_map)*/ .attr('viewBox', '0 0 ' + width_map + ' ' + height_map) .attr('preserveAspectRatio', 'xMidYMid meet') .attr('style', 'width: '+percent_width+'%; height: auto;') .on("click", stopped, true); $('#map_container').attr('style', 'background: none; height:auto;'); var map_id = $('#poll_id').val(); var preview = $('#poll_id').attr('data-preview'); var preview_suffix = ''; if(typeof preview !== 'undefined' && preview !== false && preview == '1') { preview_suffix = '_preview'; } var topojson_map = 'maps_d3_us_congress_2018.json'; console.log(parseInt(map_id)); if( parseInt(map_id) <= 32 ) { // has new PA districts topojson_map = 'maps_d3_us_congress_113.json'; } queue() .defer(d3.json, '/assets/scripts/maps_d3_us.json') .defer(d3.json, '/assets/scripts/'+topojson_map) .defer(d3.json, '/epolls/json/'+map_id+preview_suffix+'.js') //.defer(d3.tsv, '/assets/scripts/maps_d3_state_id_names.tsv') .await(ready); } function ready(error, us, congress, map_data) { if (error) return console.error(error); loaded_map_data = map_data; console.log(loaded_map_data); svg_map.append("rect") .attr("class", "map_background") .attr("width", width_map) .attr("height", height_map) .on("click", reset_zoom); svg_map.append("defs").append("path") .attr("id", "land") .datum(topojson.feature(us, us.objects.land)) .attr("d", path_map); svg_map.append("clipPath") .attr("id", "clip-land") .append("use") .attr("xlink:href", "#land"); g_map = svg_map.append("g"); g_map .attr("class", "districts") .attr("clip-path", "url(#clip-land)") .selectAll("path") /*.data(topojson.feature(us, us.objects.states).features)*/ .data(topojson.feature(congress, congress.objects.districts).features) .enter().append("path") .attr("d", path_map) .attr("class", function(d, i){ //console.log(d.id); var found_key = key_where(map_data.election.race, d.id, 'state_fips', 'district_number'); if(found_key !== false) { return simple_safe_url(map_data.election.race[found_key].status); } else { //console.log('id of false: ' + d.id); return d.id; } }) .attr("data-postal", function(d, i){ var found_key = key_where(map_data.election.race, d.id, 'state_fips', 'district_number'); //console.log('found_key: ' + found_key + ', d.id: '+d.id); if(found_key !== false) { //console.log('found') return map_data.election.race[found_key].region_key; } else { console.log('notfound: '+d.id); return 'ER'; } }) .attr("data-url", function(d, i){ var found_key = key_where(map_data.election.race, d.id, 'state_fips', 'district_number'); if(found_key !== false) { return map_data.election.race[found_key].url; } else { return ''; } }); state_map = svg_map.append("g"); state_map .attr("class", "states") .attr("clip-path", "url(#clip-land)") .selectAll("path") .data(topojson.feature(us, us.objects.states).features) /*.data(topojson.feature(congress, congress.objects.districts).features)*/ .enter().append("path") .attr("d", path_map) .attr("data-id", function(d, i){ return d.id; }) .on("click", clicked_state); dist_map = svg_map.append("path"); dist_map .attr("class", "district-boundaries") .datum(topojson.mesh(congress, congress.objects.districts, function(a, b) { return a !== b && (a.id / 1000 | 0) === (b.id / 1000 | 0); })) .attr("d", path_map); svg_map .call(zoom_map.event); // Hover Indicator $('.districts path').hover(function(e) { $('#map_tool_tip').html($(this).attr('data-postal')); $('#map_tool_tip').css('left', e.pageX+10); $('#map_tool_tip').css('top', e.pageY+10); $('#map_tool_tip').show(); }, function(e) { $('#map_tool_tip').hide(); $('#map_tool_tip').html(''); }); $('.states path').hover(function(e) { $('#map_tool_tip').html(id_to_state_name($(this).attr('data-id'))); $('#map_tool_tip').css('left', e.pageX+10); $('#map_tool_tip').css('top', e.pageY+10); $('#map_tool_tip').show(); }, function(e) { $('#map_tool_tip').hide(); $('#map_tool_tip').html(''); }); $('.districts path').click(function(e) { if($(this).attr('data-url').length > 0) { window.location = $(this).attr('data-url'); } }); $('#map_zoom_out').click(function(e) { reset_zoom(); }); } function key_where(arr, val, prop1, prop2) { for(var i = 0; i < arr.length; i++) { if( (arr[i][prop1] * 100) + (arr[i][prop2] * 1) == val + '') { return i; } } //console.log('arr'); //console.log(arr); //console.log('arr[270][prop1]: '+arr[270][prop1]); //console.log('arr[270][prop2]: '+arr[270][prop2]); return false; } function clicked_state(d) { if (active.node() === this) return reset_zoom(); active.classed("active", false); active = d3.select(this).classed("active", true); var bounds = path_map.bounds(d), dx = bounds[1][0] - bounds[0][0], dy = bounds[1][1] - bounds[0][1], x = (bounds[0][0] + bounds[1][0]) / 2, y = (bounds[0][1] + bounds[1][1]) / 2, scale = .7 / Math.max(dx / width_map, dy / height_map), translate = [width_map / 2 - scale * x, height_map / 2 - scale * y]; svg_map.transition() .duration(750) .call(zoom_map.translate(translate).scale(scale).event); state_map.selectAll("path").style("pointer-events", "none"); show_zoom_button(); show_district_squares(d.id); } function reset_zoom() { active.classed("active", false); active = d3.select(null); svg_map.transition() .duration(750) .call(zoom_map.translate([0, 0]).scale(1).event); state_map.selectAll("path").style("pointer-events", "auto"); hide_zoom_button(); hide_district_squares(); } function show_district_squares(id) { var html = ''; // Sort races by region_id loaded_map_data.election.race.sort(function(a,b) { return parseInt(a['region_id']) > parseInt(b['region_id']); }); for(var i = 0; i < loaded_map_data.election.race.length; i++) { var item = loaded_map_data.election.race[i]; if(item.state_fips == id) { html += '' + item.region_key + ''; } } $('#map_district_squares').html(html); var os = $('#map_canvas').offset(); $('#map_district_squares').css('left', os.left + 10); $('#map_district_squares').css('top', os.top + 35); $('#map_district_squares').show(); } function hide_district_squares() { //console.log(loaded_map_data); $('#map_district_squares').hide(); $('#map_district_squares').html(''); } function show_zoom_button() { $('#map_zoom_out').html('Zoom Out to Full Map'); var os = $('#map_canvas').offset(); $('#map_zoom_out').css('left', os.left + 10); $('#map_zoom_out').css('top', os.top + 10); $('#map_zoom_out').show(); } function hide_zoom_button() { $('#map_zoom_out').hide(); $('#map_zoom_out').html(''); } function zoomed() { dist_map.style("stroke-width", 0.8 / d3.event.scale + "px"); state_map.selectAll("path").style("stroke-width", 2 / d3.event.scale + "px"); g_map.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); dist_map.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); state_map.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"); } // If the drag behavior prevents the default click, // also stop propagation so we don’t click-to-zoom. function stopped() { if (d3.event.defaultPrevented) d3.event.stopPropagation(); } function simple_safe_url(str) { return str.split(' ').join('_').toLowerCase(); } function id_to_state_name(id) { states = { '1' : 'Alabama', '2' : 'Alaska', '4' : 'Arizona', '5' : 'Arkansas', '6' : 'California', '8' : 'Colorado', '9' : 'Connecticut', '10' : 'Delaware', '11' : 'Washington D.C.', '12' : 'Florida', '13' : 'Georgia', '15' : 'Hawaii', '16' : 'Idaho', '17' : 'Illinois', '18' : 'Indiana', '19' : 'Iowa', '20' : 'Kansas', '21' : 'Kentucky', '22' : 'Louisiana', '23' : 'Maine', '24' : 'Maryland', '25' : 'Massachusetts', '26' : 'Michigan', '27' : 'Minnesota', '28' : 'Mississippi', '29' : 'Missouri', '30' : 'Montana', '31' : 'Nebraska', '32' : 'Nevada', '33' : 'New Hampshire', '34' : 'New Jersey', '35' : 'New Mexico', '36' : 'New York', '37' : 'North Carolina', '38' : 'North Dakota', '39' : 'Ohio', '40' : 'Oklahoma', '41' : 'Oregon', '42' : 'Pennsylvania', '44' : 'Rhode Island', '45' : 'South Carolina', '46' : 'South Dakota', '47' : 'Tennessee', '48' : 'Texas', '49' : 'Utah', '50' : 'Vermont', '51' : 'Virginia', '53' : 'Washington', '54' : 'West Virginia', '55' : 'Wisconsin', '56' : 'Wyoming' } return states[id]; }