Published
Edited
Dec 4, 2020
Fork of 20 Million
3 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
map = {
const canvas = d3
.create("canvas")
.attr("width", mapWidth)
.attr("height", mapHeight)
.node();
canvas.width = mapWidth;
canvas.height = mapHeight;
let ctx = canvas.getContext("2d");
scaleCanvas(canvas, ctx);
ctx.fillStyle = "rgba(5,5,5,1)";
ctx.fillRect(0, 0, mapWidth, mapHeight);

const path = d3.geoPath(projection, ctx);
/*
ctx.save();
ctx.beginPath(),
path(land),
(ctx.strokeStyle = "rgba(255, 255, 255, 0.2 )"),
ctx.stroke();
ctx.restore();
*/
// DRAW TICK
draw(ctx);
// svg.append("g").attr("transform", "translate(${height},20)");
// .append(() => legend({ ramp, title: data.title, width: 260 }));

return canvas;
}
Insert cell
metric = "30DayActiveHH"
Insert cell
Insert cell
metricNormalize = d3
.scaleLinear()
.domain(metricExtent)
.range([0, 5])
Insert cell
function draw(ctx) {
circles.forEach(d => {
// if (d.longitude > lngFilter * 2 - 160) return false;
if (!d.longitude || !d.latitude || !d) return false;
const loc = projection([d.longitude, d.latitude]);
if (!loc) return null;
const [x, y] = loc;
// const x = width / 2;
// const y = height / 2;

// let r = 2.5 * (sliceFilter * 0.01);
// if (r < 1) r = 1;
let r = d.frames(tick) * 2;
let fill = d.colorFrames(tick);

// ctx.fillStyle = "rgba(225, 225, 225, 1)";
ctx.fillStyle = weightColor(fill);
//ctx.strokeStyle = "rgba(225, 225, 225, 0.15)";
ctx.lineWidth = 1;
// ctx.fillRect(x, y, 2, 2);
ctx.beginPath();
// ctx.arc(x, y, 2, 0, 2 * Math.PI);
// ctx.stroke();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fill();
});
}
Insert cell
circles = slicedMonthlyData
.sort((a, b) => {
//return +a.longitude - +b.latitude;
return +b['30DayActiveHH'] - +a['30DayActiveHH'];
// return +a['30DayActiveHH'] - +b['30DayActiveHH'];
})
.map((c, i) => {
// Add for each one, some condition where we're gonna say like
// where in the life cycle this circle is
// where in the animation does this circle kick in

const metricRaw = +c['30DayActiveHH'];
const metricNormal = metricNormalize(metricRaw);
// const metricNormal = metricRaw;

let start = Math.round(
(i * (ticks.length - 50)) / slicedMonthlyData.length
);
return {
...c,
metricRaw,
metricNormal,
frames: keyframe([
[0, 0],
[start, 0.25],
[start + 10, metricNormal * 0.5],
[start + 50, metricNormal * 1],
[240, metricNormal * 1]
]),
colorFrames: keyframe([
[0, metricNormal * 0.25],
[start, metricNormal * 0.5],
[start + 10, metricNormal * 0.8],
[start + 50, metricNormal * 1],
[240, metricNormal * 1]
])
};
})
Insert cell
projection = d3
// .geoAlbersUsa()
// .geoMiller()
.geoEquirectangular()
// .geoInterruptedMollweideHemispheres()
// .geoVanDerGrinten2()
//.translate([width / 2, height / 2])
// .scale([width * 0.2])
.fitWidth(mapWidth * 0.98, land)
.translate([mapWidth / 2, mapHeight / 2])
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
html`<div>
${chance
.shuffle(circles)
.slice(0, 25)
.map(d => {
return drawKeyframes(d.frames.frames);
})}
</div>
`
Insert cell
circles[1]
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
mapHeight = 2048 / 4
Insert cell
mapWidth = 4096 / 4
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
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