This variation of a simple bar chart adds sorting with staggered delay and translucency to improve readability during the transition. This technique is recommended by Heer & Robertson. Use the checkbox in the top right to turn sorting on or off.
Created
September 23, 2017 21:42
-
-
Save milroc/28784d9243324dc77e161c08ae87e8c7 to your computer and use it in GitHub Desktop.
Popsicles
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
license: gpl-3.0 |
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
letter | frequency | |
---|---|---|
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 |
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> | |
<meta charset="utf-8"> | |
<style> | |
body { | |
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; | |
position: relative; | |
width: 960px; | |
} | |
.axis text { | |
font: 10px sans-serif; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: #000; | |
shape-rendering: crispEdges; | |
} | |
.x.axis path { | |
display: none; | |
} | |
label { | |
position: absolute; | |
top: 10px; | |
right: 10px; | |
} | |
</style> | |
<label><input type="checkbox"> Sort values</label> | |
<script src="//d3js.org/d3.v3.min.js"></script> | |
<script> | |
var margin = {top: 20, right: 20, bottom: 30, left: 40}, | |
width = 960 - margin.left - margin.right, | |
height = 500 - margin.top - margin.bottom; | |
var formatPercent = d3.format(".0%"); | |
var x = d3.scale.ordinal() | |
.rangeRoundBands([0, width], .5, 1); | |
var y = d3.scale.linear() | |
.range([height, 0]); | |
var color = d3.scale.ordinal().range(["#F95B34", "#EE3E64", "#F36283", "#FF9C34", "#EBDE52", "#B7D84B", "#44ACCF"]); | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
.orient("bottom"); | |
var yAxis = d3.svg.axis() | |
.scale(y) | |
.orient("left") | |
.tickFormat(formatPercent); | |
var svg = d3.select("body").append("svg") | |
.attr("width", width + margin.left + margin.right) | |
.attr("height", height + margin.top + margin.bottom) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
//SVG filter for the gooey effect | |
//Code taken from http://tympanus.net/codrops/2015/03/10/creative-gooey-effects/ | |
var defs = svg.append("defs"); | |
var filter = defs.append("filter").attr("id","gooeyCodeFilter"); | |
filter.append("feGaussianBlur") | |
.attr("in","SourceGraphic") | |
.attr("stdDeviation","10") | |
//to fix safari: http://stackoverflow.com/questions/24295043/svg-gaussian-blur-in-safari-unexpectedly-lightens-image | |
.attr("color-interpolation-filters","sRGB") | |
.attr("result","blur"); | |
filter.append("feColorMatrix") | |
.attr("in","blur") | |
.attr("mode","matrix") | |
.attr("values","1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7") | |
.attr("result","gooey"); | |
//If you want the end shapes to be exactly the same size as without the filter | |
//add the feComposite below. However this will result in a less beautiful gooey effect | |
//filter.append("feBlend") | |
// .attr("in","SourceGraphic") | |
// .attr("in2","gooey"); | |
//Instead of the feBlend, you can do feComposite. This will also place a sharp image on top | |
//But it will result in smaller circles | |
// filter.append("feComposite") //feBlend | |
// .attr("in","SourceGraphic") | |
// .attr("in2","gooey") | |
// .attr("operator","atop"); | |
d3.tsv("data.tsv", function(error, data) { | |
data = data.filter(function(d, i) { return i < 15; }); | |
data.forEach(function(d) { | |
d.frequency = +d.frequency; | |
}); | |
x.domain(data.map(function(d) { return d.letter; })); | |
y.domain([0, d3.max(data, function(d) { return d.frequency; })]); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis) | |
.append("text") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 6) | |
.attr("dy", ".71em") | |
.style("text-anchor", "end") | |
.text("Frequency"); | |
svg.append('g').attr('filter', 'url(#gooeyCodeFilter)').selectAll(".bar") | |
.data(data) | |
.enter().append("rect") | |
.attr("class", "bar") | |
.attr("fill", function(d, i) { return color(i); }) | |
.attr("x", function(d) { return x(d.letter); }) | |
.attr("width", x.rangeBand()) | |
.attr("y", function(d) { return y(d.frequency); }) | |
.attr("height", function(d) { return height - y(d.frequency); }); | |
d3.select("input").on("change", change); | |
var sortTimeout = setTimeout(function() { | |
d3.select("input").property("checked", true).each(change); | |
}, 2000); | |
function change() { | |
clearTimeout(sortTimeout); | |
// Copy-on-write since tweens are evaluated after a delay. | |
var x0 = x.domain(data.sort(this.checked | |
? function(a, b) { return b.frequency - a.frequency; } | |
: function(a, b) { return d3.ascending(a.letter, b.letter); }) | |
.map(function(d) { return d.letter; })) | |
.copy(); | |
svg.selectAll(".bar") | |
.sort(function(a, b) { return x0(a.letter) - x0(b.letter); }); | |
var transition = svg.transition().duration(750 * 2), | |
delay = function(d, i) { return i * 50; }; | |
transition.selectAll(".bar") | |
.delay(delay) | |
.attr("x", function(d) { return x0(d.letter); }); | |
transition.select(".x.axis") | |
.call(xAxis) | |
.selectAll("g") | |
.delay(delay); | |
} | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment