1
// Based on http://vis.stanford.edu/protovis/ex/sort.html
2
// Based on work by Robert Sedgewick
8
var x = d3.scale.linear()
10
.range([height, width - height]);
12
var a = d3.scale.linear()
14
.range([90 + 60, 270 - 60]);
16
var data = shuffle(d3.range(n)),
19
var vis = d3.select("#chart").append("svg")
21
.attr("height", height);
23
var line = vis.selectAll("line")
25
.enter().append("line")
30
.attr("transform", transform);
34
// Start the animation!
36
var passes = mergesort(data).reverse();
41
var pass = passes.pop();
43
line.data(pass, Number)
46
.attr("transform", transform);
49
setTimeout(update, duration);
52
setTimeout(start, duration + 4000);
57
function transform(d, i) {
58
return "translate(" + x(i) + "," + height + ")rotate(" + a(d) + ")";
61
// Fisher-Yates shuffle
62
function shuffle(array) {
63
var i = array.length, j, t;
65
j = ~~(Math.random() * (i + 1));
74
// Sorts the specified array using bottom-up mergesort, returning an array of
75
// arrays representing the state of the specified array after each insertion for
76
// each parallel pass. The first pass is performed at size = 2.
78
function mergesort(array) {
85
// double the size each pass
86
while (m < array.length) {
87
i = j = 0; while (i < array.length) j += merge(i, i += m, i += m);
88
if (j) passes.push(array.slice());
92
// Merges two adjacent sorted arrays in-place.
93
function merge(start, middle, end) {
94
middle = Math.min(array.length, middle);
95
end = Math.min(array.length, end);
96
for (; start < middle; start++) {
97
if (array[start] > array[middle]) {
99
array[start] = array[middle];
100
insert(middle, end, v);
107
// Inserts the value v into the subarray specified by start and end.
108
function insert(start, end, v) {
109
while (start + 1 < end && array[start + 1] < v) {
110
var tmp = array[start];
111
array[start] = array[start + 1];
112
array[start + 1] = tmp;