From 9d402b8d3b5fc16b00f26004d79bf2f08080a116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maciej=20Kr=C3=BCger?= Date: Mon, 27 Feb 2023 14:23:08 +0100 Subject: [PATCH] Screenshot Mode / Inverted Graph --- lib/forcegraph.js | 76 +++++++++++++++++++++++++++++++++++-------- lib/gui.js | 45 +++++++++++++++++++++++++ scss/_base.scss | 4 +++ scss/_forcegraph.scss | 6 +++- scss/main.scss | 12 +++++++ 5 files changed, 129 insertions(+), 14 deletions(-) diff --git a/lib/forcegraph.js b/lib/forcegraph.js index c7d71d61..7fef553e 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -1,9 +1,9 @@ -define(["d3"], function (d3) { +define(["d3", "leaflet"], function (d3, L) { var margin = 200 var NODE_RADIUS = 15 var LINE_RADIUS = 7 - return function (config, linkScale, sidebar, router) { + return function (config, linkScale, sidebar, router, buttons) { var self = this var canvas, ctx, screenRect var nodesDict, linksDict @@ -22,11 +22,37 @@ define(["d3"], function (d3) { var unseenNodes = [] var unknownNodes = [] var savedPanZoom + var isBrightBackground = false var draggedNode var LINK_DISTANCE = 70 + var ChangeBackgroundButton = L.Control.extend({ + options: { + position: "bottomright" + }, + + initialize: function (f, options) { + L.Util.setOptions(this, options) + this.f = f + }, + + onAdd: function () { + var button = L.DomUtil.create("button", "change-background") + button.textContent = "\uF275" + + // L.DomEvent.disableClickPropagation(button) + // Click propagation isn't disabled as this causes problems with the + // location picking mode; instead propagation is stopped in onClick(). + L.DomEvent.addListener(button, "click", this.f, this) + + this.button = button + + return button + } + }) + function graphDiameter(nodes) { return Math.sqrt(nodes.length / Math.PI) * LINK_DISTANCE * 1.41 } @@ -274,12 +300,12 @@ define(["d3"], function (d3) { nctx.shadowOffsetX = node.width * 1.5 + 0 nctx.shadowOffsetY = node.height * 1.5 + 3 nctx.shadowBlur = 12 - nctx.shadowColor = "rgba(0, 0, 0, 0.16)" + nctx.shadowColor = isBrightBackground ? "rgba(255, 255, 255, 0.16)" : "rgba(0, 0, 0, 0.16)" nctx.stroke() nctx.shadowOffsetX = node.width * 1.5 + 0 nctx.shadowOffsetY = node.height * 1.5 + 3 nctx.shadowBlur = 12 - nctx.shadowColor = "rgba(0, 0, 0, 0.23)" + nctx.shadowColor = isBrightBackground ? "rgba(255, 255, 255, 0.23)" : "rgba(0, 0, 0, 0.23)" nctx.stroke() nctx.restore() @@ -312,10 +338,10 @@ define(["d3"], function (d3) { ctx.scale(scale, scale) var unknownColor = "#D10E2A" - var nonUplinkColor = "#F2E3C6" + var nonUplinkColor = isBrightBackground ? "#cfcfcf" : "#F2E3C6" var uplinkColor = "#5BAAEB" var unseenColor = "#FFA726" - var highlightColor = "rgba(252, 227, 198, 0.15)" + var highlightColor = isBrightBackground ? "rgba(3, 28, 57, 0.075)" : "rgba(252, 227, 198, 0.15)" var nodeRadius = 6 var cableColor = "#50B0F0" @@ -335,7 +361,7 @@ define(["d3"], function (d3) { ctx.moveTo(d.source.x + dx * nodeRadius, d.source.y + dy * nodeRadius) ctx.lineTo(d.target.x - (distancex / 2) - dx * nodeRadius, d.target.y - (distancey / 2) - dy * nodeRadius) ctx.strokeStyle = d.o.type === "Kabel" ? cableColor : d.color - ctx.globalAlpha = d.o.isVPN ? 0.1 : 0.8 + ctx.globalAlpha = d.o.isVPN ? (isBrightBackground ? 0.3 : 0.1) : 0.8 ctx.lineWidth = d.o.isVPN ? 1.5 : 2.5 ctx.stroke() }) @@ -415,11 +441,11 @@ define(["d3"], function (d3) { // -- draw node highlights -- if (highlightedNodes.length) { ctx.save() - ctx.shadowColor = "rgba(255, 255, 255, 1.0)" + ctx.shadowColor = isBrightBackground ? "rgba(0, 0, 0, 0.6)" : "rgba(255, 255, 255, 1.0)" ctx.shadowBlur = 10 * nodeRadius ctx.shadowOffsetX = 0 ctx.shadowOffsetY = 0 - ctx.globalCompositeOperation = "lighten" + ctx.globalCompositeOperation = isBrightBackground ? "darken" : "lighten" ctx.fillStyle = highlightColor ctx.beginPath() @@ -436,7 +462,7 @@ define(["d3"], function (d3) { if (highlightedLinks.length) { ctx.save() ctx.lineWidth = 2 * 5 * nodeRadius - ctx.shadowColor = "rgba(255, 255, 255, 1.0)" + ctx.shadowColor = isBrightBackground ? "rgba(0, 0, 0, 0.6)" : "rgba(255, 255, 255, 1.0)" ctx.shadowBlur = 10 * nodeRadius ctx.shadowOffsetX = 0 ctx.shadowOffsetY = 0 @@ -569,6 +595,20 @@ define(["d3"], function (d3) { } } + var mybuttons = [] + + function addButton(button) { + var el = button.onAdd() + mybuttons.push(el) + buttons.appendChild(el) + } + + function clearButtons() { + mybuttons.forEach( function (d) { + buttons.removeChild(d) + }) + } + el = document.createElement("div") el.classList.add("graph") @@ -606,12 +646,21 @@ define(["d3"], function (d3) { .on("tick", tickEvent) .on("end", savePositions) + var hackData + + addButton(new ChangeBackgroundButton(function () { + el.classList.toggle('graph-bright') + isBrightBackground = !isBrightBackground + self.setData(hackData) + })) + window.addEventListener("resize", resizeCanvas) panzoom() self.setData = function (data) { var oldNodes = {} + hackData = data intNodes.forEach( function (d) { oldNodes[d.o.id] = d @@ -653,7 +702,7 @@ define(["d3"], function (d3) { e.target = newNodesDict[d.target.id] if (d.isVPN) - e.color = "rgba(255, 255, 255, " + (0.6 / d.tq) + ")" + e.color = isBrightBackground ? "rgba(0, 0, 0, " + (0.6 / d.tq) + ")" : "rgba(255, 255, 255, " + (0.6 / d.tq) + ")" else e.color = linkScale(d.tq).hex() @@ -684,8 +733,8 @@ define(["d3"], function (d3) { bctx.scale(scale, scale) bctx.textBaseline = "middle" bctx.textAlign = "center" - bctx.fillStyle = "rgba(242, 227, 198, 1.0)" - bctx.shadowColor = "rgba(0, 0, 0, 1)" + bctx.fillStyle = isBrightBackground ? "rgba(13, 28, 57, 1.0)" : "rgba(242, 227, 198, 1.0)" + bctx.shadowColor = isBrightBackground ? "rgba(255, 255, 255, 1)" : "rgba(0, 0, 0, 1)" bctx.shadowBlur = 5 bctx.fillText(name, buffer.width / (2 * scale), buffer.height / (2 * scale)) @@ -774,6 +823,7 @@ define(["d3"], function (d3) { } self.destroy = function () { + clearButtons() force.stop() canvas.remove() force = null diff --git a/lib/gui.js b/lib/gui.js index c32bf62c..ad36cd3d 100644 --- a/lib/gui.js +++ b/lib/gui.js @@ -70,6 +70,51 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist, buttons.appendChild(buttonToggle) + function toggleScreenshotMode () { + screenshotMode = !screenshotMode + sidebar.container.classList.toggle('hide') + buttons.classList.toggle('hide') + Array.from(document.querySelectorAll('.leaflet-bottom')).forEach(function (el) { + el.classList.toggle('hide') + }) + } + + var screenshotMode = false + + var info = document.createElement("div") + info.classList.add("info-screenshot") + info.classList.add("vanish") + info.textContent = "ESC zum beenden des Screenshot-Modus" + document.body.appendChild(info) + + document.addEventListener("keydown", function(evt) { + if (!screenshotMode) + return + + evt = evt || window.event + var isEscape = false + + if ("key" in evt) + isEscape = (evt.key === "Escape" || evt.key === "Esc") + else + isEscape = (evt.keyCode === 27) + + if (isEscape) + toggleScreenshotMode() + }) + + var buttonScreenshot = document.createElement("button") + buttonScreenshot.textContent = "\uF118" + buttonScreenshot.onclick = function () { + toggleScreenshotMode() + info.classList.remove("vanish") + setTimeout(function () { + info.classList.add("vanish") + }, 5000) + } + + buttons.appendChild(buttonScreenshot) + var title = new Title(config) var header = new Container("header") diff --git a/scss/_base.scss b/scss/_base.scss index 21ca3ff4..250a8536 100644 --- a/scss/_base.scss +++ b/scss/_base.scss @@ -32,3 +32,7 @@ h6 { .hide { display: none; } + +.vanish { + opacity: 0; +} diff --git a/scss/_forcegraph.scss b/scss/_forcegraph.scss index 84bdd6f1..85625006 100644 --- a/scss/_forcegraph.scss +++ b/scss/_forcegraph.scss @@ -7,4 +7,8 @@ display: block; position: absolute; } -} +} + +.graph-bright { + background: #ffffff; +} diff --git a/scss/main.scss b/scss/main.scss index 27197090..4435167a 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -273,6 +273,18 @@ button.close { } } +.info-screenshot { + position: absolute; + right: 0; + bottom: 0; + margin: 1em; + border-radius: 6px; + padding: .5em; + @include shadow(1); + background: rgba(255, 255, 255, 0.7); + transition: .5s; +} + .sidebar h2, .sidebar h3 { padding-left: $buttondistance; padding-right: $buttondistance;