Published
Edited
Apr 17, 2019
2 forks
5 stars
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 [county, state] = d.data.name.split(", ");
const x = d.data[X_VAR];
const y = d.data[Y_VAR];
return `${county} \n${state}: \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 = "pct_without_internet"
Insert cell
Y_VAR = "pct_below_poverty_level"
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(
await d3.csv("https://gist.githubusercontent.com/clhenrick/52a65bafecbfeced5d90417d50480c90/raw/a298d59c1dc0aa29a1abce529c5219906dbf0979/acs_internet_access_joined_poverty.csv", parseRow),
{ x: "% of population without internet access", y: "% of population below poverty level" }
)
Insert cell
parseRow = d => {
const keys = Object.keys(d);
const numerics = keys.slice(2)
numerics.forEach(key => { d[key] = +d[key]; })
d.pct_without_internet = +d3.format(".2f")(d.no_internet_access / d.total_pop * 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