--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/toolkit/javascript/d3/examples/sort/sort.js Thu Apr 10 14:20:23 2014 +0200
@@ -0,0 +1,112 @@
+// Based on http://vis.stanford.edu/protovis/ex/sort.html
+// Based on work by Robert Sedgewick
+
+var w = 960,
+ h = 50,
+ n = 240,
+ x = d3.scale.linear().domain([0, n]).range([h, w - h]),
+ a = d3.scale.linear().domain([0, n - 1]).range([90 + 60, 270 - 60]),
+ data = shuffle(d3.range(n)),
+ duration = 250;
+
+var vis = d3.select("#chart").append("svg:svg")
+ .attr("width", w)
+ .attr("height", h);
+
+var line = vis.selectAll("line")
+ .data(data)
+ .enter().append("svg:line")
+ .attr("x1", 0)
+ .attr("y1", 0)
+ .attr("x2", 0)
+ .attr("y2", h)
+ .attr("transform", transform);
+
+start();
+
+// Start the animation!
+function start() {
+ var passes = mergesort(data).reverse();
+
+ update();
+
+ function update() {
+ var pass = passes.pop();
+
+ line.data(pass, Number)
+ .transition()
+ .duration(duration)
+ .attr("transform", transform);
+
+ if (passes.length) {
+ setTimeout(update, duration);
+ } else {
+ shuffle(data);
+ setTimeout(start, duration + 4000);
+ }
+ }
+}
+
+function transform(d, i) {
+ return "translate(" + x(i) + "," + h + ")rotate(" + a(d) + ")";
+}
+
+// Fisher-Yates shuffle
+function shuffle(array) {
+ var i = array.length, j, t;
+ while (--i > 0) {
+ j = ~~(Math.random() * (i + 1));
+ t = array[j];
+ array[j] = array[i];
+ array[i] = t;
+ }
+ return array;
+}
+
+//
+// Sorts the specified array using bottom-up mergesort, returning an array of
+// arrays representing the state of the specified array after each insertion for
+// each parallel pass. The first pass is performed at size = 2.
+//
+function mergesort(array) {
+ var passes = [],
+ i,
+ j,
+ n = array.length,
+ m = 1;
+
+ // double the size each pass
+ while (m < array.length) {
+ i = j = 0; while (i < array.length) j += merge(i, i += m, i += m);
+ if (j) passes.push(array.slice());
+ else m <<= 1;
+ }
+
+ // Merges two adjacent sorted arrays in-place.
+ function merge(start, middle, end) {
+ middle = Math.min(array.length, middle);
+ end = Math.min(array.length, end);
+ for (; start < middle; start++) {
+ if (array[start] > array[middle]) {
+ var v = array[start];
+ array[start] = array[middle];
+ insert(middle, end, v);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // Inserts the value v into the subarray specified by start and end.
+ function insert(start, end, v) {
+ while (start + 1 < end && array[start + 1] < v) {
+ var tmp = array[start];
+ array[start] = array[start + 1];
+ array[start + 1] = tmp;
+ start++;
+ }
+ array[start] = v;
+ }
+
+ return passes;
+}