You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
318 lines
9.0 KiB
318 lines
9.0 KiB
/**
|
|
*
|
|
*/
|
|
Visualizer.prototype.initItems = function(n) {
|
|
var data = this.sorter.generate(n);
|
|
var shuffled = this.sorter.shuffle(data);
|
|
var ordered = Object.create(shuffled);
|
|
ordered = this.sorter.sort(ordered, 0, ordered.length - 1);
|
|
|
|
// A swap on the dataset will not take effect until after transition is complete, so custom index is required.
|
|
var n = 0;
|
|
for (var i in shuffled) {
|
|
shuffled[i].index = n++;
|
|
}
|
|
|
|
if (this.svg !== undefined) {
|
|
this.svg.remove();
|
|
}
|
|
|
|
this.instructionIndex = 0;
|
|
this.svg = d3.select(this.parent).append('svg')
|
|
.attr('class', 'sorter-svg');
|
|
|
|
// Items
|
|
this.groups = this.svg.selectAll('g').data(shuffled).enter().insert('g')
|
|
.attr('transform', `translate(0, ${Visualizer.itemY})`);
|
|
|
|
this.groups.append('rect')
|
|
.attr('class', 'item')
|
|
.attr('height', Visualizer.itemH)
|
|
.attr('width', Visualizer.itemW)
|
|
.attr('fill', function doFill(d) { return d.fill; });
|
|
|
|
this.groups.transition(500)
|
|
.attr('transform', function doTransform(d, i) {
|
|
return `translate(${i * (Visualizer.itemW + Visualizer.spacerW) + Visualizer.spacerW}, ${Visualizer.itemY})`;
|
|
});
|
|
|
|
// Item labels
|
|
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)`;
|
|
});
|
|
|
|
// Markers
|
|
var m1 = this.svg.append('g')
|
|
.attr('class', 'marker')
|
|
.attr('id', 'marker1')
|
|
.attr('transform', `translate(${Visualizer.spacerW}, ${Visualizer.spacerW})`);
|
|
|
|
m1.append('rect')
|
|
.attr('height', Visualizer.itemW)
|
|
.attr('width', Visualizer.itemW);
|
|
|
|
m1.append('text')
|
|
.attr('text-anchor', 'middle')
|
|
.attr('x', (Visualizer.itemW / 2))
|
|
.attr('y', 10);
|
|
|
|
var m2 = this.svg.append('g')
|
|
.attr('transform', `translate(${Visualizer.spacerW}, ${Visualizer.spacerW})`)
|
|
.attr('class', 'marker')
|
|
.attr('style', 'display:none')
|
|
.attr('id', 'marker2');
|
|
|
|
m2.append('rect')
|
|
.attr('height', Visualizer.itemW)
|
|
.attr('width', Visualizer.itemW);
|
|
|
|
m2.append('text')
|
|
.attr('text-anchor', 'middle')
|
|
.attr('x', (Visualizer.itemW / 2))
|
|
.attr('y', 10);
|
|
};
|
|
|
|
/**
|
|
*
|
|
*/
|
|
Visualizer.prototype.initMessages = function() {
|
|
var container = document.createElement('div');
|
|
container.className = 'message-container';
|
|
|
|
var div1 = document.createElement('div');
|
|
div1.className = 'message';
|
|
|
|
var div2 = document.createElement('div');
|
|
div2.className = 'message';
|
|
|
|
var div3 = document.createElement('div');
|
|
div3.className = 'message';
|
|
|
|
var div4 = document.createElement('div');
|
|
div4.className = 'message';
|
|
div4.innerHTML = 'Comparisons: 0';
|
|
|
|
var div5 = document.createElement('div');
|
|
div5.className = 'message';
|
|
div5.innerHTML = 'Swaps: 0';
|
|
|
|
div1.innerHTML = 'testing';
|
|
div2.innerHTML = 'testing';
|
|
div3.innerHTML = 'testing';
|
|
div4.innerHTML = 'testing';
|
|
div5.innerHTML = 'testing';
|
|
|
|
container.appendChild(div1);
|
|
container.appendChild(div2);
|
|
container.appendChild(div3);
|
|
container.appendChild(div4);
|
|
container.appendChild(div5);
|
|
|
|
return container;
|
|
};
|
|
|
|
/**
|
|
*
|
|
*/
|
|
Visualizer.prototype.initRange = function() {
|
|
var rangeInput = function(label, event) {
|
|
label.innerHTML = 'Number of items (n) = ' + event.target.value;
|
|
};
|
|
|
|
var rangeChange = function(event) {
|
|
this.initItems(event.target.value);
|
|
};
|
|
|
|
var container = document.createElement('div');
|
|
container.className = 'range-container';
|
|
|
|
var msg = document.createElement('div');
|
|
msg.className = 'msg';
|
|
msg.innerHTML = "Number of items (n) = 10";
|
|
|
|
var range = document.createElement('input');
|
|
range.setAttribute('type', 'range');
|
|
range.setAttribute('value', 10);
|
|
range.setAttribute('min', 10);
|
|
range.setAttribute('max', 40);
|
|
range.addEventListener('change', rangeChange.bind(this));
|
|
range.addEventListener('input', rangeInput.bind(null, msg));
|
|
|
|
container.appendChild(range);
|
|
container.appendChild(msg);
|
|
|
|
return container;
|
|
},
|
|
|
|
/**
|
|
*
|
|
*/
|
|
Visualizer.prototype.initControls = function() {
|
|
var updatePlayPause = function(paused) {
|
|
if (paused === true) {
|
|
play.className = 'fa fa-pause';
|
|
}
|
|
else {
|
|
play.className = 'fa fa-play';
|
|
}
|
|
};
|
|
|
|
var playclick = function() {
|
|
this.paused = !this.paused;
|
|
updatePlayPause(this.paused);
|
|
this.followInstruction();
|
|
};
|
|
|
|
var backclick = function() {
|
|
this.paused = true;
|
|
this.instructionIndex--;
|
|
this.followInstruction();
|
|
};
|
|
|
|
var forwardclick = function() {
|
|
this.paused = true;
|
|
this.followInstruction();
|
|
this.instructionIndex++;
|
|
};
|
|
|
|
var restartclick = function() {
|
|
this.paused = false;
|
|
updatePlayPause(this.paused);
|
|
this.instructionIndex = 0;
|
|
this.followInstruction();
|
|
};
|
|
|
|
var play = document.createElement('button');
|
|
play.className = 'fa fa-play';
|
|
play.title = 'Play'
|
|
play.addEventListener('click', playclick.bind(this));
|
|
|
|
var back = document.createElement('button');
|
|
back.className = 'fa fa-step-backward';
|
|
back.title = 'Step Backward';
|
|
back.addEventListener('click', backclick.bind(this));
|
|
|
|
var forward = document.createElement('button');
|
|
forward.className = 'fa fa-step-forward'
|
|
forward.title = 'Step Forward';
|
|
forward.addEventListener('click', forwardclick.bind(this));
|
|
|
|
var reset = document.createElement('button');
|
|
reset.className = 'fa fa-fast-backward';
|
|
reset.title = 'Restart'
|
|
reset.addEventListener('click', restartclick.bind(this));
|
|
|
|
var container = document.createElement('div');
|
|
container.className = 'controls-container';
|
|
|
|
container.appendChild(reset);
|
|
container.appendChild(back);
|
|
container.appendChild(play);
|
|
container.appendChild(forward);
|
|
|
|
return container;
|
|
};
|
|
|
|
Visualizer.prototype.initProperties = function() {
|
|
// Div 1
|
|
var div1 = document.createElement('div');
|
|
div1.className = 'property p1';
|
|
|
|
var title1 = document.createElement('div');
|
|
title1.innerHTML = 'Stable';
|
|
title1.className = 'title';
|
|
div1.appendChild(title1);
|
|
|
|
var value1 = document.createElement('div');
|
|
value1.className = 'value';
|
|
value1.innerHTML = this.parent.attributes['data-stable'].value;
|
|
div1.appendChild(value1);
|
|
|
|
// Div 2
|
|
var div2 = document.createElement('div');
|
|
div2.className = 'property p2';
|
|
|
|
var title2 = document.createElement('div');
|
|
title2.innerHTML = 'Adaptive';
|
|
title2.className = 'title';
|
|
div2.appendChild(title2);
|
|
|
|
var value2 = document.createElement('div');
|
|
value2.className = 'value';
|
|
value2.innerHTML = this.parent.attributes['data-adaptive'].value;
|
|
div2.appendChild(value2);
|
|
|
|
// Div 3
|
|
var div3 = document.createElement('div');
|
|
div3.className = 'property p3';
|
|
|
|
var title3 = document.createElement('div');
|
|
title3.innerHTML = 'Worst Performance';
|
|
title3.className = 'title';
|
|
div3.appendChild(title3);
|
|
|
|
var value3 = document.createElement('div');
|
|
value3.className = 'value';
|
|
value3.innerHTML = this.parent.attributes['data-worst-perf'].value;
|
|
div3.appendChild(value3);
|
|
|
|
// Div 4
|
|
var div4 = document.createElement('div');
|
|
div4.className = 'property p4';
|
|
|
|
var title4 = document.createElement('div');
|
|
title4.innerHTML = 'Average Performance';
|
|
title4.className = 'title';
|
|
div4.appendChild(title4);
|
|
|
|
var value4 = document.createElement('div');
|
|
value4.className = 'value';
|
|
value4.innerHTML = this.parent.attributes['data-avg-perf'].value;
|
|
div4.appendChild(value4);
|
|
|
|
// Div 5
|
|
var div5 = document.createElement('div');
|
|
div5.className = 'property p5';
|
|
|
|
var title5 = document.createElement('div');
|
|
title5.innerHTML = 'Best Performance';
|
|
title5.className = 'title';
|
|
div5.appendChild(title5);
|
|
|
|
var value5 = document.createElement('div');
|
|
value5.className = 'value';
|
|
value5.innerHTML = this.parent.attributes['data-best-perf'].value;
|
|
div5.appendChild(value5);
|
|
|
|
// Div 6
|
|
var div6 = document.createElement('div');
|
|
div6.className = 'property p6';
|
|
|
|
var title6 = document.createElement('div');
|
|
title6.innerHTML = 'Worst Memory';
|
|
title6.className = 'title';
|
|
div6.appendChild(title6);
|
|
|
|
var value6 = document.createElement('div');
|
|
value6.className = 'value';
|
|
value6.innerHTML = this.parent.attributes['data-worst-memory'].value;
|
|
div6.appendChild(value6);
|
|
|
|
// Container
|
|
var container = document.createElement('div');
|
|
container.className = 'sorter-properties';
|
|
|
|
container.appendChild(div1);
|
|
container.appendChild(div2);
|
|
container.appendChild(div3);
|
|
container.appendChild(div4);
|
|
container.appendChild(div5);
|
|
container.appendChild(div6);
|
|
|
|
return container;
|
|
};
|
|
|