electoral_tile_map = {
let div = d3
.create('div')
.style("width", `${map_width}px`)
.style("height", `${height}px`)
.style('overflow', 'hidden');
let svg = div
.append('svg')
.style('overflow', 'hidden')
.attr("viewBox", [0, 0, map_width, height]);
let path = d3.geoPath().projection(proj);
let map = svg.append('g');
map
.selectAll("path.tile")
.data(electoral_tiles.tiles.features)
.join("path")
.attr('class', 'tile')
.attr('d', path)
.style("fill", function(d) {
let result = result_map.get(d.properties.name);
if (result == 'R') {
return '#ff3333';
} else if (result == 'D') {
return '#3333ff';
} else {
return '#ccc';
}
})
.attr("stroke-width", '0.8px')
.attr("stroke", function(d) {
return '#000';
})
.attr("stroke-linejoin", "round");
map
.selectAll("path.subtile")
.data(electoral_tiles.maine_nebraska_1)
.join("path")
.attr('class', 'subtile')
.attr('d', path)
.style("fill", function(d) {
let name = d.properties.name;
if (name == 'MAINE') {
return '#ff3333';
} else if (name == "NEBRASKA") {
return '#3333ff';
} else {
return '#aaa';
}
})
.attr("stroke-width", '1px')
.attr("stroke", function(d) {
return '#000';
})
.attr("stroke-linejoin", "round");
map
.selectAll("path.boundary")
.data(electoral_tiles.boundaries.features)
.join("path")
.attr('class', 'boundary')
.attr('d', path)
.style('fill', 'white')
.style("fill-opacity", 0)
.attr("stroke-width", '2px')
.attr("stroke", "white")
.attr("stroke-linejoin", "round")
.attr('title', function(d) {
if (d.properties.name == "MAINE") {
return "MAINE: 3 votes for Biden and 1 vote for Trump";
} else if (d.properties.name == "NEBRASKA") {
return "NEBRASKA: 4 votes for Trump and 1 vote for Biden";
}
let result = result_map.get(d.properties.name);
let winner;
if (result == "D") {
winner = "Biden";
} else if (result == "R") {
winner = "Trump";
} else {
winner = "no one in particular, just yet.";
}
return `${d.properties.name}: ${d.properties.tilegramValue} votes for ${winner}`;
})
.on('mouseenter', function(evt) {
let copy = this.cloneNode(true);
copy.setAttribute('stroke', 'black');
copy.setAttribute('stroke-width', '6px');
copy.setAttribute('class', 'temp');
copy.addEventListener('mouseleave', function() {
map.selectAll('.temp').remove();
});
tippy(copy, {
content: copy.getAttribute("title"),
followCursor: true,
theme: 'light'
});
map.append(() => copy);
});
let biden_votes = d3.sum(
electoral_tiles.boundaries.features
.filter(o => result_map.get(o.properties.name) == 'D')
.map(o => o.properties.tilegramValue)
);
let trump_votes = d3.sum(
electoral_tiles.boundaries.features
.filter(o => result_map.get(o.properties.name) == 'R')
.map(o => o.properties.tilegramValue)
);
let undecided_votes = d3.sum(
electoral_tiles.boundaries.features
.filter(o => result_map.get(o.properties.name) == '?')
.map(o => o.properties.tilegramValue)
);
map
.append('text')
.attr('x', `${0.2 * map_width}`)
.attr('y', `${0.05 * height}`)
.attr('font-family', 'sans-serif')
.text(`Biden: ${biden_votes}`);
map
.append('text')
.attr('x', `${0.4 * map_width}`)
.attr('y', `${0.05 * height}`)
.attr('font-family', 'sans-serif')
.text(`Trump: ${trump_votes}`);
map
.append('text')
.attr('x', `${0.6 * map_width}`)
.attr('y', `${0.05 * height}`)
.attr('font-family', 'sans-serif')
.text(`Undecided: ${undecided_votes}`);
return div.node();
}