Published
Edited
May 14, 2020
Insert cell
Insert cell
Insert cell
chart = {
const svg = d3.select(DOM.svg(width, height));
const g = svg.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`)
g.append("g").call(xAxis);
g.append("g").call(yAxis);
const cells = g.append("g")
.classed("cells", true)
.selectAll("g")
.data(voronoi(data).polygons())
.join("g")
.classed("cell", true);
cells.append("circle")
.attr("cx", d => d && d.data && xScale(d.data[X_VAR]))
.attr("cy", d => d && d.data && yScale(d.data[Y_VAR]))
.attr("r", d => d && d.data && 2);
cells.append("path")
.attr("d", d => d && d.join && "M" + d.join("L") + "Z");

cells.append("title")
.text(d => {
if (d && d.data) {
const name = d.data.NAME.split(", ");
const x = d.data[X_VAR];
const y = d.data[Y_VAR];
return `${name}: \nx: ${x}% \ny: ${y}%`;
}
});
g.append("line")
.attr("class", "regression")
.datum(linearRegression(data))
.attr("x1", d => xScale(d[0][0]))
.attr("x2", d => xScale(d[1][0]))
.attr("y1", d => yScale(d[0][1]))
.attr("y2", d => yScale(d[1][1]));
return svg.node();
}
Insert cell
height = width
Insert cell
margin = ({ top: 10, right: 10, bottom: 30, left: 30 })
Insert cell
X_VAR = "age85uppct"
Insert cell
Y_VAR = "blackpct"
Insert cell
yScale = d3.scaleLinear()
.range([height - margin.top - margin.bottom, 0])
.domain(d3.extent(data, d => d[Y_VAR]))
Insert cell
xScale = d3.scaleLinear()
.range([0, width - margin.left - margin.right])
.domain(d3.extent(data, d => d[X_VAR]))
Insert cell
xAxis = g =>
g.attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
.call(d3.axisBottom(xScale))
.call(d => d.select(".domain").remove())
.call(g =>
g.append("text")
.text(data.x)
.attr("y", -4)
.attr("x", width - margin.right - margin.left)
.attr("text-anchor", "end")
.attr("fill", "#333")
.attr("font-weight", "bold")
)
Insert cell
yAxis = g =>
g.call(d3.axisLeft(yScale))
.call(g => g.select(".domain").remove())
.call(g =>
g.append("text")
.text(data.y)
.attr("x", 4)
.attr("text-anchor", "start")
.attr("fill", "#333")
.attr("font-weight", "bold")
)
Insert cell
linearRegression = regression.regressionLinear()
.x(d => d[X_VAR])
.y(d => d[Y_VAR])
Insert cell
voronoi = d3.voronoi()
.extent([[-margin.left, -margin.top], [width + margin.right, height + margin.bottom]])
.x(d => xScale(d[X_VAR]))
.y(d => yScale(d[Y_VAR]))
Insert cell
Insert cell
style = html`<style>
.cell path {
fill: none;
stroke: none;
pointer-events: all;
cursor: pointer;
}

.cell circle {
fill: #333;
}

.cell:hover circle {
fill: red;
}

line.regression {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
</style>`
Insert cell
Insert cell
data = Object.assign(d3.csvParse(await FileAttachment("JoinedFinal.csv").text(), parseRow),
{ x: "% of population age > 85", y: "% of black population " })
Insert cell
parseRow = d => {
const keys = Object.keys(d);
const numerics = keys.slice(2)
numerics.forEach(key => { d[key] = +d[key]; })
d.blackpct = +d3.format(".2f")(d.BLACK / d.POPULATION * 100);
d.age85uppct = +d3.format(".2f")(d.AGE_85_UP / d.POPULATION * 100);
return d;
}
Insert cell
Insert cell
d3 = require("d3@5")
Insert cell
regression = require("d3-regression@1")
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