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

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more