This is the second step of my first attempt to learn canvas. I want to improve a piece a made a few weeks ago about the division of occupations. The d3.js version has so many DOM elements due to all the small bar charts that it is very slow. Therefore, I hope that a canvas version might improve things.
In this block I create a static circle pack layout that only uses D3 for the initialization, scales and such. But the visual is drawn with pure canvas, based on the data supplied by the d3 pack layout
I wrote a more extensive tutorial around what I learned while doing this project in my blog Learnings from a D3.js addict on starting with Canvas in which this can be seen as step 2. See the previous step in which d3.js still played a much bigger role here and the next step that has become a zoomable circle pack (but with a jitter) here
If you want to see the final result, with everything up and running in canvas look here
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<!-- D3.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js" charset="utf-8"></script>
</head>
<body>
<div id="chart"></div>
<script>
//////////////////////////////////////////////////////////////
////////////////// Create Set-up variables //////////////////
//////////////////////////////////////////////////////////////
var width = Math.max(document.getElementById("chart").offsetWidth,350) - 20,
height = (window.innerWidth < 768 ? width : window.innerHeight - 20);
//Size of the circle pack layout
var diameter = Math.min(width*0.9, height*0.9);
//The grey colors of the circles depend on the depth
var colorCircle = d3.scale.ordinal()
.domain([0,1,2,3])
.range(['#bfbfbf','#838383','#4c4c4c','#1c1c1c']);
//Initialize the circle pack layout
var pack = d3.layout.pack()
.padding(1)
.size([diameter, diameter])
.value(function(d) { return d.size; })
.sort(function(d) { return d.ID; }); //Creates a more interesting visual I think
//////////////////////////////////////////////////////////////
/////////////////////// Create Canvas ////////////////////////
//////////////////////////////////////////////////////////////
//Create the canvas and context
var canvas = d3.select("#chart").append("canvas")
.attr("id", "canvas")
.attr("width", width)
.attr("height", height);
var context = canvas.node().getContext("2d");
context.clearRect(0, 0, width, height);
//////////////////////////////////////////////////////////////
////////////////// Create Circle Packing /////////////////////
//////////////////////////////////////////////////////////////
d3.json("occupation.json", function(error, dataset) {
var nodes = pack.nodes(dataset);
//Loop over the nodes dataset and draw each circle to the canvas
for (var i = 0; i < nodes.length; i++) {
//Select one of the nodes/circles
var node = nodes[i];
//Draw each circle
context.fillStyle = node.children ? colorCircle(node.depth) : "white";
context.beginPath();
context.arc(node.x, node.y, node.r, 0, 2 * Math.PI, true);
context.fill();
context.closePath();
};
});
</script>
</body>
</html>