Built with blockbuilder.org
Last active
April 15, 2019 16:48
-
-
Save bhison/017d2ba5b183b9ad30cc6a0742e67f2c to your computer and use it in GitHub Desktop.
d3 canvas tutorial from scratch
This file contains hidden or 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: mit |
This file contains hidden or 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> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
</style> | |
</head> | |
<body> | |
<script> | |
var data = []; | |
d3.range(5000).forEach(function(el) { | |
data.push({ value:el }); | |
}); | |
var width = 750, height = 400; | |
var canvas = d3.select('#container') | |
.append('canvas') | |
.attr('width', width) | |
.attr('height', height); | |
var context = canvas.node().getContext('2d'); | |
var customBase = document.createElement('custom'); | |
var custom = d3.select(customBase); //parent to all elements (instead of SVG) | |
var groupSpacing = 4, | |
cellSpacing = 2, | |
offset = height / 2, | |
cellSize = Math.floor((width - 11 * groupSpacing) / 100) - cellSpacing; | |
function databind(data){ | |
colourScale = d3.scaleSequential(d3.interpolateSpectral) | |
.domain(d3.extent(data, function(d) { return d; })); | |
var join = custom.selectAll('custom.rect') | |
.data(data); | |
var enterSel = join.enter() | |
.append('custom') | |
.attr('class', 'rect') | |
.attr('x', function(d, i) { | |
var x0 = Math.floor(i / 100) % 10, x1 = Math.floor(i % 10); | |
return groupSpacing * x0 + (cellSpacing + cellSize) * (x1 + x0 * 10); | |
}) | |
.attr('y', function(d, i) { | |
var y0 = Math.floor(i / 1000), y1 = Math.floor(i % 100 / 10); | |
return groupSpacing * y0 + (cellSpacing + cellSize) * (y1 + y0 * 10); | |
}) | |
.attr('width', 0) | |
.attr('height', 0); | |
join | |
.merge(enterSel) | |
.transition() | |
.attr('width', cellSize) | |
.attr('height', cellSize) | |
//[TS] .attr not .style - we just want data attached to element | |
.attr('fillStyle', function(d) { return colourScale(d); }); | |
var exitSel = join.exit() | |
.transition() | |
.attr('width', 0) | |
.attr('height', 0) | |
.remove(); | |
} // databind() | |
function draw() { | |
context.clearRect(0, 0, width, height); // Clear the canvas. | |
//selects children of custom with class of rect to use for databind() | |
var elements = custom.selectAll('custom.rect'); | |
elements.each(function(d,i) { // For each virtual/custom element... | |
var node = d3.select(this); | |
//Get the fillStyle from the node and apply it to the context | |
context.fillStyle = node.attr('fillStyle'); | |
//Sets the position using fillRect with values from attributes | |
context.fillRect( | |
node.attr('x'), node.attr('y'), node.attr('width'), node.attr('height') | |
); | |
}) | |
} // draw() | |
// === First call === // | |
databind(d3.range(value)); // Build the custom elements in memory. | |
var t = d3.timer(function(elapsed) { | |
draw(); | |
if (elapsed > 300) t.stop(); | |
}); // Timer running the draw function repeatedly for 300 ms. | |
//=From: https://medium.freecodecamp.org/d3-and-canvas-in-3-steps-8505c8b27444 | |
////////GOT TO "Let the user update the number of squares" | |
</script> | |
<h3>Coloured Grid</h3> | |
<input type='text' id='text-input' value='5000'> | |
<div id='text-explain'>...takes numbers between 1 and 10k</div> | |
<div id='container'></div> | |
</body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment