Skip to content

Instantly share code, notes, and snippets.

@jwilber
Last active October 24, 2018 07:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jwilber/bbd72e522963d9fa37d21e6d23b7265f to your computer and use it in GitHub Desktop.
Save jwilber/bbd72e522963d9fa37d21e6d23b7265f to your computer and use it in GitHub Desktop.
reusable scatterplot (es6 class)
license: mit

Structure a scatterplot as an ES6 class.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="scatter.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
.point {
fill: #000;
stroke: transparent;
stroke-width: 5px;
}
.line {
fill: none;
stroke: #aaa;
}
.axis {
.domain,
.tick line {
display: none;
}
}
</style>
</head>
<body>
<!-- here's the div our chart will be injected into -->
<div class="chart-container" style="max-width: 1000px;"></div>
<script>
const chart = new Chart({
element: document.querySelector('.chart-container'),
data: "tweetdata.csv",
x: 'day',
y: 'retweets'
});
</script>
</body>
class Chart {
constructor(opts) {
this.element = opts.element;
this.x = opts.x;
this.y = opts.y;
d3.csv(opts.data, (d) => {
this.data = d;
this.draw();
});
}
draw() {
this.width = 750;
this.height = this.width / 1.5;
this.margin = {
top: 50,
bottom: 50,
right: 50,
left: 50
};
this.element.innerHTML = '';
const svg = d3.select(this.element).append('svg');
svg.attr('width', this.width);
svg.attr('height', this.height);
this.plot = svg.append('g')
.attr('transform', `translate(${this.margin.left}, ${this.margin.top})`)
this.createScales();
this.addAxes();
this.addScatter();
}
createScales() {
const xExtent = d3.extent(this.data, d => +d[this.x]);
const yExtent = d3.extent(this.data, d => +d[this.y]);
// force zero baseline if all data is positive
if (yExtent[0] > 0) { yExtent[0] = 0; };
if (xExtent[0] > 0) { xExtent[0] = 0; };
this.xScale = d3.scaleLinear()
.range([0, this.width - (this.margin.right*2)])
.domain(xExtent);
this.yScale = d3.scaleLinear()
.range([this.height - (this.margin.top + this.margin.bottom), 0])
.domain(yExtent);
};
addAxes() {
const xAxis = d3.axisBottom()
.scale(this.xScale);
const yAxis = d3.axisLeft()
.scale(this.yScale);
this.plot.append('g')
.attr('class', 'x_axis')
.attr('transform', `translate(0, ${this.height - (this.margin.top + this.margin.bottom)})`)
.call(xAxis);
this.plot.append('g')
.attr('class', 'y_axis')
.call(yAxis);
};
addScatter() {
this.plot.selectAll('circle')
.data(this.data).enter()
.append('circle')
.attr("cx", d => this.xScale(+d[this.x]))
.attr("cy", d => this.yScale(+d[this.y]))
.attr("r", 4);
};
}
day tweets retweets favorites
1 1 2 5
2 6 11 3
3 3 8 1
4 5 14 6
5 10 29 16
6 4 22 10
7 3 14 1
8 5 18 7
9 1 30 22
10 4 16 15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment