|
|
|
@ -10,18 +10,56 @@ function Visualizer(parent) { |
|
|
|
|
bottom.className = 'bottom'; |
|
|
|
|
parent.appendChild(bottom); |
|
|
|
|
|
|
|
|
|
var range = this.initRange(); |
|
|
|
|
parent.querySelector('.bottom').appendChild(range); |
|
|
|
|
|
|
|
|
|
var controls = this.initControls(); |
|
|
|
|
parent.querySelector('.bottom').appendChild(controls); |
|
|
|
|
|
|
|
|
|
var comments = this.initComments(); |
|
|
|
|
parent.querySelector('.bottom').appendChild(comments); |
|
|
|
|
|
|
|
|
|
var range = this.initRange(); |
|
|
|
|
parent.querySelector('.bottom').appendChild(range); |
|
|
|
|
|
|
|
|
|
this.groups = null; |
|
|
|
|
this.parent = parent; |
|
|
|
|
this.init(10); |
|
|
|
|
this.sorter = null; |
|
|
|
|
|
|
|
|
|
switch(parent.attributes['data-algorithm'].value) { |
|
|
|
|
case 'quick': |
|
|
|
|
this.sorter = new QuickSort(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'merge': |
|
|
|
|
this.sorter = new MergeSort(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'selection': |
|
|
|
|
this.sorter = new SelectionSort(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'bubble': |
|
|
|
|
this.sorter = new BubbleSort(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'insertion': |
|
|
|
|
this.sorter = new InsertionSort(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'shell': |
|
|
|
|
this.sorter = new ShellSort(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'radix': |
|
|
|
|
this.sorter = new RadixSort(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
throw new Error('Unrecognized sort type.'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// this.instructions = null;
|
|
|
|
|
// this.currentInstruction = 0;
|
|
|
|
|
|
|
|
|
|
this.init(10); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Public static properties (mutable)
|
|
|
|
@ -34,61 +72,51 @@ Visualizer.itemY = 20; |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
Visualizer.prototype.init = function(n) { |
|
|
|
|
// Sorter setup.
|
|
|
|
|
var QS = new Quicksort(); |
|
|
|
|
var data = QS.generate(n); |
|
|
|
|
var shuffled = QS.shuffle(data); |
|
|
|
|
var data = this.sorter.generate(n); |
|
|
|
|
var shuffled = this.sorter.shuffle(data); |
|
|
|
|
var ordered = Object.create(shuffled); |
|
|
|
|
QS.sort(ordered, 0, ordered.length - 1); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var x = [] |
|
|
|
|
ordered.forEach(function(obj0) { |
|
|
|
|
x.push(obj0.value); |
|
|
|
|
}) |
|
|
|
|
ordered = this.sorter.sort(ordered, 0, ordered.length - 1); |
|
|
|
|
|
|
|
|
|
console.log(x.join(',')); |
|
|
|
|
// console.log(ordered);
|
|
|
|
|
|
|
|
|
|
// A swap on the dataset will not take effect until after transition is complete, so custom index is required.
|
|
|
|
|
var n = 0; |
|
|
|
|
for (i in shuffled) { |
|
|
|
|
shuffled[i].index = n++; |
|
|
|
|
} |
|
|
|
|
// var x = []
|
|
|
|
|
// ordered.forEach(function(obj0) {
|
|
|
|
|
// x.push(obj0.value);
|
|
|
|
|
// })
|
|
|
|
|
|
|
|
|
|
var svg = d3.select(this.parent.querySelector('.top')).append('svg'); |
|
|
|
|
// console.log(x.join(','));
|
|
|
|
|
|
|
|
|
|
this.groups = svg.selectAll('g').data(shuffled).enter().append('g') |
|
|
|
|
.attr('transform', `translate(0, ${Visualizer.itemY})`); |
|
|
|
|
// // A swap on the dataset will not take effect until after transition is complete, so custom index is required.
|
|
|
|
|
// var n = 0;
|
|
|
|
|
// for (i in shuffled) {
|
|
|
|
|
// shuffled[i].index = n++;
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
this.groups.append('rect') |
|
|
|
|
.attr('height', Visualizer.itemH) |
|
|
|
|
.attr('width', Visualizer.itemW) |
|
|
|
|
.attr('fill', function doFill(d) { return `rgb(0, 0, ${d.value})`; }); |
|
|
|
|
// var svg = d3.select(this.parent.querySelector('.top')).append('svg');
|
|
|
|
|
|
|
|
|
|
this.groups.transition(500) |
|
|
|
|
.attr('transform', function doTransform(d, i) { |
|
|
|
|
return `translate(${i * (Visualizer.itemW + Visualizer.spacerW)}, ${Visualizer.itemY})`; |
|
|
|
|
}); |
|
|
|
|
// this.groups = svg.selectAll('g').data(shuffled).enter().append('g')
|
|
|
|
|
// .attr('transform', `translate(0, ${Visualizer.itemY})`);
|
|
|
|
|
|
|
|
|
|
this.groups.append('text') |
|
|
|
|
.text(function t(d) { return d.value; }) |
|
|
|
|
.attr('fill', '#aaa') |
|
|
|
|
.attr('font-size', 10) |
|
|
|
|
.attr('font-family', 'sans-serif') |
|
|
|
|
.attr('transform', function doTransform(d) { |
|
|
|
|
return `rotate(90 0,0), translate(5, -3)`; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// V.addMarker('quicksort-left-marker');
|
|
|
|
|
// V.moveMarker('quicksort-left-marker', 2);
|
|
|
|
|
|
|
|
|
|
// this.svg.append('sometext').id('left-marker'); L
|
|
|
|
|
// this.svg.append('sometext').id('right-marker'); R
|
|
|
|
|
// this.svg.append('sometext').id('pivot-marker'); triangle or arrow
|
|
|
|
|
// this.groups.append('rect')
|
|
|
|
|
// .attr('height', Visualizer.itemH)
|
|
|
|
|
// .attr('width', Visualizer.itemW)
|
|
|
|
|
// .attr('fill', function doFill(d) { return `rgb(0, 0, ${d.value})`; });
|
|
|
|
|
|
|
|
|
|
// this.groups.transition(500)
|
|
|
|
|
// .attr('transform', function doTransform(d, i) {
|
|
|
|
|
// return `translate(${i * (Visualizer.itemW + Visualizer.spacerW)}, ${Visualizer.itemY})`;
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
// this.groups.append('text')
|
|
|
|
|
// .text(function t(d) { return d.value; })
|
|
|
|
|
// .attr('fill', '#aaa')
|
|
|
|
|
// .attr('font-size', 10)
|
|
|
|
|
// .attr('font-family', 'sans-serif')
|
|
|
|
|
// .attr('transform', function doTransform(d) {
|
|
|
|
|
// return `rotate(90 0,0), translate(5, -3)`;
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
setTimeout(this.followInstruction.bind(this, QS.instructions, 0), 500); |
|
|
|
|
// setTimeout(this.followInstruction.bind(this, QS.instructions, 0), 500);
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -113,31 +141,6 @@ Visualizer.prototype.swap = function(indexA, indexB) { |
|
|
|
|
}) |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
* / |
|
|
|
|
Visualizer.prototype.moveMarker = function(id, toIndex) { |
|
|
|
|
this.svg.select('#' + id).attr('x', toIndex * 22); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
* / |
|
|
|
|
Visualizer.prototype.addMarker = function(id) { |
|
|
|
|
// this.svg.append('text')
|
|
|
|
|
// .attr('id', id)
|
|
|
|
|
// .attr('x', 53)
|
|
|
|
|
// .attr('y', 50)
|
|
|
|
|
// .attr('width', 20)
|
|
|
|
|
// .attr('height', 20)
|
|
|
|
|
// .attr('fill', '#aaa')
|
|
|
|
|
// .attr('font-size', 20)
|
|
|
|
|
// .attr('alignment-baseline', 'middle')
|
|
|
|
|
// .attr('text-anchor', 'middle')
|
|
|
|
|
// .attr('transform', 'rotate(0 53,50)')
|
|
|
|
|
// .text('P');
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
@ -195,11 +198,33 @@ Visualizer.prototype.followInstruction = function(instructions, index) { |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
Visualizer.prototype.initComments = function() { |
|
|
|
|
var container = document.createElement('div'); |
|
|
|
|
container.className = 'comment-container'; |
|
|
|
|
|
|
|
|
|
var div1 = document.createElement('div'); |
|
|
|
|
div1.className = 'comment'; |
|
|
|
|
|
|
|
|
|
var div2 = document.createElement('div'); |
|
|
|
|
div2.className = 'comment'; |
|
|
|
|
|
|
|
|
|
var div3 = document.createElement('div'); |
|
|
|
|
div3.className = 'comment'; |
|
|
|
|
|
|
|
|
|
container.appendChild(div1); |
|
|
|
|
container.appendChild(div2); |
|
|
|
|
container.appendChild(div3); |
|
|
|
|
|
|
|
|
|
return container; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* |
|
|
|
|
*/ |
|
|
|
|
Visualizer.prototype.initRange = function(Visualizer) { |
|
|
|
|
Visualizer.prototype.initRange = function() { |
|
|
|
|
var container = document.createElement('div'); |
|
|
|
|
container.className = 'range-container'; |
|
|
|
|
|
|
|
|
@ -259,7 +284,7 @@ Visualizer.prototype.initControls = function() { |
|
|
|
|
reset.addEventListener('click', onclick); |
|
|
|
|
|
|
|
|
|
var container = document.createElement('div'); |
|
|
|
|
container.className = 'controls'; |
|
|
|
|
container.className = 'controls-container'; |
|
|
|
|
|
|
|
|
|
container.appendChild(reset); |
|
|
|
|
container.appendChild(back); |
|
|
|
|