{
let container = html`<div id= "container" style='height:600px;' />`;
yield container;
let map = new mapboxgl.Map({
container,
center: [-73.982364, 40.706839],
zoom: 9.5,
style: "mapbox://styles/mapbox/light-v10",
scrollZoom: false
});
map.addControl(new mapboxgl.NavigationControl(), "top-right");
const mapboxContainer = map.getCanvasContainer()
const svg = d3.select(mapboxContainer)
.append("svg")
.style("position", "absolute")
.attr("width", width)
.attr("height", height);
function getD3() {
var bbox = document.querySelector("#container").getBoundingClientRect();
console.log(bbox)
var center = map.getCenter();
var zoom = map.getZoom();
var scale = (512) * 0.5 / Math.PI * Math.pow(2, zoom);
let projection = d3.geoMercator()
.center([center.lng, center.lat])
.translate([bbox.width/2, bbox.height/2])
.scale(scale);
return projection;
}
// calculate the original d3 projection
let projection = getD3();
let path = d3.geoPath().projection(projection);
const colorScale = d3.scaleThreshold()
.domain([3, 5, 7, 10])
.range(d3.schemeBuPu[5]);
const dists = svg
.selectAll("path")
.data(geojson.features)
.join("path")
.attr("d", path)
.attr("class", "dists")
.attr("fill", function(d) {
if (d.properties.total_first2016 > 10)
return colorScale(d.properties.pct_total_first2016_total_voted2016)
else return "whitesmoke"
})
.style("stroke", "darkgray")
.style("stroke-width", ".25")
.style("cursor", "default")
//From http://bl.ocks.org/enjalot/0d87f32a1ccb9a720d29ba74142ba365
function render() {
projection = getD3();
path.projection(projection)
dists
.attr("d", path)
}
// re-render our visualization whenever the view changes
map.on("viewreset", function() {
render()
})
map.on("move", function() {
render()
})
// render our initial visualization
render();
//FROM https://observablehq.com/@duynguyen1678/choropleth-with-tooltip
const tooltip = svg.append("g");
svg
.selectAll(".dists")
.on("touchmove mousemove", function(event, d) {
if (d.properties.total_first2016 > 10 && d.properties.winner === 'trump') {
tooltip.call(
callout,
`${format(d.properties.pct_total_first2016_total_voted2016)}
(${d.properties.total_first2016} new voters of ${d.properties.total_voted2016})
${(d.properties.DEM) ? d.properties.DEM : 0} Democrats
${(d.properties.REP) ? d.properties.REP : 0} Republicans
${((d.properties.ALL_OTH) > 0) ? d.properties.ALL_OTH : 0} Other
Trump won this district by ${d.properties.trump_votes - d.properties.clinton_votes} votes.`
);
}
else if (d.properties.total_first2016 > 10 && d.properties.winner === 'clinton') {
tooltip.call(
callout,
`${format(d.properties.pct_total_first2016_total_voted2016)}
(${d.properties.total_first2016} new voters of ${d.properties.total_voted2016})
${(d.properties.DEM) ? d.properties.DEM : 0} Democrats
${(d.properties.REP) ? d.properties.REP : 0} Republicans
${((d.properties.ALL_OTH) > 0) ? d.properties.ALL_OTH : 0} Other
Clinton won this district by ${d.properties.clinton_votes - d.properties.trump_votes} votes.`
);
} else {
tooltip.call(
callout,
`This district had fewer than 10 new voters.`);
};
tooltip.attr("transform", `translate(${d3.pointer(event, this)})`);
d3.select(this)
.style("stroke", "black")
.style("stroke-width", "2")
.style("fill", function(d) {
if (d.properties.winner === 'trump')
return "darkred";
else if (d.properties.winner === 'clinton')
return "darkblue";
else return colorScale(d.properties.pct_total_first2016_total_voted2016);
})
})
.on("touchend mouseleave", function(d) {
tooltip.call(callout, null);
d3.select(this)
.style("stroke", null)
.style("fill", function(d) {
if (d.properties.total_first2016 > 10)
return colorScale(d.properties.pct_total_first2016_total_voted2016)
else return "whitesmoke"
})
});
//From https://observablehq.com/@tmcw/using-mapbox-gl-js
// Be careful to clean up the map's resources using \`map.remove()\` whenever
// this cell is re-evaluated.
invalidation.then(() => map.remove());
}