Last active
September 22, 2017 23:24
-
-
Save mmazanec22/321d578efac8a1372eb1a04f2067b56a to your computer and use it in GitHub Desktop.
Updating Bar Graph
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
<!DOCTYPE html> | |
<html> | |
<head> | |
<script src="https://d3js.org/d3.v3.min.js"></script> | |
<script type="text/javascript" src='./updateHistogram.js'></script> | |
<link rel="stylesheet" type="text/css" href="./styles.css"> | |
</head> | |
<body> | |
<div class='parent-div'></div> | |
</body> | |
</html> |
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
html, body { | |
height: 100%; | |
width: 100%; | |
overflow: hidden; | |
} | |
.parent-div { | |
height: 100%; | |
width: 100%; | |
} | |
.bar { | |
fill-opacity: 0.2; | |
stroke: white; | |
fill: dodgerblue; | |
} | |
.axis .domain { | |
stroke: none; | |
fill: none; | |
} | |
.axis text { | |
fill: dodgerblue; | |
font-size: 0.6rem; | |
letter-spacing: 0.05rem; | |
fill-opacity: 0.8; | |
} | |
.axis line { | |
stroke: dodgerblue; | |
} |
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
document.addEventListener("DOMContentLoaded", function() { | |
const parentDiv = d3.select('.parent-div'); | |
const example = new Histogram(parentDiv); | |
setInterval(function() { | |
example.update() | |
}, 2000) | |
}); | |
class Histogram { | |
constructor(parentDiv) { | |
this.parentDiv = parentDiv; | |
this.width = 900 | |
this.height = 500 | |
this.verticalMargins = 40 | |
this.horizontalMargins = 20 | |
this.originalTimeDomain = [new Date(1980, 1), new Date(2017, 1)] | |
this.graphWidth = this.width - this.horizontalMargins * 2 | |
this.graphHeight = this.height - this.verticalMargins * 2 | |
this.histX = d3.scale.linear() | |
.domain(this.originalTimeDomain) | |
.range([0, this.graphWidth]); | |
this.histLayout = d3.layout.histogram() | |
.bins(this.histX.ticks(this.graphWidth / 10)) | |
this.draw() | |
} | |
draw() { | |
const svg = this.parentDiv.append('svg') | |
.attr('position', 'absolute') | |
.attr('preserveAspectRatio', 'xMinYMin meet') | |
.attr('width', this.width) | |
.attr('height', this.height) | |
let dataToUse = this.makeData(); | |
const xData = this.histLayout(dataToUse); | |
const yMax = d3.max(xData, d => d.length); | |
const y = d3.scale.linear() | |
.domain([0, yMax]) | |
.range([this.graphHeight, 0]); | |
const xAxis = d3.svg.axis() | |
.scale(this.histX) | |
.orient('top') | |
.tickFormat(d => new Date(d).getYear()); | |
const barGroup = svg.append('g') | |
.attr('class', 'bar-group') | |
const bars = barGroup.selectAll('.bar') | |
.data(xData); | |
bars.exit() | |
.transition() | |
.duration(750) | |
.attr('height', 0); | |
const barWidth = this.graphWidth / xData.length | |
bars.enter().append('rect') | |
.attr('class', 'bar') | |
.attr('y', 0.1) | |
.attr('height', 0) | |
.attr('width', barWidth) | |
.attr('transform', d => `translate(${this.histX(d.x) + this.horizontalMargins}, ${this.verticalMargins})`) | |
bars.transition() | |
.duration(750) | |
.attr('height', d => this.graphHeight - y(d.length)); | |
const xAxisElements = svg.append('g') | |
.attr('class', 'x axis') | |
.attr('transform', `translate(${this.horizontalMargins} ${this.verticalMargins})`) | |
.call(xAxis); | |
xAxisElements.selectAll('path, line') | |
.style('shape-rendering', 'crispEdges'); | |
} | |
update() { | |
const self = this; | |
let dataToUse = self.makeData(); | |
const newXData = self.histLayout(dataToUse); | |
// Max height should be large enough to see the buckets where there is only one; | |
// but small enough that it looks like bars have changed when they have | |
const yMax = Math.max(d3.max(newXData, d => d.length), 16 / 2); | |
const y = d3.scale.linear() | |
.domain([0, yMax]) | |
.range([self.graphHeight, 0]); | |
const bars = d3.selectAll('.bar') | |
.data(newXData); | |
bars.exit().attr('height', 0); | |
bars.transition() | |
.duration(750) | |
.attr('height', d => self.graphHeight - y(d.length)); | |
} | |
makeData(length = 500) { | |
return new Array(500).fill({}).map(function() { | |
const year = Math.random() * (2017 - 1980) + 1980; | |
const month = Math.random() * (12 - 1) + 1; | |
const day = Math.random() * (30 - 1) + 1; | |
const hours = Math.random() * 23; | |
const minutes = Math.random() * 59 + 1; | |
return new Date(year, month, day, hours, minutes); | |
}).sort((a, b) => a - b) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment