Created
January 14, 2021 20:11
-
-
Save joshuajnoble/68cb70a7997309cd58ac6d7d69920486 to your computer and use it in GitHub Desktop.
A basic scatterplot in d3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function scatterPlot({ | |
chart, /* this needs to be an SVG element */ | |
width, | |
height, | |
data, | |
xfield, | |
yfield, | |
xdomain, /* min/max x values */ | |
ydomain, /* min/max y values */ | |
xpadding, | |
ypadding, | |
size, /* size of the dot */ | |
title, | |
xlabel, | |
ylabel, | |
xgrid, /* show a grid true/false */ | |
ygrid /* show a grid true/false */ | |
}) { | |
let xAxisHeight = 30; | |
let yAxisHeight = 20; | |
let xAxisWidth = 20; | |
let yAxisWidth = 20; | |
let titleHeight = 30; | |
let textHeight = 10; | |
let figPadding = 40; | |
let topPadding = titleHeight + figPadding; | |
let leftPadding = figPadding + yAxisWidth; | |
let bottomPadding = figPadding + xAxisHeight; | |
let svg = chart.node(); | |
let w = width - leftPadding - 30; | |
let h = height - topPadding - bottomPadding; | |
let xscale = d3 | |
.scaleLinear() | |
.domain(xdomain) | |
.range([0, w]); | |
let yscale = d3 | |
.scaleLinear() | |
.domain(ydomain) | |
.range([h, 0]); | |
let xvalue_scale = d3 | |
.scaleLinear() | |
.domain(xdomain) | |
.range([0, w]); | |
let yvalue_scale = d3 | |
.scaleLinear() | |
.domain(ydomain) | |
.range([h, 0]); | |
// Add x axis | |
let xAxis = d3 | |
.axisBottom(xscale) | |
.tickPadding(4) | |
.tickSizeOuter(0); | |
chart | |
.append("g") | |
.attr("class", "x axis") | |
.attr( | |
"transform", | |
"translate(" + leftPadding + "," + (h + topPadding) + ")" | |
) | |
.call(xAxis); | |
// Add x axis label | |
chart | |
.append("text") | |
.attr( | |
"transform", | |
"translate(" + | |
(leftPadding + w / 2) + | |
" ," + | |
(height - figPadding + 10) + | |
")" | |
) | |
.style("text-anchor", "middle") | |
.text(xlabel); | |
// x axis | |
// Ref: https://bl.ocks.org/d3noob/c506ac45617cf9ed39337f99f8511218 | |
if (xgrid) { | |
chart | |
.append("g") | |
.attr("class", "x grid") | |
.attr("transform", "translate(" + leftPadding + "," + topPadding + ")") | |
.call( | |
xAxis | |
.tickSize(h) | |
.tickFormat("") | |
.ticks(5) | |
); | |
} | |
// Add y axis | |
let yAxis = d3 | |
.axisLeft(yscale) | |
.tickSizeOuter(0) | |
.ticks(4); | |
chart | |
.append("g") | |
.attr("class", "y axis") | |
.attr("transform", "translate(" + leftPadding + "," + topPadding + ")") | |
.call(yAxis); | |
// Add y axis label | |
chart | |
.append("text") | |
.attr( | |
"transform", | |
"rotate(-90)," + | |
"translate(" + | |
(0 - topPadding - h / 2 - 10) + | |
" ," + | |
(figPadding + textHeight / 2 - 15) + | |
")" | |
) | |
.style("text-anchor", "middle") | |
.text(ylabel); | |
// y grid | |
if (ygrid) { | |
chart | |
.append("g") | |
.attr("class", "y grid") | |
.attr("transform", "translate(" + leftPadding + "," + topPadding + ")") | |
.call(yAxis.tickSize(-w).tickFormat("")); | |
} | |
// create a new group, use `selectAll` to build an empty | |
// list context | |
let dots = chart | |
.append("g") | |
.attr("class", "dots") | |
.selectAll() | |
.data(data) | |
.enter() | |
.append("circle") | |
.attr("cx", d => leftPadding + xvalue_scale(d[xfield])) | |
.attr("cy", d => topPadding + yvalue_scale(d[yfield])) | |
.attr("r", size); | |
// Add title | |
chart | |
.append("text") | |
.attr("class", "title") | |
.attr("text-anchor", "middle") | |
.attr("x", w / 2 + leftPadding) | |
.attr("y", figPadding + titleHeight / 2) | |
.text(title); | |
return chart; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment