const DURATION = 500; class Recorder { constructor(graph) { this.graph = graph; this.rendered = -1; this.rendering = false; this.states = new Array(); this.unblockRendering = ((recorder) => () => { recorder.rendering = false; })(this); this.initGraph(); } initGraph() { this.graph.transition(() => d3 .transition("main") .ease(d3.easeLinear) .on("end", this.unblockRendering) .delay(500) .duration(DURATION) ); } render() { if ( this.rendering || !this.states || this.rendered == this.states.length - 1 ) { return; } this.rendering = true; this.rendered++; this.graph.renderDot(this.states[this.rendered]); } previous() { throw "not implemented!"; } next() { throw "not implemented!"; } record(tree) { // TODO: adjust join if necessary this.states.push(tree.toDot().join("")); this.render(); } } let recorder = new Recorder(d3.select("#graph").graphviz()); let tree = new AVLTree(); tree.recorder = recorder; function insertCallback() { let number = document.getElementById("insertInput").value; if (number === "") { return false; } let value = parseInt(number); tree.insert(value); document.getElementById("insertInput").value = ""; return false; } function deleteCallback() { let number = document.getElementById("deleteInput").value; if (number === "") { return false; } let value = parseInt(number); tree.delete(value); document.getElementById("deleteInput").value = ""; return false; } function render() { recorder.render(); setTimeout(render); } render();