JSFiddle - React, Tailwind, and code Playground
HTML
<h2>Lucene PriorityQueue animation</h2>
<table>
<tr>
<td>Add doc with score:</td>
<td>
<button data-bind="disable: animating, click: function () { insertAndShow(10) }">10</button>
<button data-bind="disable: animating, click: function () { insertAndShow(20) }">20</button>
<button data-bind="disable: animating,click: function () { insertAndShow(30) }">30</button>
<button data-bind="disable: animating,click: function () { insertAndShow(40) }">40</button>
<button data-bind="disable: animating, click: function () { insertAndShow(50) }">50</button>
<button data-bind="disable: animating, click: function () { addRandom() }">Add Randoms</button>
</td>
</tr>
<tr>
<td>Remove top doc:</td>
<td>
<button data-bind="disable: animating,click: function () { doPop() }">Pop</button>
</td>
</tr>
</table>
<em>Click on a bar to remove an entry</em>
<svg id="svgCanvas" width="100%" height="120" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg" pointer-events="all" preserveAspectRatio="xMidYMid slice">
<g>
<g id="viewport">
<line stroke="#000000" id="svg_3" data-bind="attr:{x1:1, x2:500, y2:100, y1:100}" fill="none" />
<g data-bind="foreach: slots">
<rect fill="#007fff" stroke-width="0" data-bind="attr:{x:x,y:y, width:width, height:height, class:clazz} ,click: function () { $root.doRemove($data) }" />
<text text-anchor="right" font-family="Sans-serif" font-size="8" data-bind="text:doc, attr:{x:x,y:120}"></text>
</g>
</g>
</g>
</svg> <span data-bind="text:status"></span>
CSS
.changedSlot {
fill:red;
}
.unchangedSlot {
fill:gray;
}
body {
font-family:"Helvetica", "Arial", "FreeSans", "Verdana", "Tahoma", "Lucida Sans", "Lucida Sans Unicode", "Luxi Sans", sans-serif;
font-size:12px;
}
JavaScript
function ScoreDoc(score, doc) {
var self = this;
self.doc = doc;
self.score = score;
}
// For display purposes
function Bar(scoreDoc, pos) {
var self = this;
self.width = 10;
self.clazz = "unchangedSlot";
self.doc = scoreDoc.doc;
self.pos = pos;
self.x = pos * (self.width + 2);
self.score = scoreDoc.score;
self.height = self.score;
self.y = 100 - self.height;
}
function AlgoViewModel() {
var self = this;
//PriorityQueue variables
self.size = 0;
self.maxSize = 40;
self.heap = [null, null];
//Display data
self.animating = false;
self.status = ko.observable();
self.docNum = 0;
self.slots = ko.observableArray();
self.snapshotNum = 0;
self.snapshots = [];
self.animPause=10;
//PriorityQueue functions
self.add = function (val) {
self.docNum++;
var element = new ScoreDoc(val, self.docNum);
self.size++;
self.heap[self.size] = element;
self.addSnapshot(element);
self.upHeap();
}
//Change - new function to remove element
self.remove = function (element) {
if (self.size == 0) {
return false;
}
for (var i = 1; i <= self.size; i++) {
//have to compare doc ids here rather than object==object
if (self.heap[i].doc == element.doc) {
self.heap[i] = self.heap[self.size];
self.addSnapshot(self.heap[i]);
self.size--;
self.addSnapshot(null);
//Change- downHeap now takes a parameter
self.downHeap(i);
self.startAnimation();
return;
}
}
}
self.pop = function () {
if (self.size > 0) {
var result = self.heap[1]; // save first value
self.heap[1] = self.heap[self.size]; // move last to first
self.addSnapshot(self.heap[1]);
self.heap[self.size] = null; //...