chart = {
const vis = d3.select(map())
const italy = vis.select('.map')
const cells = data.map((d, i) => ({...d, cell: voronoi.cellPolygon(i)}) )
italy.append("g")
.attr("stroke", "orange")
.selectAll("path")
.data(cells)
.join("path")
.attr("d", d => `M${d3.polygonCentroid(d.cell)}L${d.x} ${d.y}`)
.attr('vector-effect', 'non-scaling-stroke')
italy.append("path")
.attr("fill", "none")
.attr("stroke", "#99c")
.attr("d", delaunay.render())
.attr('vector-effect', 'non-scaling-stroke')
italy.append("path")
.attr("fill", "none")
.attr("stroke", "#0cc")
.attr("d", voronoi.render())
.attr('vector-effect', 'non-scaling-stroke')
italy.selectAll('.capital')
.data(data)
.join('circle')
.attr('class', 'capital')
.attr('cx', d => d.x)
.attr('cy', d => d.y)
italy.append("g")
.style("font", "10px sans-serif")
.selectAll(".label")
.data(cells)
.join("text")
.attr('class', 'label')
.each(function(d) {
const [cx, cy] = d3.polygonCentroid(d.cell)
const angle = (Math.round(Math.atan2(cy - d.y, cx - d.x) / Math.PI * 2) + 4) % 4
d3.select(this).call(angle === 0 ? orient.right
: angle === 3 ? orient.top
: angle === 1 ? orient.bottom
: orient.left)
})
.text((d, i) => d.label)
function zoomed(event) {
lod(event.transform.k)
}
function lod(z) {
italy.selectAll('.capital')
.attr('r', 1.5 / Math.sqrt(z))
italy.selectAll('.label')
.attr("transform", d => `translate(${d.x} ${d.y}) scale(${1/Math.sqrt(z)})`)
.attr("display", d => boundingBox(d.cell).width > 80/Math.sqrt(z) ? null : "none")
}
zoom.on('zoom', zoomed)
lod(d3.zoomTransform(vis).k)
return vis.node()
}