Skip to content

Instantly share code, notes, and snippets.

@karen-izuka
Last active February 17, 2020 19:39
Show Gist options
  • Save karen-izuka/2ebb1df656c19841a127f035ee92e43e to your computer and use it in GitHub Desktop.
Save karen-izuka/2ebb1df656c19841a127f035ee92e43e to your computer and use it in GitHub Desktop.
Sortable Bar Chart
letter value
A .08167
B .01492
C .02780
D .04253
E .12702
F .02288
G .02022
H .06094
I .06973
J .00153
K .00747
L .04025
M .02517
N .06749
O .07507
P .01929
Q .00098
R .05987
S .06333
T .09056
U .02758
V .01037
W .02465
X .00150
Y .01971
Z .00074
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Letter Frequency</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Frequency of Letters in the English Language</h1>
<div id="chart"></div>
<div id="select">
<select id="order">
<option selected disabled>Select Order</option>
<option value="A">Alphabetical</option>
<option value="B">Increasing Order</option>
<option value="C">Decreasing Order</option>
</select>
</div>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script src="index.js"></script>
</body>
</html>
//static variables
const width = 1250;
const height = 500;
const margin = {top: 25, right: 25, bottom: 25, left: 25};
const svg = d3.select('#chart')
.append('svg')
.attr('width', width)
.attr('height', height);
const x = d3.scaleBand()
.range([margin.left, width - margin.right])
.padding(0.1);
const y = d3.scaleLinear()
.range([height - margin.bottom, margin.top]);
const xAxis = g => g
.attr('transform', `translate(0, ${height - margin.bottom})`)
.call(d3.axisBottom(x).tickSizeOuter(0));
const format = d3.format('.1%');
//data load
const load = async () => {
//load data
const data = await d3.csv('data.csv', ({letter, value}) => ({letter: letter, value: +value}));
//render chart
chart(data);
//update chart
document.querySelector('#order').addEventListener('change', function() {
let order = this.options[this.selectedIndex].value;
switch (order) {
case 'A': data.sort((a, b) => a.letter.localeCompare(b.letter)); break;
case 'B': data.sort((a, b) => a.value - b.value); break;
case 'C': data.sort((a, b) => b.value - a.value); break;
}
chart.update(data);
});
}
//chart function
const chart = data => {
x.domain(data.map(d => d.letter));
y.domain([0, d3.max(data, d => d.value)]);
const bar = svg.selectAll('rect')
.data(data)
.join('rect')
.attr('class', 'bar')
.attr('x', d => x(d.letter))
.attr('y', d => y(d.value))
.attr('width', x.bandwidth())
.attr('height', d => y(0) - y(d.value));
const label = svg.selectAll('text')
.data(data)
.join('text')
.text(d => format(d.value))
.attr('class', 'label')
.attr('x', d => x(d.letter) + x.bandwidth()/2)
.attr('y', d => y(d.value) - 10)
.attr('text-anchor', 'middle');
const gx = svg.append('g')
.attr('class', 'axis')
.call(xAxis);
chart.update = (data) => {
x.domain(data.map(d => d.letter));
const t = svg.transition()
.duration(1000);
bar.data(data, d => d.letter)
.transition(t)
.delay((d, i) => i*25)
.attr('x', d => x(d.letter));
label.data(data, d => d.letter)
.transition(t)
.delay((d, i) => i*25)
.attr('x', d => x(d.letter) + x.bandwidth()/2);
gx.transition(t)
.call(xAxis)
.selectAll('.tick')
.delay((d, i) => i*25)
}
}
//invoke function
load()
h1 {
font-family: Arial, Helvetica, sans-serif;
padding: 25px;
text-align: center;
}
svg {
display: block;
margin: auto;
}
.axis text {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
.bar {
fill: #a6bddb;
opacity: 0.5;
}
.label {
font-family: Arial, Helvetica, sans-serif;
font-size: 12px;
}
#select {
padding: 25px;
text-align: center;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment