Public
Edited
Apr 19, 2023
7 forks
Insert cell
Insert cell
mercator = d3
.geoMercator()
.center([-119, 37.4])
.scale((1 << 18) / (28 * Math.PI))
.translate([320, 320])
Insert cell
Insert cell
legend = (g) => {
const x = d3
.scaleLinear()
.domain(d3.extent(color.domain()))
.rangeRound([0, 260]);

g.selectAll("rect")
.data(color.range().map((d) => color.invertExtent(d)))
.join("rect")
.attr("height", 8)
.attr("x", (d) => x(round5(d[0])))
.attr("width", (d) => x(round5(d[1])) - x(round5(d[0])))
.attr("fill", (d) => color(round5(d[0])));

g.append("text")
.attr("x", x.range()[0])
.attr("y", -6)
.attr("fill", "currentColor")
.attr("text-anchor", "middle")
.attr("font-weight", "bold")
.text(data.title);

g.call(
d3
.axisBottom(x)
.tickSize(13)
.tickFormat((d) => format(d)) //here
.tickValues(
color
.range()
.slice(1)
.map((d) => round5(color.invertExtent(d)[0]))
)
)
.select(".domain")
.remove();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
rawData = FileAttachment("ca-all-clearances@1.csv").csv({typed:false})
Insert cell
filteredData = rawData.map((d => [
d.GEOID, + d.rate
]))
Insert cell
Insert cell
data = Object.assign( new Map(filteredData), {title: "Cases Cleared"})
Insert cell
color = d3.scaleQuantize([round5(d3.min(rawData, d => +d.rate)), round5(d3.max(rawData, d => +d.rate))], d3.schemeBlues[9])
Insert cell
function round5(num) {
return Math.round(num / 5) * 5;
}
Insert cell
format = d => `${d}%`
Insert cell
callout = (g, value) => {
if (!value) return g.style("display", "none");

g
.style("display", null)
.style("pointer-events", "none")
// .style("font", "10px sans-serif");

const path = g.selectAll("path")
.data([null])
.join("path")
.attr("fill", "white")
.attr("stroke", "lightgrey")
.attr("stroke-width", "0.5px");;

const text = g.selectAll("text")
.data([null])
.join("text")
.call(text => text
.selectAll("tspan")
.data((value + "").split(/\n/))
.join("tspan")
.attr("x", 0)
.attr("y", (d, i) => `${i * 1.1}em`)
.style("font-weight", (_, i) => i ? null : "bold")
.text(d => d));

const {x, y, width: w, height: h} = text.node().getBBox();

text.attr("transform", `translate(${-w / 2},${15 - y})`);
path.attr("d", `M${-w / 2 - 10},5H-5l5,-5l5,5H${w / 2 + 10}v${h + 20}h-${w + 20}z`);
}
Insert cell
html`<style>
.tooltip {
font-family:sans-serif;
border: 1px solid #ccc;
font-size: 12px
}
</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