144 lines
2.9 KiB
JavaScript
144 lines
2.9 KiB
JavaScript
var dotSourceList = {{ dot_source_list|tojson }};
|
|
|
|
var state = {
|
|
transitionDelay: 0,
|
|
index: 0,
|
|
playing: false,
|
|
}
|
|
var controls = {
|
|
index: null,
|
|
buttons: {
|
|
next: null,
|
|
prev: null,
|
|
toggle: null,
|
|
},
|
|
slider: null,
|
|
}
|
|
var graph = null;
|
|
|
|
/////////////
|
|
// Helpers //
|
|
/////////////
|
|
// From https://stackoverflow.com/a/37623959/1931274
|
|
function onRangeChange(r, f) {
|
|
var n, c, m;
|
|
r.addEventListener("input", function (e) {
|
|
n = 1; c = e.target.value; if (c != m) { f(e); }; m = c;
|
|
});
|
|
r.addEventListener("change", function (e) { if (!n) { f(e); }});
|
|
}
|
|
|
|
//////////////
|
|
// UI Logic //
|
|
//////////////
|
|
function setupControls() {
|
|
controls.index = document.getElementById("index");
|
|
|
|
controls.buttons.next = document.getElementById("next");
|
|
controls.buttons.next.onclick = showNext;
|
|
|
|
controls.buttons.prev = document.getElementById("prev");
|
|
controls.buttons.prev.onclick = showPrevious;
|
|
|
|
controls.buttons.toggle = document.getElementById("toggle");
|
|
controls.buttons.toggle.onclick = toggle;
|
|
|
|
controls.slider = document.getElementById("slider");
|
|
controls.slider.setAttribute("max", dotSourceList.length - 1);
|
|
onRangeChange(controls.slider, showSliderState);
|
|
|
|
}
|
|
|
|
function updateControls() {
|
|
controls.slider.value = state.index;
|
|
controls.index.innerHTML = state.index;
|
|
|
|
if (state.playing) {
|
|
controls.buttons.toggle.innerHTML = "Pause";
|
|
} else {
|
|
controls.buttons.toggle.innerHTML = "Play";
|
|
}
|
|
}
|
|
|
|
//////////////////
|
|
// UI callbacks //
|
|
//////////////////
|
|
function toggle() {
|
|
console.log("toggle");
|
|
state.playing = !state.playing;
|
|
showThisGraph();
|
|
}
|
|
|
|
function showNext() {
|
|
console.log("next");
|
|
state.playing = false;
|
|
if (state.index < dotSourceList.length - 1) {
|
|
state.index = state.index + 1;
|
|
}
|
|
showThisGraph();
|
|
}
|
|
|
|
function showPrevious() {
|
|
console.log("previous");
|
|
state.playing = false;
|
|
if (state.index != 0) {
|
|
state.index = state.index - 1;
|
|
}
|
|
showThisGraph();
|
|
}
|
|
|
|
function showSliderState() {
|
|
console.log("slider");
|
|
var value = Number(controls.slider.value);
|
|
state.index = value;
|
|
state.playing = false;
|
|
|
|
showThisGraph();
|
|
}
|
|
|
|
///////////////
|
|
// Rendering //
|
|
///////////////
|
|
function prepareGraph() {
|
|
graph = d3.select("#graph").graphviz();
|
|
graph
|
|
.zoom(false)
|
|
.transition(function () {
|
|
return d3.transition("main")
|
|
.ease(d3.easeExpOut)
|
|
.duration(500)
|
|
// .delay(state.transitionDelay);
|
|
})
|
|
.on("initEnd", showThisGraph);
|
|
|
|
}
|
|
|
|
function showThisGraph() {
|
|
updateControls();
|
|
|
|
var dotSource = dotSourceList[state.index];
|
|
return graph
|
|
.renderDot(dotSource)
|
|
// The following sets up the "play" mode.
|
|
.on("end", continueIfPlaying);
|
|
}
|
|
|
|
|
|
function continueIfPlaying() {
|
|
if (!state.playing) {
|
|
return
|
|
}
|
|
state.index = (state.index + 1) % dotSourceList.length;
|
|
showThisGraph();
|
|
}
|
|
|
|
/////////////////
|
|
// Entry Point //
|
|
/////////////////
|
|
function main() {
|
|
setupControls();
|
|
prepareGraph();
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", main);
|