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 = '
';
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];
}