A version of the previous block, but improved to speed the drawing and to make fast transitions.
Based on this block by Peter Beshai
<!DOCTYPE html>
<meta charset="utf-8">
<style>
</style>
<body>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
const width = 960,
height = 670;
const duration = 1500;
const ease = d3.easeCubic;
let timer;
let currLayout = 0;
var canvas = d3.select("body")
.append("canvas")
.attr('height', height)
.attr('width', width);
var context = canvas.node().getContext("2d");
var points = [];
var penes = [{'Nom':'Dotze anys i un dia de reclusió temporal', 'Nombre': 11348, 'Color': '#eded07'},
{'Nom':'Sobreseïment','Nombre': 10479, 'Color': '#afa'},
{'Nom':'Absolt','Nombre': 7204, 'Color': '#7f7'},
{'Nom':'Llibertat','Nombre': 6105, 'Color': '#8f8'},
{'Nom':'Sense declaració de responsabilitats','Nombre': 5469, 'Color': '#cfc'},
{'Nom':'Mort','Nombre': 4404, 'Color': '#f00'},
{'Nom':'Vint anys de reclusió temporal','Nombre': 3826, 'Color': '#d18400'},
{'Nom':'Reclusió perpètua','Nombre': 3740, 'Color': '#d15a00'},
{'Nom':'Quinze anys de reclusió temporal','Nombre': 3560, 'Color': '#d1aa00'},
{'Nom':'Arxiu','Nombre': 3360, 'Color': '#afa'},
{'Nom':'Sis anys i un dia de presó major','Nombre': 2022, 'Color': '#d1c600'},
{'Nom':'Trenta anys de reclusió major','Nombre': 665, 'Color': '#d16500'},
{'Nom':'Pena de multa','Nombre': 648, 'Color': '#b8d100'},
{'Nom':'Sis mesos i un dia de presó menor','Nombre': 548, 'Color': '#cad100'},
{'Nom':'Dotze anys i un dia de reclusió menor','Nombre': 516, 'Color': '#eded07'},
{'Nom':'Dotze anys de presó major','Nombre': 434, 'Color': '#eded07'},
{'Nom':'Destinat a Batalló de Treballadors o a','Nombre': 298, 'Color': '#156f72'},
{'Nom':'Un any de presó menor','Nombre': 298, 'Color': '#cad100'},
{'Nom':'Desglossament en un altre procediment','Nombre': 258, 'Color': '#bbb'},
{'Nom':'Absolt i un mes d\'arrest menor','Nombre': 199, 'Color': '#e5ed04'},
{'Nom':'Tres anys i un dia de presó menor','Nombre': 178, 'Color': '#d1c600'},
{'Nom':'Nou anys de presó major','Nombre': 178, 'Color': '#d1b800'},
{'Nom':'Vuit anys de presó major','Nombre': 171, 'Color': '#d1b800'},
{'Nom':'Vint anys de reclusió major','Nombre': 11, 'Color': '#d17600'},
{'Nom':'Altres','Nombre': 11, 'Color': '#aaa'},
];
var totalVictimes = 65990;
var j = 0;
penes.forEach(function(pena){
for(var i = 0; i<pena['Nombre']; i++){
points.push({'color': pena['Color'], 'x': width/2, 'y': height/2, 'order': j});
j++;
}
});
for(var i=j; i<totalVictimes; i++){
points.push('Altres');
}
function orderedLayout(points){
let stackHeight = 220;
points.forEach((point) => {
point.x = 3*Math.floor(point.order/stackHeight);
point.y = 3*(point.order%stackHeight);;
});
return points;
}
function randomLayout(points){
let stackHeight = 220;
shuffle(points)
points.forEach((point, i) => {
point.x = 3*Math.floor(i/stackHeight);
point.y = 3*(i%stackHeight);;
});
return points;
}
const layouts = [randomLayout, orderedLayout];
function draw() {
context.clearRect(0,0,canvas.attr("width"),canvas.attr("height"));
for (let i = 0; i < points.length; ++i) {
const point = points[i];
context.fillStyle = point.color;
context.fillRect(point.x, point.y, 2, 2);
}
}
function animate(layout) {
// store the source position
points.forEach(point => {
point.sx = point.x;
point.sy = point.y;
});
// get destination x and y position on each point
layout(points);
// store the destination position
points.forEach(point => {
point.tx = point.x;
point.ty = point.y;
});
timer = d3.timer((elapsed) => {
// compute how far through the animation we are (0 to 1)
const t = Math.min(1, ease(elapsed / duration));
// update point positions (interpolate between source and target)
points.forEach(point => {
point.x = point.sx * (1 - t) + point.tx * t;
point.y = point.sy * (1 - t) + point.ty * t;
});
// update what is drawn on screen
draw();
// if this animation is over
if (t === 1) {
timer.stop();
currLayout = (currLayout + 1) % layouts.length;
animate(layouts[currLayout]);
}
});
}
animate(layouts[currLayout]);
function shuffle(array) {
//https://stackoverflow.com/questions/2450954/how-to-randomize-shuffle-a-javascript-array
var currentIndex = array.length, temporaryValue, randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
</script>
</body>