infobox
This commit is contained in:
parent
69c043bc39
commit
c6460003da
4 changed files with 175 additions and 48 deletions
|
@ -20,12 +20,57 @@ svg {
|
||||||
stroke-width: .05vw;
|
stroke-width: .05vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(min-width: 768px) {
|
|
||||||
|
|
||||||
|
/* box */
|
||||||
|
|
||||||
|
div#box {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
top: 0px;
|
||||||
|
right: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* visibility box */
|
||||||
|
|
||||||
|
div.box_off {
|
||||||
|
visibility: hidden;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.box_on {
|
||||||
|
visibility: visible;
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* box content */
|
||||||
|
|
||||||
|
div#box_content {
|
||||||
|
position: relative;
|
||||||
|
/* cursor: text; change to something cool */
|
||||||
|
width: 50vw;
|
||||||
|
height: 50vh;
|
||||||
|
z-index: 1000;
|
||||||
|
background: #000;
|
||||||
|
opacity: 85%;
|
||||||
|
border: solid .2vw #30dfdf;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-family: Helvetica, sans-serif; /* change */
|
||||||
|
font-size: 2vh;
|
||||||
|
padding: 2vh 2vw;
|
||||||
|
text-align: right;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* !! somehow adjust screenwidth for desktop (in js */
|
||||||
|
/* @media(min-width: 768px) {
|
||||||
|
|
||||||
#mobile_network {
|
#mobile_network {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
} */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
|
// replace div data with translated (html output askama)
|
||||||
|
// like this ? title: "{{"title1"|translate(lang)}}"
|
||||||
let graph = {
|
let graph = {
|
||||||
nodes : [
|
nodes : [
|
||||||
{id : "hemp", index: 0, x: 719.1790913580512, y: 326.11409230900296, vy: 0.0009665554475078223, vx: 0.00044710537175425926},
|
{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", index: 1, x: 473.51321690437135, y: 317.1181430586339, vy: 0.0005811239352358496, vx: 0.0005105059544352408 },
|
{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", index: 2, x: 495.66982580572676, y: 18.53, vy: 0.0007713356454593206, vx: 0.0007887999665437037 },
|
{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", index: 3, x: 457.9995206323447, y: 277.13445200140694, vy: 0.0004637678594351416, vx: 0.0007441570379881761 },
|
{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", index: 4, x: 428.05791236956037, y: 237.65121337678465, vy: 0.00037483669542696317, vx: 0.00039028860355878376 },
|
{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", index: 5, x: 461.65464520161396, y: 189.18158017082138, vy: -0.00023265081878199873, vx: 0.00006278089396472572 }
|
{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 width = 100;
|
||||||
let height = 200;
|
let height = 200;
|
||||||
let radius = 15;
|
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
|
link = svg
|
||||||
.selectAll(".link")
|
.selectAll(".link")
|
||||||
.data(graph.links)
|
.data(graph.links)
|
||||||
|
@ -45,10 +47,9 @@ const svg = d3.select("#mobile_network").append("svg").attr("viewBox", "0, 0, 10
|
||||||
.classed("node", true)
|
.classed("node", true)
|
||||||
.classed("fixed", d => d.fx !== undefined);
|
.classed("fixed", d => d.fx !== undefined);
|
||||||
|
|
||||||
|
|
||||||
const node1 = svg.select("#hemp")
|
const node1 = svg.select("#hemp")
|
||||||
.attr("fill", "url(#imgHemp)")
|
.attr("fill", "url(#imgHemp)")
|
||||||
.append("a")
|
|
||||||
.attr("xlink:href", "/hemp");
|
|
||||||
|
|
||||||
const node2 = svg.select("#permapp")
|
const node2 = svg.select("#permapp")
|
||||||
.attr("fill", "url(#imgPermapp)");
|
.attr("fill", "url(#imgPermapp)");
|
||||||
|
@ -65,6 +66,7 @@ const node5 = svg.select("#kaoscube")
|
||||||
const node6 = svg.select("#offgrid")
|
const node6 = svg.select("#offgrid")
|
||||||
.attr("fill", "url(#imgOff)");
|
.attr("fill", "url(#imgOff)");
|
||||||
|
|
||||||
|
|
||||||
const defs = svg.append("svg:defs");
|
const defs = svg.append("svg:defs");
|
||||||
|
|
||||||
defs.append("svg:pattern")
|
defs.append("svg:pattern")
|
||||||
|
@ -145,41 +147,45 @@ defs.append("svg:pattern")
|
||||||
.force("x", d3.forceX(-30))
|
.force("x", d3.forceX(-30))
|
||||||
.on("tick", tick);
|
.on("tick", tick);
|
||||||
|
|
||||||
|
|
||||||
const drag = d3
|
const drag = d3
|
||||||
.drag()
|
.drag()
|
||||||
.on("start", dragstart)
|
.on("start", dragstart)
|
||||||
.on("drag", dragged);
|
.on("drag", dragged);
|
||||||
|
|
||||||
// invokes regiserd callback
|
|
||||||
node.call(drag).on("click", click);
|
node.call(drag).on("click", click);
|
||||||
|
|
||||||
function tick() {
|
|
||||||
link
|
|
||||||
.attr("x1", d => d.source.x)
|
|
||||||
.attr("y1", d => d.source.y)
|
|
||||||
.attr("x2", d => d.target.x)
|
|
||||||
.attr("y2", d => d.target.y);
|
|
||||||
node
|
|
||||||
.attr("cx", d => d.x = Math.max(radius, Math.min(width - radius, d.x)))
|
|
||||||
.attr("cy", d => d.y = Math.max(radius, Math.min(height - radius, d.y)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// make this work on touch as well
|
// on doubleclick release position
|
||||||
|
node.on("dblclick", release );
|
||||||
|
|
||||||
function click(event, d) {
|
function release(event, d) {
|
||||||
|
// back to original position
|
||||||
delete d.fx;
|
delete d.fx;
|
||||||
delete d.fy;
|
delete d.fy;
|
||||||
// remove fixed position on click
|
|
||||||
d3.select(this).classed("fixed", false);
|
|
||||||
simulation.alpha(1).restart();
|
simulation.alpha(1).restart();
|
||||||
|
}
|
||||||
|
|
||||||
// on this click display html text box
|
// make this work on touch as well !
|
||||||
|
|
||||||
|
function click(event, d) {
|
||||||
|
d3.select(this).classed("fixed", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function dragstart() {
|
function dragstart() {
|
||||||
|
// select element and set position to fixed
|
||||||
d3.select(this).classed("fixed", true);
|
d3.select(this).classed("fixed", true);
|
||||||
|
|
||||||
|
// 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) {
|
function dragged(event, d) {
|
||||||
|
@ -193,11 +199,80 @@ defs.append("svg:pattern")
|
||||||
simulation.alpha(1).restart();
|
simulation.alpha(1).restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function tick() {
|
||||||
|
link
|
||||||
|
.attr("x1", d => d.source.x)
|
||||||
|
.attr("y1", d => d.source.y)
|
||||||
|
.attr("x2", d => d.target.x)
|
||||||
|
.attr("y2", d => d.target.y);
|
||||||
|
node
|
||||||
|
.attr("cx", d => d.x = Math.max(radius, Math.min(width - radius, d.x)))
|
||||||
|
.attr("cy", d => d.y = Math.max(radius, Math.min(height - radius, d.y)));
|
||||||
|
}
|
||||||
|
|
||||||
function clamp(x, lo, hi) {
|
function clamp(x, lo, hi) {
|
||||||
return x < lo ? lo : x > hi ? hi : x;
|
return x < lo ? lo : x > hi ? hi : x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
|
||||||
|
|
||||||
|
// change status of a box from visible to hidden and viceversa on click
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="{{ lang }}">
|
<html lang="{{ lang }}" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||||
<head>
|
<head>
|
||||||
{% block head %}
|
{% block head %}
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
|
|
|
@ -1,6 +1,13 @@
|
||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div id="mobile_network"></div>
|
<div id="mobile_network"></div>
|
||||||
|
<div id="box" class ="box_off">
|
||||||
|
<div id ="box_content">
|
||||||
|
<h1 id ="title">Test</h1>
|
||||||
|
<p id="description"></p>
|
||||||
|
<a id="page_link"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<script type="module" src="/assets/js/net.js"></script>
|
<script type="module" src="/assets/js/net.js"></script>
|
||||||
<script type="text/javascript" src="/assets/js/d3.v7.min.js"></script>
|
<script type="text/javascript" src="/assets/js/d3.v7.min.js"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
Loading…
Reference in a new issue