/** * */ 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; };