Public
Edited
Oct 7, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
data = _.zipWith(wellbeingScore, MULTI_pct, (score, pct) => (
{
x: score,
y: pct
}
))
Insert cell
Insert cell
Insert cell
margin = ({ top: 20, right: 20, bottom: 20, left: 50 })
Insert cell
Insert cell
xScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.x)])
.range([margin.left, width - margin.right])
Insert cell
yScale = d3.scaleLinear()
.domain([0, 45])
.range([height - margin.bottom, margin.top])
Insert cell
Insert cell
xAxis = g => g.attr('transform', `translate(0, ${height - margin.bottom})`)
.attr("class", "xAxis")
.call(d3.axisBottom(xScale).ticks(4))
Insert cell
yAxis = g => g.attr('transform', `translate(${margin.left}, 0)`)
.attr("class", "yAxis")
.call(d3.axisLeft(yScale).ticks(4))
Insert cell
Insert cell
// We get back an object with m (slope) and b (y intercept). Inspect the object above if you're not sure.
linearRegression = ss.linearRegression(data.map(d => [d.x, d.y]))
Insert cell
// We can pass that object into a helper function to get a function that given x, returns y!
// It's just using the formula from our high school algebra class, y = mx + b
linearRegressionLine = ss.linearRegressionLine(linearRegression)
Insert cell
// We need to define the 2 points of the regression line to be able to have D3 make a line.
// This just makes 2 points, 1 for the start and 1 for the end of our line.
regressionPoints = {
const firstX = data[0].x;
const lastX = data.slice(-1)[0].x;
const xCoordinates = [firstX, lastX];
return xCoordinates.map(d => ({
x: d, // We pick x and y arbitrarily, just make sure they match d3.line accessors
y: linearRegressionLine(d)
}));
}
Insert cell
// We also need to prepare a line generator that knows what to do with each datapoint.
line = d3.line()
.x(d => xScale(d.x))
.y(d => yScale(d.y))
Insert cell
// Lastly, here's the function that will tie everything together!

/*
Draws a scatterplot and linear regression line and attaches it to the DOM node "target".
*/
renderChart = (target) => {
target.append('g')
.call(xAxis);
target.append('g')
.call(yAxis);
// scatterplot
target.selectAll('circle')
.data(data)
.enter().append('circle')
.attr('r', 3.5)
.attr('cx', d => xScale(d.x))
.attr('cy', d => yScale(d.y));
// regression line
target.append('path')
.classed('regressionLine', true)
.datum(regressionPoints)
.attr('d', line);
}
Insert cell
Insert cell
// Light styling
html`
<style>
.chart .xAxis path,line {
stroke: #dddddd;
}

.chart .yAxis path,line {
stroke: #dddddd;
}

.chart circle {
fill: steelblue;
}

.chart path.regressionLine {
stroke: steelblue;
fill: none;
stroke-width: 1.2;
stroke-dasharray: 2,2;
}

</style>
`
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