Public
Edited
May 18, 2023
3 stars
Insert cell
Insert cell
Insert cell
Insert cell
{
const svg = d3.create('svg')
.attr('width', width + 100)
.attr('height', height)
// .attr('viewBox', [0, -10, width, height])
const hex = svg.append('g')
// .attr('transform', `translate(${0}, ${0})`)
.selectAll('.hexagon')
.data(hexbin(svgData))
.enter().append('g')
.attr('class', 'hexagon')
.attr('transform', d => `translate(${d.x}, ${d.y})`)
hex.append('path')
.attr('d', hexbin.hexagon())
.attr('stroke', '#eee')
.attr('stroke-opacity', '0.5')
.attr('stroke-width', '1px')
.style('fill', d => (d[0].index >= pctValue) ? '#bfabcc' : '#6b2e63')

// add some numbers so we can check the values are correct
if (numbersDisplay.includes('numbers')) {
hex.append('text')
.style('font-size', '8px')
.attr('text-anchor', 'middle')
.attr('y', '2px')
.style('fill', d => (d[0].index >= pctValue) ? '#000' : '#fff')
.text(d => d[0].index + 1)
}

svg.append('text')
.style('fill', '#6b2e63')
.attr('x', '500px')
.attr('y', '400px')
.style('font-size', '60px')
.text(pctValue + '%')

return svg.node()
}
Insert cell
Insert cell
imageData = image.getContext('2d').getImageData(0, 0, width, height).data
Insert cell
imageDataAlpha = imageData.filter((d,i) => i%4 === 3)
Insert cell
imageCenters = {
return centers.filter(d => imageDataAlpha[Math.floor(d[0]) + Math.floor(d[1]) * width]);
}
Insert cell
Insert cell
svgData = imageCenters.map((d, i) => {
const array = d
return {
x: d[0],
y: d[1],
index: 99 - i //reverse the default number order so bottom to top
}
})
Insert cell
Insert cell
Insert cell
Insert cell
{
const context = DOM.context2d(width, height);

const canvasHex = new Path2D(hexbin.hexagon());
context.lineWidth = 1;
context.strokeStyle = 'tomato'
imageCenters.forEach(d => {
context.translate(d[0], d[1]);
context.stroke(canvasHex);
context.translate(-d[0], -d[1])
})

return context.canvas;
}
Insert cell
centers = hexbin.centers()
Insert cell
imageCenters.length // this doubles as number of hexagons
Insert cell
r = 11.87 // changing this will change the number of hexes ^^ 11.87 give me 100 centers with the dimensions 500 by 500
Insert cell
width = 500 // TODO calc width, height and radius to ensure 100 hexes are rendered so doesn't have to be hard coded
Insert cell
height = 500
Insert cell
Insert cell
ukGeo = topojson.feature(ukTopo, ukTopo.objects.GBR_adm0)
Insert cell
geoPath = d3.geoPath().projection(projection)
Insert cell
extentUk = [[0, height * 0.05], [width, height * 0.95]]
Insert cell
// projection = d3.geoAlbers().fitSize([width, height], ukGeo)
projection = d3.geoConicEqualArea().parallels([50, 61]).fitExtent(extentUk, ukGeo)
Insert cell
path = d3.geoPath().projection(projection)
Insert cell
topojson = require('topojson@3')
Insert cell
hexbin = d3.hexbin()
.x(d => d.x)
.y(d => d.y)
.radius(r)
.extent([[0, 0], [width, height]])
Insert cell
Insert cell
<hr>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=PT+Sans&display=swap" rel="stylesheet">

<style>
text {
font-family: 'PT Sans', sans-serif;
font-weight: 400;
font-size: 9px;
letter-spacing: 2px;
text-anchor: middle;
}
svg {
background: #eee
}


</style>
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more