Frontend requiremets finished

delete_edge
Ugo Finnendahl 5 years ago
parent 8494cc6992
commit e2bb890704
  1. 8
      frontend/assets/css/src/style.scss
  2. 2
      frontend/assets/css/style.min.css
  3. 580
      frontend/assets/js/canvas.js
  4. 28
      frontend/index.html

@ -37,6 +37,14 @@ main{
position: relative; position: relative;
height: 100%; height: 100%;
.background{
position: absolute;
top:0;
left:0;
background-color: rgba(0,0,0,0.5);
width: 100%;
height: 100%;
}
input{ input{
position: absolute; position: absolute;
border: none; border: none;

@ -1 +1 @@
*{margin:0;padding:0;box-sizing:border-box}body{font-family:Roboto}main{position:relative;height:100vh}main #infobar{position:absolute;top:0;width:100%;padding:0.4em;background-color:rgba(232,9,9,0.4);border:4px solid rgba(232,9,9,0.8);text-align:center;font-weight:bold;font-size:1.8em;z-index:1;transform:translateY(-100%);transition:transform 1s}main #infobar.active{transform:translateY(0%)}main .canvas{background-color:lightgrey;position:relative;height:100%}main .canvas input{position:absolute;border:none;padding:0.6em 1em;width:50px;transform:translateX(-50%) translateY(-50%)}main nav,main footer{display:flex;position:absolute;top:1em;left:1em;opacity:0.9}main nav button,main footer button{display:block;background-color:#939292;border:none;border-radius:1em;padding:1em 1em;min-width:8em;margin:0.4em;color:black;border:solid 2px #131313;box-shadow:2px 2px 8px rgba(0,0,0,0.5)}main nav button:focus,main footer button:focus{outline:none}main nav button::-moz-focus-inner,main footer button::-moz-focus-inner{border:0}main nav button:hover,main footer button:hover{background-color:#acacac;border-color:#000;cursor:pointer}main nav button.active,main footer button.active{background-color:#f08d19}main nav button h1,main footer button h1{text-align:center;font-size:1.4em;font-weight:normal;white-space:nowrap}main nav button img,main footer button img{display:block;margin:0 auto 0.5em auto;width:2em}main footer{top:auto;left:auto;bottom:1em;right:1em} *{margin:0;padding:0;box-sizing:border-box}body{font-family:Roboto}main{position:relative;height:100vh}main #infobar{position:absolute;top:0;width:100%;padding:0.4em;background-color:rgba(232,9,9,0.4);border:4px solid rgba(232,9,9,0.8);text-align:center;font-weight:bold;font-size:1.8em;z-index:1;transform:translateY(-100%);transition:transform 1s}main #infobar.active{transform:translateY(0%)}main .canvas{background-color:lightgrey;position:relative;height:100%}main .canvas .background{position:absolute;top:0;left:0;background-color:rgba(0,0,0,0.5);width:100%;height:100%}main .canvas input{position:absolute;border:none;padding:0.6em 1em;width:50px;transform:translateX(-50%) translateY(-50%)}main nav,main footer{display:flex;position:absolute;top:1em;left:1em;opacity:0.9}main nav button,main footer button{display:block;background-color:#939292;border:none;border-radius:1em;padding:1em 1em;min-width:8em;margin:0.4em;color:black;border:solid 2px #131313;box-shadow:2px 2px 8px rgba(0,0,0,0.5)}main nav button:focus,main footer button:focus{outline:none}main nav button::-moz-focus-inner,main footer button::-moz-focus-inner{border:0}main nav button:hover,main footer button:hover{background-color:#acacac;border-color:#000;cursor:pointer}main nav button.active,main footer button.active{background-color:#f08d19}main nav button h1,main footer button h1{text-align:center;font-size:1.4em;font-weight:normal;white-space:nowrap}main nav button img,main footer button img{display:block;margin:0 auto 0.5em auto;width:2em}main footer{top:auto;left:auto;bottom:1em;right:1em}

@ -1,6 +1,8 @@
const canvas = document.getElementById("canvas"); const canvas = document.getElementById("canvas");
// Layouts //-----------------------------------------------------------------------------
//-----------------------------Layouts-----------------------------------------
//-----------------------------------------------------------------------------
var width = canvas.offsetWidth; var width = canvas.offsetWidth;
var height = canvas.offsetHeight; var height = canvas.offsetHeight;
@ -31,8 +33,8 @@ const node_text_layout = {
y: 2 - node_size, y: 2 - node_size,
text: name, text: name,
fontSize: 22, fontSize: 22,
width: 2 * node_size-1, width: 2 * node_size - 1,
height: 2 * node_size-1, height: 2 * node_size - 1,
fontFamily: 'Roboto', fontFamily: 'Roboto',
fill: 'black', fill: 'black',
verticalAlign: 'middle', verticalAlign: 'middle',
@ -54,6 +56,7 @@ const edge_text_layout = {
align: 'center' align: 'center'
}; };
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//-------------------------------Init------------------------------------------ //-------------------------------Init------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -62,6 +65,7 @@ var node_layer = new Konva.Layer();
var konva_edges = []; var konva_edges = [];
var konva_nodes = []; var konva_nodes = [];
var graph_copy = {}; var graph_copy = {};
var state = "idle"; var state = "idle";
@ -73,267 +77,340 @@ var path_elements = [];
// (additions) auto layout // (additions) auto layout
var auto_layout = false; var auto_layout = false;
function initialisation(){ function initialization() {
stage.add(edge_layer); stage.add(edge_layer);
stage.add(node_layer); stage.add(node_layer);
// avoid flickering
edge_layer.hide();
// avoid flickering // draw initial graph
edge_layer.hide(); for (id in nodes) {
// draw initial graph
for (id in nodes) {
draw_new_node(nodes[id], node_size + Math.random() * (width - 2 * node_size), node_size + Math.random() * (height - 2 * node_size)); draw_new_node(nodes[id], node_size + Math.random() * (width - 2 * node_size), node_size + Math.random() * (height - 2 * node_size));
} }
for (id in edges) { for (id in edges) {
draw_new_edge(edges[id]); draw_new_edge(edges[id]);
} }
// (additions) auto layout
if ( sessionStorage.getItem("auto_layout") !== null) { // (additions) auto layout
if (sessionStorage.getItem("auto_layout") !== null) {
// Restore the contents of the text field // Restore the contents of the text field
auto_layout = (sessionStorage.getItem("auto_layout") == 'true'); auto_layout = (sessionStorage.getItem("auto_layout") == 'true');
if (auto_layout){ if (auto_layout) {
document.querySelector("[data-activeon=auto_layout]").classList.add("active"); document.querySelector("[data-activeon=auto_layout]").classList.add("active");
} }
} }
// Precalculate a good graph presentation // Precalculate a good graph presentation
for (var i = 0; i < 1000; i++) { for (var i = 0; i < 1000; i++) {
force_directed_graph(); force_directed_graph();
} }
node_layer.draw();
edge_layer.show();
}
initialization();
edge_layer.show();
}
initialisation();
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//------------------------------utils------------------------------------------ //------------------------------utils------------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
function sort(array) { function sort(array) {
return array.sort(function(a, b) { return array.sort(function(a, b) {
return a - b; return a - b;
}) })
} }
function show_error(msg) {
let infobar = document.querySelector("#infobar");
infobar.innerHTML = msg;
infobar.classList.add("active");
window.setTimeout(function() {
infobar.classList.remove("active");
}, 4000);
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
//---------------------------draw methods-------------------------------------- //---------------------------draw methods--------------------------------------
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
function draw_new_node(name, x, y) { function draw_new_node(name, x, y) {
const pos = { let group = new Konva.Group({
x: x, x: x,
y: y y: y,
}; draggable: true,
let group = new Konva.Group({ dragBoundFunc: function(pos) {
...pos, return {
draggable: true, x: sort([node_size, pos.x, width - node_size])[1],
dragBoundFunc: function(pos) { y: sort([node_size, pos.y, height - node_size])[1],
return { };
x: sort([node_size, pos.x, width - node_size])[1], },
y: sort([node_size, pos.y, height - node_size])[1], id: name
}; });
}, let box = new Konva.Circle(node_layout);
id: name let simpleText = new Konva.Text({
}); ...node_text_layout,
let box = new Konva.Circle(node_layout); text: name
let simpleText = new Konva.Text({...node_text_layout, text: name}); });
group.add(box); group.add(box);
group.add(simpleText); group.add(simpleText);
group.on("click", on_node_click); group.on("click", on_node_click);
group.on('dragstart', function() { group.on('dragstart', function() {
group.attrs.dragging = true; group.attrs.dragging = true;
}); });
group.on('dragend', function() { group.on('dragend', function() {
group.attrs.dragging = false; group.attrs.dragging = false;
}); });
group.on('mouseover', function() { group.on('mouseover', function() {
document.body.style.cursor = 'pointer'; document.body.style.cursor = 'pointer';
}); });
group.on('mouseout', function() { group.on('mouseout', function() {
document.body.style.cursor = 'default'; document.body.style.cursor = 'default';
}); });
graph_copy[name] = []; graph_copy[name] = [];
konva_nodes.push(group); konva_nodes.push(group);
node_layer.add(group); node_layer.add(group);
node_layer.draw(); node_layer.draw();
} }
function draw_new_edge(edge) { function draw_new_edge(edge) {
let start_node = stage.findOne('#' + edge["start"]); let start_node = stage.findOne('#' + edge["start"]);
let end_node = stage.findOne('#' + edge["end"]); let end_node = stage.findOne('#' + edge["end"]);
let weight = edge["weight"]; let weight = edge["weight"];
let group = new Konva.Group({ let group = new Konva.Group({
start_node: start_node, start_node: start_node,
end_node: end_node, end_node: end_node,
weight: weight, weight: weight,
id: edge["start"]+edge["end"] id: edge["start"] + edge["end"]
}); });
let line = new Konva.Line(edge_layout); let line = new Konva.Line(edge_layout);
let simpleText = new Konva.Text({...edge_text_layout, text: weight}); let simpleText = new Konva.Text({
...edge_text_layout,
graph_copy[edge["start"]].push(edge["end"]); text: weight
graph_copy[edge["end"]].push(edge["start"]); });
group.add(line); graph_copy[edge["start"]].push(edge["end"]);
group.add(simpleText); graph_copy[edge["end"]].push(edge["start"]);
konva_edges.push(group);
update_edge(group); group.add(line);
group.add(simpleText);
edge_layer.add(group); konva_edges.push(group);
edge_layer.draw(); update_edge(group);
return group; edge_layer.add(group);
edge_layer.draw();
return group;
} }
function update_edge(konva_edge) { function update_edge(konva_edge) {
let line = konva_edge.children[0]; let line = konva_edge.children[0];
let text = konva_edge.children[1]; let text = konva_edge.children[1];
let start_node = konva_edge.attrs.start_node; let start_node = konva_edge.attrs.start_node;
let end_node = konva_edge.attrs.end_node; let end_node = konva_edge.attrs.end_node;
let size = 15+text.text().length*15; let size = 15 + text.text().length * 15;
let line_length = Math.sqrt((start_node.getX() - end_node.getX()) ** 2 + (start_node.getY() - end_node.getY()) ** 2) - size; let line_length = Math.sqrt((start_node.getX() - end_node.getX()) ** 2 + (start_node.getY() - end_node.getY()) ** 2) - size;
line.points([start_node.getX(), start_node.getY(), end_node.getX(), end_node.getY()]);
line.dash([line_length / 2, size, line_length / 2]); line.points([start_node.getX(), start_node.getY(), end_node.getX(), end_node.getY()]);
text.x((start_node.getX() + end_node.getX()) / 2 - node_size); line.dash([line_length / 2, size, line_length / 2]);
text.y((start_node.getY() + end_node.getY()) / 2 - node_size), text.x((start_node.getX() + end_node.getX()) / 2 - node_size);
text.y((start_node.getY() + end_node.getY()) / 2 - node_size),
edge_layer.draw();
edge_layer.draw();
} }
function reset_node_style(){ function reset_node_style() {
for (let id in konva_nodes) { for (let id in konva_nodes) {
konva_nodes[id].children[0].strokeWidth(node_layout.strokeWidth); konva_nodes[id].children[0].strokeWidth(node_layout.strokeWidth);
konva_nodes[id].children[0].stroke("black"); konva_nodes[id].children[0].stroke("black");
} }
} }
function reset_edge_style(){ function reset_edge_style() {
for (let id in konva_edges) { for (let id in konva_edges) {
konva_edges[id].children[0].strokeWidth(edge_layout.strokeWidth); konva_edges[id].children[0].strokeWidth(edge_layout.strokeWidth);
konva_edges[id].children[0].stroke("black"); konva_edges[id].children[0].stroke("black");
} }
} }
function draw_selected_nodes() { function draw_selected_nodes() {
reset_node_style(); reset_node_style();
reset_edge_style(); reset_edge_style();
for (let id in selected) { for (let id in selected) {
selected[id].children[0].strokeWidth(node_layout.strokeWidth + 1); selected[id].children[0].strokeWidth(node_layout.strokeWidth + 1);
selected[id].children[0].stroke("rgb(240, 141, 25)"); selected[id].children[0].stroke("rgb(240, 141, 25)");
} }
node_layer.draw(); node_layer.draw();
} }
function draw_path(path){ function draw_path(path) {
let path_elements = []; let path_elements = [];
for (let id in path){ for (let id in path) {
path_elements.push(stage.findOne("#"+path[id])); path_elements.push(stage.findOne("#" + path[id]));
if (id == 0) { if (id == 0) {
continue continue
} }
let current_edge = stage.findOne("#"+path[id-1]+path[id]); let current_edge = stage.findOne("#" + path[id - 1] + path[id]);
if (current_edge){ if (current_edge) {
path_elements.push(current_edge); path_elements.push(current_edge);
}else{ } else {
path_elements.push(stage.findOne("#"+path[id]+path[id-1])); path_elements.push(stage.findOne("#" + path[id] + path[id - 1]));
} }
} }
reset_node_style(); reset_node_style();
reset_edge_style(); reset_edge_style();
for (let id in path_elements) { for (let id in path_elements) {
path_elements[id].children[0].strokeWidth(node_layout.strokeWidth + 1); path_elements[id].children[0].strokeWidth(node_layout.strokeWidth + 1);
path_elements[id].children[0].stroke("rgb(240, 141, 25)"); path_elements[id].children[0].stroke("rgb(240, 141, 25)");
} }
} }
function on_node_click(e) { function on_node_click(e) {
e.cancelBubble = true; e.cancelBubble = true;
// let mousePos = stage.getPointerPosition(); // let mousePos = stage.getPointerPosition();
let idx = selected.indexOf(this); let idx = selected.indexOf(this);
if (idx >= 0) { if (idx >= 0) {
selected.splice(idx, 1); selected.splice(idx, 1);
} else if (selected.length < 2) { } else if (selected.length < 2) {
selected.push(this); selected.push(this);
} else { } else {
selected.shift(); selected.shift();
selected.push(this); selected.push(this);
} }
draw_selected_nodes(); draw_selected_nodes();
}; };
//-----------------------------------------------------------------------------
//---------------------------REST methods--------------------------------------
//-----------------------------------------------------------------------------
function post(endpoint, data) {
return fetch(url + endpoint, {
method: 'POST',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json'
}
}).then(res => res.json())
}
function create_node() {
function create_node(){ if (state != "create_node") {
if (state != "create_node"){
state = "create_node"; state = "create_node";
// let mousePos = stage.getPointerPosition(); // let mousePos = stage.getPointerPosition();
let pos = {x: width/2, y: height/2}; let pos = {
create_input(pos.x, pos.y).then(function(text) { x: width / 2,
draw_new_node(text, pos.x, pos.y); y: height / 2
state = "idle"; };
}, function(){state = "idle"}); create_input(pos.x, pos.y).then(function(text) {
} post("nodes", {
name: text
})
.then(function(res) {
if (res["error"]) {
show_error(res["error"])
} else {
draw_new_node(text, pos.x, pos.y);
}
state = "idle";
})
.catch(error => console.error('Error:', error));
}, function() {state = "idle"});
}
} }
function create_edge() { function create_edge() {
if (selected.length < 2) { if (selected.length < 2) {
show_error("Select at least 2 nodes."); show_error("Select at least 2 nodes.");
return; return;
} }
let x = (selected[0].getX() + selected[1].getX()) / 2; let x = (selected[0].getX() + selected[1].getX()) / 2;
let y = (selected[0].getY() + selected[1].getY()) / 2; let y = (selected[0].getY() + selected[1].getY()) / 2;
create_input(x, y).then(function(text) { create_input(x, y).then(function(text) {
draw_new_edge({ post("edges", {
start: selected[0].id(),
end: selected[1].id(),
weight: text
})
.then(function(res) {
if (res["error"]) {
show_error(res["error"])
} else {
draw_new_edge({
"start": selected[0].children[1].text(), "start": selected[0].children[1].text(),
"end": selected[1].children[1].text(), "end": selected[1].children[1].text(),
"weight": text "weight": text
}); });
selected = []; selected = [];
draw_selected_nodes(); draw_selected_nodes();
},function(){}); }
})
.catch(error => console.error('Error:', error));
}, function() {});
} }
function create_input(x, y) { function create_input(x, y) {
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
var input = document.createElement("input"); var container = document.createElement("div");
input.setAttribute("type", "text"); container.classList.add("background");
input.style.left = x + "px"; var input = document.createElement("input");
input.style.top = y + "px"; var clear = function() {
canvas.appendChild(input); container.remove();
input.focus(); stage.listening(true);
stage.listening(false); focus = true;
window.addEventListener("keyup", function(event) { }
if (event.key === "Escape") { input.setAttribute("type", "text");
input.remove(); input.style.left = x + "px";
stage.listening(true); input.style.top = y + "px";
reject(); canvas.appendChild(container);
} container.appendChild(input);
}); input.focus();
input.addEventListener("keyup", function(event) { stage.listening(false);
if (event.key === "Enter") { focus = false;
resolve(input.value); window.addEventListener("keyup", function(event) {
input.remove(); if (event.key === "Escape") {
stage.listening(true); reject();
} clear();
}); }
});
input.addEventListener("keyup", function(event) {
if (event.key === "Enter") {
resolve(input.value);
clear();
}
}); });
});
} }
function find_path(){ function find_path(data) {
draw_path(elem); if (data.length < 2) {
show_error("Select at least 2 nodes.");
return;
}
console.log(url + "paths/" + data[0].attrs.id + "/" + data[1].attrs.id);
fetch(url + "paths/" + data[0].attrs.id + "/" + data[1].attrs.id).then(res => res.json())
.then(function(res) {
if (res["error"]) {
show_error(res["error"]);
} else {
selected = [];
draw_path(res["path"]);
}
})
.catch(error => console.error('Error:', error));
} }
//-----------------------------------------------------------------------------
//------------------------background methods-----------------------------------
//-----------------------------------------------------------------------------
function update_edges(edges) { function update_edges(edges) {
for (id in edges) { for (id in edges) {
update_edge(edges[id]); update_edge(edges[id]);
} }
} }
node_layer.on('beforeDraw', function() { node_layer.on('beforeDraw', function() {
update_edges(konva_edges); update_edges(konva_edges);
}); });
// adapt the stage on any window resize // adapt the stage on any window resize
@ -346,91 +423,80 @@ function fitStageIntoParentContainer() {
} }
window.addEventListener('resize', fitStageIntoParentContainer); window.addEventListener('resize', fitStageIntoParentContainer);
//-----------------------------------------------------------------------------
//---------------------(additions) auto layout---------------------------------
//-----------------------------------------------------------------------------
//---------------------(additions) auto layout---------------------------------
function toggle_auto_layout() { function toggle_auto_layout() {
auto_layout = !auto_layout; auto_layout = !auto_layout;
document.querySelector("[data-activeon=auto_layout]").classList.toggle("active"); document.querySelector("[data-activeon=auto_layout]").classList.toggle("active");
sessionStorage.setItem("auto_layout", auto_layout); sessionStorage.setItem("auto_layout", auto_layout);
} }
function normalize(vec) { function normalize(vec) {
let l = Math.sqrt(vec[0]**2+vec[1]**2); let l = Math.sqrt(vec[0] ** 2 + vec[1] ** 2);
return [vec[0]/l,vec[1]/l]; return [vec[0] / l, vec[1] / l];
} }
function in_edges(start_node, end_node){ function in_edges(start_node, end_node) {
let idx = graph_copy[start_node.attrs.id].indexOf(end_node.attrs.id); let idx = graph_copy[start_node.attrs.id].indexOf(end_node.attrs.id);
if (idx < 0){ if (idx < 0) {
return false; return false;
} }
return true; return true;
} }
function force_directed_graph(spring_length = 300, step = 0.004){ function force_directed_graph(spring_length = 300, step = 0.004) {
for (var idx in konva_nodes){ for (var idx in konva_nodes) {
if (konva_nodes[idx].attrs.dragging){ if (konva_nodes[idx].attrs.dragging) {
continue continue
} }
var x1 = konva_nodes[idx].getX(); var x1 = konva_nodes[idx].getX();
var y1 = konva_nodes[idx].getY(); var y1 = konva_nodes[idx].getY();
var rep = [0,0]; var rep = [0, 0];
var attr = [0,0]; var attr = [0, 0];
for (let jdx in konva_nodes){ for (let jdx in konva_nodes) {
if (idx == jdx){ if (idx == jdx) {
continue; continue;
} }
let x2 = konva_nodes[jdx].getX(); let x2 = konva_nodes[jdx].getX();
let y2 = konva_nodes[jdx].getY(); let y2 = konva_nodes[jdx].getY();
let dir = normalize([x2-x1,y2-y1]); let dir = normalize([x2 - x1, y2 - y1]);
let dist = ((x1-x2)**2+(y1-y2)**2); let dist = ((x1 - x2) ** 2 + (y1 - y2) ** 2);
if (in_edges(konva_nodes[idx], konva_nodes[jdx])){ if (in_edges(konva_nodes[idx], konva_nodes[jdx])) {
let f = (dist/spring_length); let f = (dist / spring_length);
attr[0] += f*dir[0]; attr[0] += f * dir[0];
attr[1] += f*dir[1]; attr[1] += f * dir[1];
}
let f = (spring_length**2/Math.sqrt(dist));
rep[0] -= f*dir[0];
rep[1] -= f*dir[1];
}
let new_x = x1+step*(rep[0]+attr[0]);
let new_y = y1+step*(rep[1]+attr[1]);
if (new_x < 2*node_size) {
new_x += 10*step*((2*node_size-new_x));
} else if (new_x > width-2*node_size) {
new_x += 10*step*((width-2*node_size-new_x));
}
if (new_y < 2*node_size) {
new_y += 10*step*((2*node_size-new_y));
} else if (new_y > height-2*node_size) {
new_y += 10*step*((height-2*node_size-new_y));
}
konva_nodes[idx].x(new_x);
konva_nodes[idx].y(new_y);
} }
let f = (spring_length ** 2 / Math.sqrt(dist));
rep[0] -= f * dir[0];
rep[1] -= f * dir[1];
}
let new_x = x1 + step * (rep[0] + attr[0]);
let new_y = y1 + step * (rep[1] + attr[1]);
if (new_x < 2 * node_size) {
new_x += 10 * step * ((2 * node_size - new_x));
} else if (new_x > width - 2 * node_size) {
new_x += 10 * step * ((width - 2 * node_size - new_x));
}
if (new_y < 2 * node_size) {
new_y += 10 * step * ((2 * node_size - new_y));
} else if (new_y > height - 2 * node_size) {
new_y += 10 * step * ((height - 2 * node_size - new_y));
}
konva_nodes[idx].x(new_x);
konva_nodes[idx].y(new_y);
}
} }
var anim = new Konva.Animation(function(frame) { var anim = new Konva.Animation(function(frame) {
if (auto_layout) { if (auto_layout && focus) {
const spring_length = 300; const step = 0.00025 * frame.timeDiff;
const step = 0.00025*frame.timeDiff; force_directed_graph(300, step)
force_directed_graph(spring_length, step)
} }
}, node_layer); }, node_layer);
anim.start(); anim.start();
function show_error(msg){
let infobar = document.querySelector("#infobar");
infobar.innerHTML = msg;
infobar.classList.add("active");
window.setTimeout(function(){ infobar.classList.remove("active"); }, 4000);
}
// bug: this avoids glitches // bug: this avoids glitches
window.onfocus = function () {auto_layout = true;}; window.onfocus = function() {focus = true;};
window.onblur = function () {auto_layout = false;}; window.onblur = function() {focus = false;};

