|
|
@ -1,11 +1,13 @@ |
|
|
|
// replace div data with translated (html output askama)
|
|
|
|
// like this ? title: "{{"title1"|translate(lang)}}"
|
|
|
|
let graph = { |
|
|
|
nodes : [ |
|
|
|
{id : "hemp", index: 0, x: 719.1790913580512, y: 326.11409230900296, vy: 0.0009665554475078223, vx: 0.00044710537175425926}, |
|
|
|
{id : "permapp", index: 1, x: 473.51321690437135, y: 317.1181430586339, vy: 0.0005811239352358496, vx: 0.0005105059544352408 }, |
|
|
|
{id : "offgrid", index: 2, x: 495.66982580572676, y: 18.53, vy: 0.0007713356454593206, vx: 0.0007887999665437037 }, |
|
|
|
{id : "cyberpreneur", index: 3, x: 457.9995206323447, y: 277.13445200140694, vy: 0.0004637678594351416, vx: 0.0007441570379881761 }, |
|
|
|
{id : "kaoscube", index: 4, x: 428.05791236956037, y: 237.65121337678465, vy: 0.00037483669542696317, vx: 0.00039028860355878376 }, |
|
|
|
{id : "spider", index: 5, x: 461.65464520161396, y: 189.18158017082138, vy: -0.00023265081878199873, vx: 0.00006278089396472572 } |
|
|
|
{id : "hemp", url: "/hemp" ,index: 0, x: 719.1790913580512, y: 326.11409230900296, vy: 0.0009665554475078223, vx: 0.00044710537175425926, title: "Title1", content: "Content 1"}, |
|
|
|
{id : "permapp", url: "/spider/permapp",index: 1, x: 473.51321690437135, y: 317.1181430586339, vy: 0.0005811239352358496, vx: 0.0005105059544352408, title: "Title 2", content: "Content 2"}, |
|
|
|
{id : "offgrid",url: "/offgrid", index: 2, x: 495.66982580572676, y: 18.53, vy: 0.0007713356454593206, vx: 0.0007887999665437037, title: "Title 3", content: "Content 3"}, |
|
|
|
{id : "cyberpreneur",url: "/cyberpreneur", index: 3, x: 457.9995206323447, y: 277.13445200140694, vy: 0.0004637678594351416, vx: 0.0007441570379881761, title: "Title 4", content: "Content 4" }, |
|
|
|
{id : "kaoscube",url: "/kaoscube", index: 4, x: 428.05791236956037, y: 237.65121337678465, vy: 0.00037483669542696317, vx: 0.00039028860355878376, title: "Title 5", content: "Content 5"}, |
|
|
|
{id : "spider", url: "/spider",index: 5, x: 461.65464520161396, y: 189.18158017082138, vy: -0.00023265081878199873, vx: 0.00006278089396472572, title: "Title 6", content: "Content 6" } |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
@ -24,13 +26,13 @@ let graph = { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// mobile network
|
|
|
|
// has to be made responsive to actual screensize !
|
|
|
|
|
|
|
|
let width = 100; |
|
|
|
let height = 200; |
|
|
|
let radius = 15; |
|
|
|
|
|
|
|
const svg = d3.select("#mobile_network").append("svg").attr("viewBox", "0, 0, 100, 200").attr("preserveAspectRatio", "xMidYMid meet"), |
|
|
|
const svg = d3.select("#mobile_network").append("svg").attr("viewBox", "0, 0, 100, 200").attr("preserveAspectRatio", "xMidYMid meet").attr("style", "position: relative;"), |
|
|
|
link = svg |
|
|
|
.selectAll(".link") |
|
|
|
.data(graph.links) |
|
|
@ -45,10 +47,9 @@ const svg = d3.select("#mobile_network").append("svg").attr("viewBox", "0, 0, 10 |
|
|
|
.classed("node", true) |
|
|
|
.classed("fixed", d => d.fx !== undefined); |
|
|
|
|
|
|
|
|
|
|
|
const node1 = svg.select("#hemp") |
|
|
|
.attr("fill", "url(#imgHemp)") |
|
|
|
.append("a") |
|
|
|
.attr("xlink:href", "/hemp"); |
|
|
|
|
|
|
|
const node2 = svg.select("#permapp") |
|
|
|
.attr("fill", "url(#imgPermapp)"); |
|
|
@ -65,6 +66,7 @@ const node5 = svg.select("#kaoscube") |
|
|
|
const node6 = svg.select("#offgrid") |
|
|
|
.attr("fill", "url(#imgOff)"); |
|
|
|
|
|
|
|
|
|
|
|
const defs = svg.append("svg:defs"); |
|
|
|
|
|
|
|
defs.append("svg:pattern") |
|
|
@ -145,14 +147,57 @@ defs.append("svg:pattern") |
|
|
|
.force("x", d3.forceX(-30)) |
|
|
|
.on("tick", tick); |
|
|
|
|
|
|
|
const drag = d3 |
|
|
|
.drag() |
|
|
|
.on("start", dragstart) |
|
|
|
.on("drag", dragged); |
|
|
|
|
|
|
|
node.call(drag).on("click", click); |
|
|
|
|
|
|
|
|
|
|
|
// on doubleclick release position
|
|
|
|
node.on("dblclick", release ); |
|
|
|
|
|
|
|
function release(event, d) { |
|
|
|
// back to original position
|
|
|
|
delete d.fx; |
|
|
|
delete d.fy; |
|
|
|
simulation.alpha(1).restart(); |
|
|
|
} |
|
|
|
|
|
|
|
// make this work on touch as well !
|
|
|
|
|
|
|
|
function click(event, d) { |
|
|
|
d3.select(this).classed("fixed", false); |
|
|
|
} |
|
|
|
|
|
|
|
const drag = d3 |
|
|
|
.drag() |
|
|
|
.on("start", dragstart) |
|
|
|
.on("drag", dragged); |
|
|
|
function dragstart() { |
|
|
|
// select element and set position to fixed
|
|
|
|
d3.select(this).classed("fixed", true); |
|
|
|
|
|
|
|
// invokes regiserd callback
|
|
|
|
node.call(drag).on("click", click); |
|
|
|
// show box on single click
|
|
|
|
toggleDiv(this.id, status); |
|
|
|
|
|
|
|
console.log("box atrr", box.attr("class")); |
|
|
|
if ( box.attr("class") == "box_on" ) { |
|
|
|
// make nodes underneath unclickable as long as box is open !
|
|
|
|
this.__on = null; |
|
|
|
} |
|
|
|
// this refers to dragged circle element
|
|
|
|
console.log("dragstart", this.id); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function dragged(event, d) { |
|
|
|
|
|
|
|
console.log("dragged",d.id); |
|
|
|
// set x position of dragged node
|
|
|
|
d.fx = clamp(event.x, 0, width); |
|
|
|
// set x position of dragged node
|
|
|
|
d.fy = clamp(event.y, 0, height); |
|
|
|
// sets duration of animation before restart
|
|
|
|
simulation.alpha(1).restart(); |
|
|
|
} |
|
|
|
|
|
|
|
function tick() { |
|
|
|
link |
|
|
@ -165,39 +210,69 @@ defs.append("svg:pattern") |
|
|
|
.attr("cy", d => d.y = Math.max(radius, Math.min(height - radius, d.y))); |
|
|
|
} |
|
|
|
|
|
|
|
// make this work on touch as well
|
|
|
|
function clamp(x, lo, hi) { |
|
|
|
return x < lo ? lo : x > hi ? hi : x; |
|
|
|
} |
|
|
|
|
|
|
|
function click(event, d) { |
|
|
|
delete d.fx; |
|
|
|
delete d.fy; |
|
|
|
// remove fixed position on click
|
|
|
|
d3.select(this).classed("fixed", false); |
|
|
|
simulation.alpha(1).restart(); |
|
|
|
|
|
|
|
// on this click display html text box
|
|
|
|
// show info divs with data based on id
|
|
|
|
|
|
|
|
} |
|
|
|
// the infobox
|
|
|
|
const box = d3.select("#box") |
|
|
|
|
|
|
|
// state of box
|
|
|
|
let toggleDiv = undefined; |
|
|
|
|
|
|
|
// all nodes
|
|
|
|
let nodeArray = graph.nodes; |
|
|
|
|
|
|
|
function dragstart() { |
|
|
|
d3.select(this).classed("fixed", true); |
|
|
|
} |
|
|
|
|
|
|
|
function dragged(event, d) { |
|
|
|
// change status of a box from visible to hidden and viceversa on click
|
|
|
|
|
|
|
|
console.log("dragged",d.id); |
|
|
|
// set x position of dragged node
|
|
|
|
d.fx = clamp(event.x, 0, width); |
|
|
|
// set x position of dragged node
|
|
|
|
d.fy = clamp(event.y, 0, height); |
|
|
|
// sets duration of animation before restart
|
|
|
|
simulation.alpha(1).restart(); |
|
|
|
toggleDiv = function( event, status ) { |
|
|
|
|
|
|
|
if ( status == "" ) { |
|
|
|
status = box.attr("class") == "box_off" ? "box_on" : "box_off"; |
|
|
|
box.attr("class", status); |
|
|
|
|
|
|
|
} else { |
|
|
|
console.log("status is", status); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
function clamp(x, lo, hi) { |
|
|
|
return x < lo ? lo : x > hi ? hi : x; |
|
|
|
} |
|
|
|
|
|
|
|
// Like that somehow: embed data as html
|
|
|
|
|
|
|
|
// Get content data
|
|
|
|
//Parameters: data, array containing all nodes
|
|
|
|
|
|
|
|
function getContent( n, nodeArray ) { |
|
|
|
info = '<div id="box">'; |
|
|
|
if( n.link ) |
|
|
|
// get link of node
|
|
|
|
info += '<a href="' + n.url + '"/>'; |
|
|
|
else |
|
|
|
console.log("couldn't get link:", n.url); |
|
|
|
|
|
|
|
if( n.title ) |
|
|
|
info += '<h1 id="title">"' + n.title + '"/>' |
|
|
|
else |
|
|
|
console.log("couldn't get title:", n.title); |
|
|
|
if( n.content ) |
|
|
|
info += '<p id="content><"' + n.content + '"/>' |
|
|
|
console.log("couldn't get title:", n.content); |
|
|
|
|
|
|
|
return info; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Show box for a given node
|
|
|
|
function showContent( node ) { |
|
|
|
// Fill it and display the box
|
|
|
|
box |
|
|
|
.html( getContent(node,nodeArray) ) |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// desktop network
|
|
|
|
|
|
|
|
|