Skip to content

Instantly share code, notes, and snippets.

@curran
Last active August 16, 2023 17:59
Show Gist options
  • Save curran/3094b37e63b918bab0a06787e161607b to your computer and use it in GitHub Desktop.
Save curran/3094b37e63b918bab0a06787e161607b to your computer and use it in GitHub Desktop.
D3 4.0 Sequential Scales Explorer
license: gpl-3.0
date bucket count
2012-07-20 800 119
2012-07-20 900 123
2012-07-20 1000 173
2012-07-20 1100 226
2012-07-20 1200 284
2012-07-20 1300 257
2012-07-20 1400 268
2012-07-20 1500 244
2012-07-20 1600 191
2012-07-20 1700 204
2012-07-20 1800 187
2012-07-20 1900 177
2012-07-20 2000 164
2012-07-20 2100 125
2012-07-20 2200 140
2012-07-20 2300 109
2012-07-20 2400 103
2012-07-21 800 123
2012-07-21 900 165
2012-07-21 1000 237
2012-07-21 1100 278
2012-07-21 1200 338
2012-07-21 1300 306
2012-07-21 1400 316
2012-07-21 1500 269
2012-07-21 1600 271
2012-07-21 1700 241
2012-07-21 1800 188
2012-07-21 1900 174
2012-07-21 2000 158
2012-07-21 2100 153
2012-07-21 2200 132
2012-07-22 900 154
2012-07-22 1000 241
2012-07-22 1100 246
2012-07-22 1200 300
2012-07-22 1300 305
2012-07-22 1400 301
2012-07-22 1500 292
2012-07-22 1600 253
2012-07-22 1700 251
2012-07-22 1800 214
2012-07-22 1900 189
2012-07-22 2000 179
2012-07-22 2100 159
2012-07-22 2200 161
2012-07-22 2300 144
2012-07-22 2400 139
2012-07-22 2500 132
2012-07-22 2600 136
2012-07-22 2800 105
2012-07-23 800 120
2012-07-23 900 156
2012-07-23 1000 209
2012-07-23 1100 267
2012-07-23 1200 299
2012-07-23 1300 316
2012-07-23 1400 318
2012-07-23 1500 307
2012-07-23 1600 295
2012-07-23 1700 273
2012-07-23 1800 283
2012-07-23 1900 229
2012-07-23 2000 192
2012-07-23 2100 193
2012-07-23 2200 170
2012-07-23 2300 164
2012-07-23 2400 154
2012-07-23 2500 138
2012-07-23 2600 101
2012-07-23 2700 115
2012-07-23 2800 103
2012-07-24 800 105
2012-07-24 900 156
2012-07-24 1000 220
2012-07-24 1100 255
2012-07-24 1200 308
2012-07-24 1300 338
2012-07-24 1400 318
2012-07-24 1500 255
2012-07-24 1600 278
2012-07-24 1700 260
2012-07-24 1800 235
2012-07-24 1900 230
2012-07-24 2000 185
2012-07-24 2100 145
2012-07-24 2200 147
2012-07-24 2300 157
2012-07-24 2400 109
2012-07-25 800 104
2012-07-25 900 191
2012-07-25 1000 201
2012-07-25 1100 238
2012-07-25 1200 223
2012-07-25 1300 229
2012-07-25 1400 286
2012-07-25 1500 256
2012-07-25 1600 240
2012-07-25 1700 233
2012-07-25 1800 202
2012-07-25 1900 180
2012-07-25 2000 184
2012-07-25 2100 161
2012-07-25 2200 125
2012-07-25 2300 110
2012-07-25 2400 101
2012-07-26 1300 132
2012-07-26 1400 117
2012-07-26 1500 124
2012-07-26 1600 154
2012-07-26 1700 167
2012-07-26 1800 137
2012-07-26 1900 169
2012-07-26 2000 175
2012-07-26 2100 168
2012-07-26 2200 188
2012-07-26 2300 137
2012-07-26 2400 173
2012-07-26 2500 164
2012-07-26 2600 167
2012-07-26 2700 115
2012-07-26 2800 116
2012-07-26 2900 118
2012-07-26 3000 125
2012-07-26 3200 104
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.label {
font-weight: bold;
}
.tile {
shape-rendering: crispEdges;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
#interpolators {
position: fixed;
top: 1px;
right: 1px;
}
</style>
</head>
<body>
<svg id="chart"></svg>
<select id="interpolators"></select>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/d3-scale-chromatic.v0.3.min.js"></script>
<script>
var margin = {top: 20, right: 90, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.timeParse("%Y-%m-%d"),
formatDate = d3.timeFormat("%b %d");
var x = d3.scaleTime().range([0, width]),
y = d3.scaleLinear().range([height, 0]),
z = d3.scaleSequential(d3.interpolateViridis);
// The size of the buckets in the CSV data file.
// This could be inferred from the data if it weren't sparse.
var xStep = 864e5,
yStep = 100;
var svg = d3.select("#chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv("data.csv", function(error, buckets) {
if (error) throw error;
// Coerce the CSV data to the appropriate types.
buckets.forEach(function(d) {
d.date = parseDate(d.date);
d.bucket = +d.bucket;
d.count = +d.count;
});
// Compute the scale domains.
x.domain(d3.extent(buckets, function(d) { return d.date; }));
y.domain(d3.extent(buckets, function(d) { return d.bucket; }));
z.domain([0, d3.max(buckets, function(d) { return d.count; })]);
// Extend the x- and y-domain to fit the last bucket.
// For example, the y-bucket 3200 corresponds to values [3200, 3300].
x.domain([x.domain()[0], +x.domain()[1] + xStep]);
y.domain([y.domain()[0], y.domain()[1] + yStep]);
// Display the tiles for each non-zero bucket.
// See http://bl.ocks.org/3074470 for an alternative implementation.
svg.selectAll(".tile")
.data(buckets)
.enter().append("rect")
.attr("class", "tile")
.attr("x", function(d) { return x(d.date); })
.attr("y", function(d) { return y(d.bucket + yStep); })
.attr("width", x(xStep) - x(0))
.attr("height", y(0) - y(yStep))
.style("fill", function(d) { return z(d.count); });
// Add a legend for the color values.
var legend = svg.selectAll(".legend")
.data(z.ticks(6).slice(1).reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(" + (width + 20) + "," + (20 + i * 20) + ")"; });
legend.append("rect")
.attr("width", 20)
.attr("height", 20)
.style("fill", z);
legend.append("text")
.attr("x", 26)
.attr("y", 10)
.attr("dy", ".35em")
.text(String);
svg.append("text")
.attr("class", "label")
.attr("x", width + 20)
.attr("y", 10)
.attr("dy", ".35em")
.text("Count");
// Add an x-axis with label.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom().scale(x).ticks(d3.timeDay).tickFormat(formatDate))
.append("text")
.attr("class", "label")
.attr("x", width)
.attr("y", -6)
.attr("text-anchor", "end")
.text("Date");
// Add a y-axis with label.
svg.append("g")
.attr("class", "y axis")
.call(d3.axisLeft().scale(y))
.append("text")
.attr("class", "label")
.attr("y", 6)
.attr("dy", ".71em")
.attr("text-anchor", "end")
.attr("transform", "rotate(-90)")
.text("Value");
var interpolators = [
// These are from d3-scale.
"Viridis",
"Inferno",
"Magma",
"Plasma",
"Warm",
"Cool",
"Rainbow",
"CubehelixDefault",
// These are from d3-scale-chromatic
"Blues",
"Greens",
"Greys",
"Oranges",
"Purples",
"Reds",
"BuGn",
"BuPu",
"GnBu",
"OrRd",
"PuBuGn",
"PuBu",
"PuRd",
"RdPu",
"YlGnBu",
"YlGn",
"YlOrBr",
"YlOrRd"
];
var autoCycle = setInterval(function (){
var node = d3.select("#interpolators").node();
var i = node.selectedIndex;
i = (i + 1) % interpolators.length;
setSelectedInterpolator(interpolators[i]);
node.selectedIndex = i;
}, 1000);
d3.select("#interpolators")
.on("change", function (){
setSelectedInterpolator(interpolators[this.selectedIndex]);
clearInterval(autoCycle);
})
.selectAll("option").data(interpolators)
.enter().append("option")
.attr("value", function (d){ return d; })
.text(function (d){ return d; });
function setSelectedInterpolator(name, transitionDuration){
if(typeof transitionDuration === "undefined"){
transitionDuration = 500;
}
z.interpolator(d3["interpolate" + name]);
svg.selectAll(".tile")
.transition().duration(transitionDuration)
.style("fill", function(d) { return z(d.count); });
svg.selectAll(".legend rect")
.transition().duration(transitionDuration)
.style("fill", z);
window.location.hash = name;
d3.select("#interpolators").node().selectedIndex = interpolators.indexOf(name);
}
if(window.location.hash){
clearInterval(autoCycle);
setSelectedInterpolator(window.location.hash.replace("#", ""), 0);
}
});
</script>
</body>
</html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment