Published
Edited
May 5, 2018
5 forks
2 stars
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
yearsExperience = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
Insert cell
salaries = [39343, 46205, 37731, 43525, 39891, 56642, 60150, 54445, 64445, 57189, 63218]
Insert cell
Insert cell
data = _.zipWith(yearsExperience, salaries, (year, salary) => (
{
x: year,
y: salary
}
))
Insert cell
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, 20000 + d3.max(data, d => d.y)]) // added a bit of breathing room (20,000)
.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))
Insert cell
yAxis = g => g.attr('transform', `translate(${margin.left}, 0)`)
.attr("class", "yAxis")
.call(d3.axisLeft(yScale))
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) => {
// First, let's make the scatterplot
target.selectAll('circle')
.data(data)
.enter().append('circle')
.attr('r', 3)
.attr('cx', d => xScale(d.x))
.attr('cy', d => yScale(d.y));
// Next, we'll draw the regression line
target.append('path')
.classed('regressionLine', true)
.datum(regressionPoints)
.attr('d', line);
// Lastly, we add the axes!
target.append('g')
.call(xAxis);
target.append('g')
.call(yAxis);
}
Insert cell
Insert cell
// Light styling
html`
<style>
.chart .xAxis path,line {
stroke: #dddddd;
}

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

.chart circle {
fill: #aaaaaa;
}

.chart path.regressionLine {
stroke: #43A047;
fill: none;
stroke-width: 1.2;
stroke-dasharray: 3,5;
}

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