@ -20,7 +20,7 @@
<img src="{{ url_for('static', filename='imgs/drawing.svg') }}"> <img src="{{ url_for('static', filename='imgs/drawing.svg') }}">
<h1>Connect</h1> <h1>Connect</h1>
</button> </button>
<button type="button" onclick="find_path()"> <button type="button" onclick="find_path(selected)">
<img src="{{ url_for('static', filename='imgs/share.svg') }}"> <img src="{{ url_for('static', filename='imgs/share.svg') }}">
<h1>Find Path</h1> <h1>Find Path</h1>
</button> </button>
@ -32,29 +32,9 @@
</footer> </footer>
</main> </main>
<script> <script>
var nodes = ["Aachen", "Berlin", "Chemnitz", "Dresden", "Essen"] var nodes = {{ nodes|safe }};
var edges = [{ var edges = {{ edges|safe }};
"start": "Aachen", const url = "http://{{ request.host|safe }}/api/";
"end": "Berlin",
"weight": 800
},{
"start": "Dresden",
"end": "Berlin",
"weight": 800
},{
"start": "Essen",
"end": "Berlin",
"weight": 800
}, {
"start": "Chemnitz",
"end": "Dresden",
"weight": 5
},
{
"start": "Chemnitz",
"end": "Berlin",
"weight": 5
}]
</script> </script>
<script src="{{ url_for('static', filename='js/canvas.js')}}"></script> <script src="{{ url_for('static', filename='js/canvas.js')}}"></script>
</body> </body>

Loading…
Cancel
Save