canvas = {
d3.select('body').selectAll('div#canvas').remove();
const div = d3.select('body').append('div').attr('id', 'canvas');
const mapContext = DOM.context2d(width, height);
const origT = projection.translate();
const origS = projection.scale();
const timeLineContext = DOM.context2d(width, height);
div.append(() => mapContext.canvas)
.style('position', 'relative');
div.append(() => timeLineContext.canvas)
.style('position', 'absolute')
.style('left', 0)
.style('top', 0);
const voronoiG = div.append('svg')
.style('width', width)
.style('height', height)
.style('position', 'absolute')
.style('left', 0)
.style('top', 0)
.append('g')
.style('fill', 'none')
.style('stroke', 'red');
function renderMap() {
mapContext.clearRect(0, 0, width, height);
drawMap(mapContext);
drawTriangles(mapContext);
voronoiG.call(makeVoronoi);
}
function renderTimeLine() {
timeLineContext.clearRect(0, 0, width, height);
drawTimeAxis(timeLineContext);
drawDistribution(timeLineContext);
}
function render() {
renderMap();
renderTimeLine();
}
function zoomed(){
const newScale = d3.event.transform.k;
const newTranslate = [newScale*origT[0] + d3.event.transform.x, newScale*origT[1] + d3.event.transform.y];
projection.scale(origS*newScale)
.translate(newTranslate);
renderMap();
}
const zoom = d3.zoom()
.translateExtent([[0,0],[width, height]])
.scaleExtent([1, 90])
.on("zoom", zoomed);
div.style('background', 'aliceblue')
.call(zoom)
.call(render)
;
return html`${div.node()}`;
}