[TASK] Reformat code spacing & remove braces jslint

This commit is contained in:
Xaver Maierhofer 2016-05-22 14:51:30 +02:00
parent c0726461fb
commit a828a55d51
35 changed files with 1631 additions and 1359 deletions

View File

@ -8,7 +8,7 @@ module.exports = function (grunt) {
} }
}); });
grunt.registerTask("saveRevision", function() { grunt.registerTask("saveRevision", function () {
grunt.event.once("git-describe", function (rev) { grunt.event.once("git-describe", function (rev) {
grunt.option("gitRevision", rev); grunt.option("gitRevision", rev);
}); });

View File

@ -13,9 +13,21 @@
} }
], ],
"siteNames": [ "siteNames": [
{ "site": "ffhl", "name": "Lübeck" }, {
{ "site": "ffeh", "name": "Entenhausen" }, "site": "ffhl",
{ "site": "ffgt", "name": "Gothamcity" }, "name": "Lübeck"
{ "site": "ffal", "name": "Atlantis" } },
{
"site": "ffeh",
"name": "Entenhausen"
},
{
"site": "ffgt",
"name": "Gothamcity"
},
{
"site": "ffal",
"name": "Atlantis"
}
] ]
} }

View File

@ -1,9 +1,9 @@
function get(url) { function get(url) {
return new Promise(function(resolve, reject) { return new Promise(function (resolve, reject) {
var req = new XMLHttpRequest(); var req = new XMLHttpRequest();
req.open('GET', url); req.open('GET', url);
req.onload = function() { req.onload = function () {
if (req.status == 200) { if (req.status == 200) {
resolve(req.response); resolve(req.response);
} }
@ -12,7 +12,7 @@ function get(url) {
} }
}; };
req.onerror = function() { req.onerror = function () {
reject(Error("Network Error")); reject(Error("Network Error"));
}; };
@ -25,19 +25,19 @@ function getJSON(url) {
} }
function sortByKey(key, d) { function sortByKey(key, d) {
return d.slice().sort( function (a, b) { return d.slice().sort(function (a, b) {
return a[key] - b[key] return a[key] - b[key]
}).reverse() }).reverse()
} }
function limit(key, m, d) { function limit(key, m, d) {
return d.filter( function (d) { return d.filter(function (d) {
return d[key].isAfter(m) return d[key].isAfter(m)
}) })
} }
function sum(a) { function sum(a) {
return a.reduce( function (a, b) { return a.reduce(function (a, b) {
return a + b return a + b
}, 0) }, 0)
} }
@ -53,11 +53,13 @@ function trueDefault(d) {
function dictGet(dict, key) { function dictGet(dict, key) {
var k = key.shift(); var k = key.shift();
if (!(k in dict)) if (!(k in dict)) {
return null; return null;
}
if (key.length == 0) if (key.length == 0) {
return dict[k]; return dict[k];
}
return dictGet(dict[k], key) return dictGet(dict[k], key)
} }
@ -68,7 +70,7 @@ function localStorageTest() {
localStorage.setItem(test, test); localStorage.setItem(test, test);
localStorage.removeItem(test); localStorage.removeItem(test);
return true return true
} catch(e) { } catch (e) {
return false return false
} }
} }
@ -100,11 +102,11 @@ function has_location(d) {
function subtract(a, b) { function subtract(a, b) {
var ids = {}; var ids = {};
b.forEach( function (d) { b.forEach(function (d) {
ids[d.nodeinfo.node_id] = true ids[d.nodeinfo.node_id] = true
}); });
return a.filter( function (d) { return a.filter(function (d) {
return !(d.nodeinfo.node_id in ids) return !(d.nodeinfo.node_id in ids)
}) })
} }
@ -112,21 +114,23 @@ function subtract(a, b) {
/* Helpers working with links */ /* Helpers working with links */
function showDistance(d) { function showDistance(d) {
if (isNaN(d.distance)) if (isNaN(d.distance)) {
return; return;
}
return numeral(d.distance).format("0,0") + " m" return numeral(d.distance).format("0,0") + " m"
} }
function showTq(d) { function showTq(d) {
return numeral(1/d.tq).format("0%") return numeral(1 / d.tq).format("0%")
} }
/* Infobox stuff (XXX: move to module) */ /* Infobox stuff (XXX: move to module) */
function attributeEntry(el, label, value) { function attributeEntry(el, label, value) {
if (value === null || value == undefined) if (value === null || value == undefined) {
return; return;
}
var tr = document.createElement("tr"); var tr = document.createElement("tr");
var th = document.createElement("th"); var th = document.createElement("th");
@ -135,10 +139,11 @@ function attributeEntry(el, label, value) {
var td = document.createElement("td"); var td = document.createElement("td");
if (typeof value == "function") if (typeof value == "function") {
value(td); value(td);
else } else {
td.appendChild(document.createTextNode(value)); td.appendChild(document.createTextNode(value));
}
tr.appendChild(td); tr.appendChild(td);
@ -152,25 +157,29 @@ function createIframe(opt, width, height) {
width = typeof width !== 'undefined' ? width : '525px'; width = typeof width !== 'undefined' ? width : '525px';
height = typeof height !== 'undefined' ? height : '350px'; height = typeof height !== 'undefined' ? height : '350px';
if (opt.src) if (opt.src) {
el.src = opt.src; el.src = opt.src;
else } else {
el.src = opt; el.src = opt;
}
if (opt.frameBorder) if (opt.frameBorder) {
el.frameBorder = opt.frameBorder; el.frameBorder = opt.frameBorder;
else } else {
el.frameBorder = 1; el.frameBorder = 1;
}
if (opt.width) if (opt.width) {
el.width = opt.width; el.width = opt.width;
else } else {
el.width = width; el.width = width;
}
if (opt.height) if (opt.height) {
el.height = opt.height; el.height = opt.height;
else } else {
el.height = height; el.height = height;
}
el.scrolling = "no"; el.scrolling = "no";
el.seamless = "seamless"; el.seamless = "seamless";
@ -190,17 +199,19 @@ function showStat(o, subst) {
if (o.caption) { if (o.caption) {
caption = listReplace(o.caption, subst); caption = listReplace(o.caption, subst);
if (!content) if (!content) {
content = document.createTextNode(caption) content = document.createTextNode(caption)
} }
}
if (o.iframe) { if (o.iframe) {
content = createIframe(o.iframe, o.width, o.height); content = createIframe(o.iframe, o.width, o.height);
if (o.iframe.src) if (o.iframe.src) {
content.src = listReplace(o.iframe.src, subst); content.src = listReplace(o.iframe.src, subst);
else } else {
content.src = listReplace(o.iframe, subst) content.src = listReplace(o.iframe, subst)
} }
}
var p = document.createElement("p"); var p = document.createElement("p");
@ -210,12 +221,14 @@ function showStat(o, subst) {
link.href = listReplace(o.href, subst); link.href = listReplace(o.href, subst);
link.appendChild(content); link.appendChild(content);
if (caption && o.thumbnail) if (caption && o.thumbnail) {
link.title = caption; link.title = caption;
}
p.appendChild(link) p.appendChild(link)
} else } else {
p.appendChild(content); p.appendChild(content);
}
return p return p
} }

View File

@ -1,6 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no"> <meta name="viewport" content="width=device-width, user-scalable=no">
<link rel="stylesheet" href="css/ionicons.min.css"> <link rel="stylesheet" href="css/ionicons.min.css">
@ -12,7 +12,7 @@
<script> <script>
console.log("Version: #revision#") console.log("Version: #revision#")
</script> </script>
</head> </head>
<body> <body>
</body> </body>
</html> </html>

View File

@ -1,6 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no"> <meta name="viewport" content="width=device-width, user-scalable=no">
<link rel="stylesheet" href="bower_components/roboto-slab-fontface/roboto-slab-fontface.css"> <link rel="stylesheet" href="bower_components/roboto-slab-fontface/roboto-slab-fontface.css">
@ -11,7 +11,7 @@
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
<script src="bower_components/es6-shim/es6-shim.min.js"></script> <script src="bower_components/es6-shim/es6-shim.min.js"></script>
<script src="bower_components/requirejs/require.js" data-main="app"></script> <script src="bower_components/requirejs/require.js" data-main="app"></script>
</head> </head>
<body> <body>
</body> </body>
</html> </html>

View File

@ -1,5 +1,5 @@
define(function () { define(function () {
return function() { return function () {
this.render = function (d) { this.render = function (d) {
var el = document.createElement("div"); var el = document.createElement("div");
d.appendChild(el); d.appendChild(el);

View File

@ -1,7 +1,8 @@
define([], function () { define([], function () {
return function (tag) { return function (tag) {
if (!tag) if (!tag) {
tag = "div"; tag = "div";
}
var self = this; var self = this;

View File

@ -7,15 +7,18 @@ define(["filters/nodefilter"], function (NodeFilter) {
var data; var data;
function remove(d) { function remove(d) {
targets = targets.filter( function (e) { return d !== e; } ); targets = targets.filter(function (e) {
return d !== e;
});
} }
function add(d) { function add(d) {
targets.push(d); targets.push(d);
if (filteredData !== undefined) if (filteredData !== undefined) {
d.setData(filteredData); d.setData(filteredData);
} }
}
function setData(d) { function setData(d) {
data = d; data = d;
@ -23,24 +26,27 @@ define(["filters/nodefilter"], function (NodeFilter) {
} }
function refresh() { function refresh() {
if (data === undefined) if (data === undefined) {
return; return;
}
var filter = filters.reduce( function (a, f) { var filter = filters.reduce(function (a, f) {
return function (d) { return function (d) {
return a(d) && f.run(d); return a(d) && f.run(d);
}; };
}, function () { return true; }); }, function () {
return true;
});
filteredData = new NodeFilter(filter)(data); filteredData = new NodeFilter(filter)(data);
targets.forEach( function (t) { targets.forEach(function (t) {
t.setData(filteredData); t.setData(filteredData);
}); });
} }
function notifyObservers() { function notifyObservers() {
filterObservers.forEach( function (d) { filterObservers.forEach(function (d) {
d.filtersChanged(filters); d.filtersChanged(filters);
}); });
} }
@ -53,7 +59,9 @@ define(["filters/nodefilter"], function (NodeFilter) {
} }
function removeFilter(d) { function removeFilter(d) {
filters = filters.filter( function (e) { return d !== e; } ); filters = filters.filter(function (e) {
return d !== e;
});
notifyObservers(); notifyObservers();
refresh(); refresh();
} }
@ -64,11 +72,14 @@ define(["filters/nodefilter"], function (NodeFilter) {
d.filtersChanged(filters); d.filtersChanged(filters);
return function () { return function () {
filterObservers = filterObservers.filter( function (e) { return d !== e; }); filterObservers = filterObservers.filter(function (e) {
return d !== e;
});
}; };
} }
return { add: add, return {
add: add,
remove: remove, remove: remove,
setData: setData, setData: setData,
addFilter: addFilter, addFilter: addFilter,

View File

@ -9,10 +9,11 @@ define([], function () {
} }
function filtersChanged(filters) { function filtersChanged(filters) {
while (container.firstChild) while (container.firstChild) {
container.removeChild(container.firstChild); container.removeChild(container.firstChild);
}
filters.forEach( function (d) { filters.forEach(function (d) {
var li = document.createElement("li"); var li = document.createElement("li");
var div = document.createElement("div"); var div = document.createElement("div");
container.appendChild(li); container.appendChild(li);
@ -27,13 +28,15 @@ define([], function () {
li.appendChild(button); li.appendChild(button);
}); });
if (container.parentNode === div && filters.length === 0) if (container.parentNode === div && filters.length === 0) {
div.removeChild(container); div.removeChild(container);
else if (filters.length > 0) } else if (filters.length > 0) {
div.appendChild(container); div.appendChild(container);
} }
}
return { render: render, return {
render: render,
filtersChanged: filtersChanged filtersChanged: filtersChanged
}; };
}; };

View File

@ -11,8 +11,9 @@ define([], function () {
function run(d) { function run(d) {
var o = dictGet(d, key.slice(0)); var o = dictGet(d, key.slice(0));
if (f) if (f) {
o = f(o); o = f(o);
}
return o === value ? !negate : negate; return o === value ? !negate : negate;
} }
@ -22,10 +23,11 @@ define([], function () {
} }
function draw(el) { function draw(el) {
if (negate) if (negate) {
el.parentNode.classList.add("not"); el.parentNode.classList.add("not");
else } else {
el.parentNode.classList.remove("not"); el.parentNode.classList.remove("not");
}
strong.textContent = (negate ? "¬" : "" ) + value; strong.textContent = (negate ? "¬" : "" ) + value;
} }
@ -39,12 +41,14 @@ define([], function () {
draw(el); draw(el);
if (refresh) if (refresh) {
refresh(); refresh();
}
}; };
} }
return { run: run, return {
run: run,
setRefresh: setRefresh, setRefresh: setRefresh,
render: render render: render
}; };

View File

@ -11,20 +11,22 @@ define([], function () {
var filteredIds = new Set(); var filteredIds = new Set();
n.graph = {}; n.graph = {};
n.graph.nodes = data.graph.nodes.filter( function (d) { n.graph.nodes = data.graph.nodes.filter(function (d) {
var r; var r;
if (d.node) if (d.node) {
r = filter(d.node); r = filter(d.node);
else } else {
r = filter({}); r = filter({});
}
if (r) if (r) {
filteredIds.add(d.id); filteredIds.add(d.id);
}
return r; return r;
}); });
n.graph.links = data.graph.links.filter( function (d) { n.graph.links = data.graph.links.filter(function (d) {
return filteredIds.has(d.source.id) && filteredIds.has(d.target.id); return filteredIds.has(d.source.id) && filteredIds.has(d.target.id);
}); });

View File

@ -32,22 +32,24 @@ define(["d3"], function (d3) {
} }
function savePositions() { function savePositions() {
if (!localStorageTest()) if (!localStorageTest()) {
return; return;
}
var save = intNodes.map( function (d) { var save = intNodes.map(function (d) {
return { id: d.o.id, x: d.x, y: d.y }; return {id: d.o.id, x: d.x, y: d.y};
}); });
localStorage.setItem("graph/nodeposition", JSON.stringify(save)); localStorage.setItem("graph/nodeposition", JSON.stringify(save));
} }
function nodeName(d) { function nodeName(d) {
if (d.o.node && d.o.node.nodeinfo) if (d.o.node && d.o.node.nodeinfo) {
return d.o.node.nodeinfo.hostname; return d.o.node.nodeinfo.hostname;
else } else {
return d.o.id; return d.o.id;
} }
}
function dragstart() { function dragstart() {
var e = translateXY(d3.mouse(el)); var e = translateXY(d3.mouse(el));
@ -56,8 +58,9 @@ define(["d3"], function (d3) {
return distancePoint(e, d) < NODE_RADIUS; return distancePoint(e, d) < NODE_RADIUS;
}); });
if (nodes.length === 0) if (nodes.length === 0) {
return; return;
}
draggedNode = nodes[0]; draggedNode = nodes[0];
d3.event.sourceEvent.stopPropagation(); d3.event.sourceEvent.stopPropagation();
@ -110,8 +113,9 @@ define(["d3"], function (d3) {
var ease = d3.ease("cubic-in-out"); var ease = d3.ease("cubic-in-out");
d3.timer(function (t) { d3.timer(function (t) {
if (t >= duration) if (t >= duration) {
return true; return true;
}
var v = interpolate(ease(t / duration)); var v = interpolate(ease(t / duration));
zoomBehavior.translate([v.x, v.y]); zoomBehavior.translate([v.x, v.y]);
@ -124,8 +128,10 @@ define(["d3"], function (d3) {
} }
function onPanZoom() { function onPanZoom() {
savedPanZoom = {translate: zoomBehavior.translate(), savedPanZoom = {
scale: zoomBehavior.scale()}; translate: zoomBehavior.translate(),
scale: zoomBehavior.scale()
};
panzoom(); panzoom();
} }
@ -133,14 +139,15 @@ define(["d3"], function (d3) {
var translate = zoomBehavior.translate(); var translate = zoomBehavior.translate();
var scale = zoomBehavior.scale(); var scale = zoomBehavior.scale();
panzoomReal(translate, scale); panzoomReal(translate, scale);
} }
function panzoomReal(translate, scale) { function panzoomReal(translate, scale) {
screenRect = {left: -translate[0] / scale, top: -translate[1] / scale, screenRect = {
left: -translate[0] / scale, top: -translate[1] / scale,
right: (canvas.width - translate[0]) / scale, right: (canvas.width - translate[0]) / scale,
bottom: (canvas.height - translate[1]) / scale}; bottom: (canvas.height - translate[1]) / scale
};
requestAnimationFrame(redraw); requestAnimationFrame(redraw);
} }
@ -177,16 +184,17 @@ define(["d3"], function (d3) {
highlightedNodes = []; highlightedNodes = [];
highlightedLinks = []; highlightedLinks = [];
if (highlight !== undefined) if (highlight !== undefined) {
if (highlight.type === "node") { if (highlight.type === "node") {
var n = nodesDict[highlight.o.nodeinfo.node_id]; var n = nodesDict[highlight.o.nodeinfo.node_id];
if (n) { if (n) {
highlightedNodes = [n]; highlightedNodes = [n];
if (!nopanzoom) if (!nopanzoom) {
panzoomTo([n.x, n.y], [n.x, n.y]); panzoomTo([n.x, n.y], [n.x, n.y]);
} }
}
return; return;
} else if (highlight.type === "link") { } else if (highlight.type === "link") {
@ -196,21 +204,28 @@ define(["d3"], function (d3) {
highlightedLinks = [l]; highlightedLinks = [l];
if (!nopanzoom) { if (!nopanzoom) {
var x = d3.extent([l.source, l.target], function (d) { return d.x; }); var x = d3.extent([l.source, l.target], function (d) {
var y = d3.extent([l.source, l.target], function (d) { return d.y; }); return d.x;
});
var y = d3.extent([l.source, l.target], function (d) {
return d.y;
});
panzoomTo([x[0], y[0]], [x[1], y[1]]); panzoomTo([x[0], y[0]], [x[1], y[1]]);
} }
} }
return; return;
} }
}
if (!nopanzoom) if (!nopanzoom) {
if (!savedPanZoom) if (!savedPanZoom) {
panzoomTo([0, 0], force.size()); panzoomTo([0, 0], force.size());
else } else {
animatePanzoom(savedPanZoom.translate, savedPanZoom.scale); animatePanzoom(savedPanZoom.translate, savedPanZoom.scale);
} }
}
}
function drawLabel(d) { function drawLabel(d) {
var neighbours = d.neighbours.filter(function (d) { var neighbours = d.neighbours.filter(function (d) {
@ -226,8 +241,9 @@ define(["d3"], function (d3) {
var angle = Math.PI / 2; var angle = Math.PI / 2;
if (neighbours.length > 0) if (neighbours.length > 0) {
angle = Math.PI + Math.atan2(sumSin, sumCos); angle = Math.PI + Math.atan2(sumSin, sumCos);
}
var cos = Math.cos(angle); var cos = Math.cos(angle);
var sin = Math.sin(angle); var sin = Math.sin(angle);
@ -351,7 +367,6 @@ define(["d3"], function (d3) {
ctx.stroke(); ctx.stroke();
// -- draw nodes -- // -- draw nodes --
ctx.save(); ctx.save();
ctx.scale(1 / scale / r, 1 / scale / r); ctx.scale(1 / scale / r, 1 / scale / r);
@ -378,8 +393,9 @@ define(["d3"], function (d3) {
ctx.beginPath(); ctx.beginPath();
nodes.filter(visibleNodes).forEach(function (d) { nodes.filter(visibleNodes).forEach(function (d) {
var clients = d.o.node.statistics.clients; var clients = d.o.node.statistics.clients;
if (clients === 0) if (clients === 0) {
return; return;
}
var startDistance = 16; var startDistance = 16;
var radius = 3; var radius = 3;
@ -449,8 +465,9 @@ define(["d3"], function (d3) {
} }
// -- draw labels -- // -- draw labels --
if (scale > 0.9) if (scale > 0.9) {
intNodes.filter(visibleNodes).forEach(drawLabel, scale); intNodes.filter(visibleNodes).forEach(drawLabel, scale);
}
ctx.restore(); ctx.restore();
} }
@ -483,33 +500,40 @@ define(["d3"], function (d3) {
var l2 = distance(a, b); var l2 = distance(a, b);
if (l2 === 0) if (l2 === 0) {
return distance(p, a); return distance(p, a);
}
var t = ((p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y)) / l2; var t = ((p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y)) / l2;
if (t < 0) if (t < 0) {
return distance(p, a); return distance(p, a);
}
if (t > 1) if (t > 1) {
return distance(p, b); return distance(p, b);
}
return Math.sqrt(distance(p, { x: a.x + t * (b.x - a.x), return Math.sqrt(distance(p, {
y: a.y + t * (b.y - a.y) })); x: a.x + t * (b.x - a.x),
y: a.y + t * (b.y - a.y)
}));
} }
function translateXY(d) { function translateXY(d) {
var translate = zoomBehavior.translate(); var translate = zoomBehavior.translate();
var scale = zoomBehavior.scale(); var scale = zoomBehavior.scale();
return {x: (d[0] - translate[0]) / scale, return {
x: (d[0] - translate[0]) / scale,
y: (d[1] - translate[1]) / scale y: (d[1] - translate[1]) / scale
}; };
} }
function onClick() { function onClick() {
if (d3.event.defaultPrevented) if (d3.event.defaultPrevented) {
return; return;
}
var e = translateXY(d3.mouse(el)); var e = translateXY(d3.mouse(el));
@ -550,14 +574,17 @@ define(["d3"], function (d3) {
return function () { return function () {
var e = d3.event; var e = d3.event;
if (e.altKey || e.ctrlKey || e.metaKey) if (e.altKey || e.ctrlKey || e.metaKey) {
return; return;
}
if (e.keyCode === 43) if (e.keyCode === 43) {
zoom(z, 1.41); zoom(z, 1.41);
}
if (e.keyCode === 45) if (e.keyCode === 45) {
zoom(z, 1 / 1.41); zoom(z, 1 / 1.41);
}
}; };
} }
@ -584,16 +611,18 @@ define(["d3"], function (d3) {
.charge(-250) .charge(-250)
.gravity(0.1) .gravity(0.1)
.linkDistance(function (d) { .linkDistance(function (d) {
if (d.o.type === "fastd" || d.o.type === "L2TP") if (d.o.type === "fastd" || d.o.type === "L2TP") {
return 0; return 0;
else } else {
return LINK_DISTANCE; return LINK_DISTANCE;
}
}) })
.linkStrength(function (d) { .linkStrength(function (d) {
if (d.o.type === "fastd" || d.o.type === "L2TP") if (d.o.type === "fastd" || d.o.type === "L2TP") {
return 0; return 0;
else } else {
return Math.max(0.5, 1 / d.o.tq); return Math.max(0.5, 1 / d.o.tq);
}
}) })
.on("tick", tickEvent) .on("tick", tickEvent)
.on("end", savePositions); .on("end", savePositions);
@ -605,16 +634,17 @@ define(["d3"], function (d3) {
self.setData = function (data) { self.setData = function (data) {
var oldNodes = {}; var oldNodes = {};
intNodes.forEach( function (d) { intNodes.forEach(function (d) {
oldNodes[d.o.id] = d; oldNodes[d.o.id] = d;
}); });
intNodes = data.graph.nodes.map( function (d) { intNodes = data.graph.nodes.map(function (d) {
var e; var e;
if (d.id in oldNodes) if (d.id in oldNodes) {
e = oldNodes[d.id]; e = oldNodes[d.id];
else } else {
e = {}; e = {};
}
e.o = d; e.o = d;
@ -623,31 +653,33 @@ define(["d3"], function (d3) {
var newNodesDict = {}; var newNodesDict = {};
intNodes.forEach( function (d) { intNodes.forEach(function (d) {
newNodesDict[d.o.id] = d; newNodesDict[d.o.id] = d;
}); });
var oldLinks = {}; var oldLinks = {};
intLinks.forEach( function (d) { intLinks.forEach(function (d) {
oldLinks[d.o.id] = d; oldLinks[d.o.id] = d;
}); });
intLinks = data.graph.links.map( function (d) { intLinks = data.graph.links.map(function (d) {
var e; var e;
if (d.id in oldLinks) if (d.id in oldLinks) {
e = oldLinks[d.id]; e = oldLinks[d.id];
else } else {
e = {}; e = {};
}
e.o = d; e.o = d;
e.source = newNodesDict[d.source.id]; e.source = newNodesDict[d.source.id];
e.target = newNodesDict[d.target.id]; e.target = newNodesDict[d.target.id];
if (d.type === "fastd" || d.type === "L2TP") if (d.type === "fastd" || d.type === "L2TP") {
e.color = "rgba(255, 255, 255, " + (0.6 / d.tq) + ")"; e.color = "rgba(255, 255, 255, " + (0.6 / d.tq) + ")";
else } else {
e.color = linkScale(d.tq).hex(); e.color = linkScale(d.tq).hex();
}
return e; return e;
}); });
@ -658,8 +690,9 @@ define(["d3"], function (d3) {
intNodes.forEach(function (d) { intNodes.forEach(function (d) {
d.neighbours = {}; d.neighbours = {};
if (d.o.node) if (d.o.node) {
nodesDict[d.o.node.nodeinfo.node_id] = d; nodesDict[d.o.node.nodeinfo.node_id] = d;
}
var name = nodeName(d); var name = nodeName(d);
@ -692,8 +725,9 @@ define(["d3"], function (d3) {
d.source.neighbours[d.target.o.id] = {node: d.target, link: d}; d.source.neighbours[d.target.o.id] = {node: d.target, link: d};
d.target.neighbours[d.source.o.id] = {node: d.source, link: d}; d.target.neighbours[d.source.o.id] = {node: d.source, link: d};
if (d.o.source && d.o.target) if (d.o.source && d.o.target) {
linksDict[d.o.id] = d; linksDict[d.o.id] = d;
}
}); });
intNodes.forEach(function (d) { intNodes.forEach(function (d) {
@ -702,22 +736,32 @@ define(["d3"], function (d3) {
}); });
}); });
nodes = intNodes.filter(function (d) { return !d.o.unseen && d.o.node; }); nodes = intNodes.filter(function (d) {
uplinkNodes = nodes.filter(function (d) { return d.o.node.flags.uplink; }); return !d.o.unseen && d.o.node;
nonUplinkNodes = nodes.filter(function (d) { return !d.o.node.flags.uplink; }); });
unseenNodes = intNodes.filter(function (d) { return d.o.unseen && d.o.node; }); uplinkNodes = nodes.filter(function (d) {
unknownNodes = intNodes.filter(function (d) { return !d.o.node; }); return d.o.node.flags.uplink;
});
nonUplinkNodes = nodes.filter(function (d) {
return !d.o.node.flags.uplink;
});
unseenNodes = intNodes.filter(function (d) {
return d.o.unseen && d.o.node;
});
unknownNodes = intNodes.filter(function (d) {
return !d.o.node;
});
if (localStorageTest()) { if (localStorageTest()) {
var save = JSON.parse(localStorage.getItem("graph/nodeposition")); var save = JSON.parse(localStorage.getItem("graph/nodeposition"));
if (save) { if (save) {
var nodePositions = {}; var nodePositions = {};
save.forEach( function (d) { save.forEach(function (d) {
nodePositions[d.id] = d; nodePositions[d.id] = d;
}); });
intNodes.forEach( function (d) { intNodes.forEach(function (d) {
if (nodePositions[d.o.id] && (d.x === undefined || d.y === undefined)) { if (nodePositions[d.o.id] && (d.x === undefined || d.y === undefined)) {
d.x = nodePositions[d.o.id].x; d.x = nodePositions[d.o.id].x;
d.y = nodePositions[d.o.id].y; d.y = nodePositions[d.o.id].y;
@ -761,8 +805,9 @@ define(["d3"], function (d3) {
canvas.remove(); canvas.remove();
force = null; force = null;
if (el.parentNode) if (el.parentNode) {
el.parentNode.removeChild(el); el.parentNode.removeChild(el);
}
}; };
self.render = function (d) { self.render = function (d) {

View File

@ -1,8 +1,8 @@
define([ "chroma-js", "map", "sidebar", "tabs", "container", "meshstats", define(["chroma-js", "map", "sidebar", "tabs", "container", "meshstats",
"legend", "linklist", "nodelist", "simplenodelist", "infobox/main", "legend", "linklist", "nodelist", "simplenodelist", "infobox/main",
"proportions", "forcegraph", "title", "about", "datadistributor", "proportions", "forcegraph", "title", "about", "datadistributor",
"filters/filtergui" ], "filters/filtergui"],
function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist, function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist,
Nodelist, SimpleNodelist, Infobox, Proportions, ForceGraph, Nodelist, SimpleNodelist, Infobox, Proportions, ForceGraph,
Title, About, DataDistributor, FilterGUI) { Title, About, DataDistributor, FilterGUI) {
return function (config, router) { return function (config, router) {
@ -21,8 +21,9 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist,
fanoutUnfiltered.add(fanout); fanoutUnfiltered.add(fanout);
function removeContent() { function removeContent() {
if (!content) if (!content) {
return; return;
}
router.removeTarget(content); router.removeTarget(content);
fanout.remove(content); fanout.remove(content);
@ -59,10 +60,11 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist,
var buttonToggle = document.createElement("button"); var buttonToggle = document.createElement("button");
buttonToggle.textContent = "\uF133"; buttonToggle.textContent = "\uF133";
buttonToggle.onclick = function () { buttonToggle.onclick = function () {
if (content.constructor === Map) if (content.constructor === Map) {
router.view("g"); router.view("g");
else } else {
router.view("m"); router.view("m");
}
}; };
buttons.appendChild(buttonToggle); buttons.appendChild(buttonToggle);
@ -119,4 +121,4 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist,
return self; return self;
}; };
}); });

View File

@ -38,7 +38,7 @@ define(function () {
if (config.linkInfos) { if (config.linkInfos) {
var source = d.source.node_id; var source = d.source.node_id;
var target = d.target.node_id; var target = d.target.node_id;
config.linkInfos.forEach( function (linkInfo) { config.linkInfos.forEach(function (linkInfo) {
var h4 = document.createElement("h4"); var h4 = document.createElement("h4");
h4.textContent = linkInfo.name; h4.textContent = linkInfo.name;
el.appendChild(h4); el.appendChild(h4);

View File

@ -5,9 +5,10 @@ define(function () {
el.appendChild(sidebarTitle); el.appendChild(sidebarTitle);
getJSON("https://nominatim.openstreetmap.org/reverse?format=json&lat=" + d.lat + "&lon=" + d.lng + "&zoom=18&addressdetails=0") getJSON("https://nominatim.openstreetmap.org/reverse?format=json&lat=" + d.lat + "&lon=" + d.lng + "&zoom=18&addressdetails=0")
.then(function(result) { .then(function (result) {
if(result.display_name) if (result.display_name) {
sidebarTitle.textContent = result.display_name; sidebarTitle.textContent = result.display_name;
}
}); });
var editLat = document.createElement("input"); var editLat = document.createElement("input");
@ -32,7 +33,7 @@ define(function () {
var linkPlain = document.createElement("a"); var linkPlain = document.createElement("a");
linkPlain.textContent = "plain"; linkPlain.textContent = "plain";
linkPlain.onclick = function() { linkPlain.onclick = function () {
switch2plain(); switch2plain();
return false; return false;
}; };
@ -40,7 +41,7 @@ define(function () {
var linkUci = document.createElement("a"); var linkUci = document.createElement("a");
linkUci.textContent = "uci"; linkUci.textContent = "uci";
linkUci.onclick = function() { linkUci.onclick = function () {
switch2uci(); switch2uci();
return false; return false;
}; };
@ -63,7 +64,9 @@ define(function () {
var btn = document.createElement("button"); var btn = document.createElement("button");
btn.className = "ion-ios-copy"; btn.className = "ion-ios-copy";
btn.title = "Kopieren"; btn.title = "Kopieren";
btn.onclick = function() { copy2clip(inputElem.id); }; btn.onclick = function () {
copy2clip(inputElem.id);
};
inputElem.id = "location-" + name; inputElem.id = "location-" + name;
inputElem.readOnly = true; inputElem.readOnly = true;
var line = document.createElement("p"); var line = document.createElement("p");

View File

@ -21,8 +21,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
return a + "° " + numeral(min).format("0.000") + suffix; return a + "° " + numeral(min).format("0.000") + suffix;
} }
if (!has_location(d)) if (!has_location(d)) {
return undefined; return undefined;
}
return function (el) { return function (el) {
var latitude = d.nodeinfo.location.latitude; var latitude = d.nodeinfo.location.latitude;
@ -39,10 +40,11 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
function showStatus(d) { function showStatus(d) {
return function (el) { return function (el) {
el.classList.add(d.flags.unseen ? "unseen" : (d.flags.online ? "online" : "offline")); el.classList.add(d.flags.unseen ? "unseen" : (d.flags.online ? "online" : "offline"));
if (d.flags.online) if (d.flags.online) {
el.textContent = "online, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")"; el.textContent = "online, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")";
else } else {
el.textContent = "offline, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")"; el.textContent = "offline, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")";
}
}; };
} }
@ -50,8 +52,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
var release = dictGet(d.nodeinfo, ["software", "firmware", "release"]); var release = dictGet(d.nodeinfo, ["software", "firmware", "release"]);
var base = dictGet(d.nodeinfo, ["software", "firmware", "base"]); var base = dictGet(d.nodeinfo, ["software", "firmware", "base"]);
if (release === null || base === null) if (release === null || base === null) {
return undefined; return undefined;
}
return release + " / " + base; return release + " / " + base;
} }
@ -59,31 +62,36 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
function showSite(d, config) { function showSite(d, config) {
var site = dictGet(d.nodeinfo, ["system", "site_code"]); var site = dictGet(d.nodeinfo, ["system", "site_code"]);
var rt = site; var rt = site;
if (config.siteNames) if (config.siteNames) {
config.siteNames.forEach( function (t) { config.siteNames.forEach(function (t) {
if(site === t.site) if (site === t.site) {
rt = t.name; rt = t.name;
}
}); });
}
return rt; return rt;
} }
function showUptime(d) { function showUptime(d) {
if (!("uptime" in d.statistics)) if (!("uptime" in d.statistics)) {
return undefined; return undefined;
}
return moment.duration(d.statistics.uptime, "seconds").humanize(); return moment.duration(d.statistics.uptime, "seconds").humanize();
} }
function showFirstseen(d) { function showFirstseen(d) {
if (!("firstseen" in d)) if (!("firstseen" in d)) {
return undefined; return undefined;
}
return d.firstseen.fromNow(true); return d.firstseen.fromNow(true);
} }
function showClients(d) { function showClients(d) {
if (!d.flags.online) if (!d.flags.online) {
return undefined; return undefined;
}
return function (el) { return function (el) {
el.appendChild(document.createTextNode(d.statistics.clients > 0 ? d.statistics.clients : "keine")); el.appendChild(document.createTextNode(d.statistics.clients > 0 ? d.statistics.clients : "keine"));
@ -98,25 +106,28 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
function showIPs(d) { function showIPs(d) {
var ips = dictGet(d.nodeinfo, ["network", "addresses"]); var ips = dictGet(d.nodeinfo, ["network", "addresses"]);
if (ips === null) if (ips === null) {
return undefined; return undefined;
}
ips.sort(); ips.sort();
return function (el) { return function (el) {
ips.forEach( function (ip, i) { ips.forEach(function (ip, i) {
var link = !ip.startsWith("fe80:"); var link = !ip.startsWith("fe80:");
if (i > 0) if (i > 0) {
el.appendChild(document.createElement("br")); el.appendChild(document.createElement("br"));
}
if (link) { if (link) {
var a = document.createElement("a"); var a = document.createElement("a");
a.href = "http://[" + ip + "]/"; a.href = "http://[" + ip + "]/";
a.textContent = ip; a.textContent = ip;
el.appendChild(a); el.appendChild(a);
} else } else {
el.appendChild(document.createTextNode(ip)); el.appendChild(document.createTextNode(ip));
}
}); });
}; };
} }
@ -149,8 +160,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
span.style.background = "rgba(255, 50, 50, 0.6)"; span.style.background = "rgba(255, 50, 50, 0.6)";
span.appendChild(bar); span.appendChild(bar);
} }
else else {
{
bar.style.width = (v * 100) + "%"; bar.style.width = (v * 100) + "%";
span.appendChild(bar); span.appendChild(bar);
} }
@ -163,8 +173,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
} }
function showLoad(d) { function showLoad(d) {
if (!("loadavg" in d.statistics)) if (!("loadavg" in d.statistics)) {
return undefined; return undefined;
}
return function (el) { return function (el) {
el.appendChild(showLoadBar("load-avg", d.statistics.loadavg)); el.appendChild(showLoadBar("load-avg", d.statistics.loadavg));
@ -172,8 +183,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
} }
function showRAM(d) { function showRAM(d) {
if (!("memory_usage" in d.statistics)) if (!("memory_usage" in d.statistics)) {
return undefined; return undefined;
}
return function (el) { return function (el) {
el.appendChild(showBar("memory-usage", d.statistics.memory_usage)); el.appendChild(showBar("memory-usage", d.statistics.memory_usage));
@ -182,15 +194,17 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
function showPages(d) { function showPages(d) {
var webpages = dictGet(d.nodeinfo, ["pages"]); var webpages = dictGet(d.nodeinfo, ["pages"]);
if (webpages === null) if (webpages === null) {
return undefined; return undefined;
}
webpages.sort(); webpages.sort();
return function (el) { return function (el) {
webpages.forEach( function (webpage, i) { webpages.forEach(function (webpage, i) {
if (i > 0) if (i > 0) {
el.appendChild(document.createElement("br")); el.appendChild(document.createElement("br"));
}
var a = document.createElement("span"); var a = document.createElement("span");
var link = document.createElement("a"); var link = document.createElement("a");
@ -203,8 +217,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
a.appendChild(t1); a.appendChild(t1);
link.textContent = webpage.replace(/^https:\/\//i, ""); link.textContent = webpage.replace(/^https:\/\//i, "");
} }
else else {
link.textContent = webpage.replace(/^http:\/\//i, ""); link.textContent = webpage.replace(/^http:\/\//i, "");
}
a.appendChild(link); a.appendChild(link);
el.appendChild(a); el.appendChild(a);
}); });
@ -213,8 +228,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
function showAutoupdate(d) { function showAutoupdate(d) {
var au = dictGet(d.nodeinfo, ["software", "autoupdater"]); var au = dictGet(d.nodeinfo, ["software", "autoupdater"]);
if (!au) if (!au) {
return undefined; return undefined;
}
return au.enabled ? "aktiviert (" + au.branch + ")" : "deaktiviert"; return au.enabled ? "aktiviert (" + au.branch + ")" : "deaktiviert";
} }
@ -226,7 +242,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
return showStat(o, subst); return showStat(o, subst);
} }
return function(config, el, router, d) { return function (config, el, router, d) {
var h2 = document.createElement("h2"); var h2 = document.createElement("h2");
h2.textContent = d.nodeinfo.hostname; h2.textContent = d.nodeinfo.hostname;
el.appendChild(h2); el.appendChild(h2);
@ -238,8 +254,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
attributeEntry(attributes, "Gateway", d.flags.gateway ? "ja" : null); attributeEntry(attributes, "Gateway", d.flags.gateway ? "ja" : null);
attributeEntry(attributes, "Koordinaten", showGeoURI(d)); attributeEntry(attributes, "Koordinaten", showGeoURI(d));
if (config.showContact) if (config.showContact) {
attributeEntry(attributes, "Kontakt", dictGet(d.nodeinfo, ["owner", "contact"])); attributeEntry(attributes, "Kontakt", dictGet(d.nodeinfo, ["owner", "contact"]));
}
attributeEntry(attributes, "Hardware", dictGet(d.nodeinfo, ["hardware", "model"])); attributeEntry(attributes, "Hardware", dictGet(d.nodeinfo, ["hardware", "model"]));
attributeEntry(attributes, "Primäre MAC", dictGet(d.nodeinfo, ["network", "mac"])); attributeEntry(attributes, "Primäre MAC", dictGet(d.nodeinfo, ["network", "mac"]));
@ -258,14 +275,14 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
el.appendChild(attributes); el.appendChild(attributes);
if (config.nodeInfos) {
if (config.nodeInfos) config.nodeInfos.forEach(function (nodeInfo) {
config.nodeInfos.forEach( function (nodeInfo) {
var h4 = document.createElement("h4"); var h4 = document.createElement("h4");
h4.textContent = nodeInfo.name; h4.textContent = nodeInfo.name;
el.appendChild(h4); el.appendChild(h4);
el.appendChild(showStatImg(nodeInfo, d)); el.appendChild(showStatImg(nodeInfo, d));
}); });
}
if (d.neighbours.length > 0) { if (d.neighbours.length > 0) {
var h3 = document.createElement("h3"); var h3 = document.createElement("h3");
@ -302,7 +319,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
var tbody = document.createElement("tbody"); var tbody = document.createElement("tbody");
d.neighbours.forEach( function (d) { d.neighbours.forEach(function (d) {
var unknown = !(d.node); var unknown = !(d.node);
var tr = document.createElement("tr"); var tr = document.createElement("tr");
@ -314,8 +331,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
var a1 = document.createElement("a"); var a1 = document.createElement("a");
a1.classList.add("hostname"); a1.classList.add("hostname");
a1.textContent = unknown ? d.id : d.node.nodeinfo.hostname; a1.textContent = unknown ? d.id : d.node.nodeinfo.hostname;
if (!unknown) if (!unknown) {
a1.href = "#"; a1.href = "#";
}
a1.onclick = router.node(d.node); a1.onclick = router.node(d.node);
td2.appendChild(a1); td2.appendChild(a1);
@ -364,4 +382,4 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"],
el.appendChild(table); el.appendChild(table);
} }
}; };
}); });

View File

@ -3,23 +3,29 @@ define(["sorttable", "virtual-dom"], function (SortTable, V) {
return (d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " " + d.target.node.nodeinfo.hostname; return (d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " " + d.target.node.nodeinfo.hostname;
} }
var headings = [{ name: "Knoten", var headings = [{
name: "Knoten",
sort: function (a, b) { sort: function (a, b) {
return linkName(a).localeCompare(linkName(b)); return linkName(a).localeCompare(linkName(b));
}, },
reverse: false reverse: false
}, },
{ name: "TQ", {
sort: function (a, b) { return a.tq - b.tq; }, name: "TQ",
sort: function (a, b) {
return a.tq - b.tq;
},
reverse: true reverse: true
}, },
{ name: "Typ", {
name: "Typ",
sort: function (a, b) { sort: function (a, b) {
return a.type.localeCompare(b.type); return a.type.localeCompare(b.type);
}, },
reverse: false reverse: false
}, },
{ name: "Entfernung", {
name: "Entfernung",
sort: function (a, b) { sort: function (a, b) {
return (a.distance === undefined ? -1 : a.distance) - return (a.distance === undefined ? -1 : a.distance) -
(b.distance === undefined ? -1 : b.distance); (b.distance === undefined ? -1 : b.distance);
@ -27,7 +33,7 @@ define(["sorttable", "virtual-dom"], function (SortTable, V) {
reverse: true reverse: true
}]; }];
return function(linkScale, router) { return function (linkScale, router) {
var table = new SortTable(headings, 2, renderRow); var table = new SortTable(headings, 2, renderRow);
function renderRow(d) { function renderRow(d) {

View File

@ -29,28 +29,28 @@ define(["leaflet"], function (L) {
fillOpacity: 0.2 fillOpacity: 0.2
}, },
initialize: function(latlng) { initialize: function (latlng) {
this.accuracyCircle = L.circle(latlng, 0, this.accuracyCircle); this.accuracyCircle = L.circle(latlng, 0, this.accuracyCircle);
this.outerCircle = L.circleMarker(latlng, this.outerCircle); this.outerCircle = L.circleMarker(latlng, this.outerCircle);
L.CircleMarker.prototype.initialize.call(this, latlng, this.innerCircle); L.CircleMarker.prototype.initialize.call(this, latlng, this.innerCircle);
this.on("remove", function() { this.on("remove", function () {
this._map.removeLayer(this.accuracyCircle); this._map.removeLayer(this.accuracyCircle);
this._map.removeLayer(this.outerCircle); this._map.removeLayer(this.outerCircle);
}); });
}, },
setLatLng: function(latlng) { setLatLng: function (latlng) {
this.accuracyCircle.setLatLng(latlng); this.accuracyCircle.setLatLng(latlng);
this.outerCircle.setLatLng(latlng); this.outerCircle.setLatLng(latlng);
L.CircleMarker.prototype.setLatLng.call(this, latlng); L.CircleMarker.prototype.setLatLng.call(this, latlng);
}, },
setAccuracy: function(accuracy) { setAccuracy: function (accuracy) {
this.accuracyCircle.setRadius(accuracy); this.accuracyCircle.setRadius(accuracy);
}, },
onAdd: function(map) { onAdd: function (map) {
this.accuracyCircle.addTo(map).bringToBack(); this.accuracyCircle.addTo(map).bringToBack();
this.outerCircle.addTo(map); this.outerCircle.addTo(map);
L.CircleMarker.prototype.onAdd.call(this, map); L.CircleMarker.prototype.onAdd.call(this, map);

View File

@ -1,5 +1,5 @@
define(["moment", "router", "leaflet", "gui", "numeral"], define(["moment", "router", "leaflet", "gui", "numeral"],
function (moment, Router, L, GUI, numeral) { function (moment, Router, L, GUI, numeral) {
return function (config) { return function (config) {
function handleData(data) { function handleData(data) {
var dataNodes = {}; var dataNodes = {};
@ -9,7 +9,6 @@ function (moment, Router, L, GUI, numeral) {
dataGraph.batadv.nodes = []; dataGraph.batadv.nodes = [];
dataGraph.batadv.links = []; dataGraph.batadv.links = [];
function rearrangeLinks(d) { function rearrangeLinks(d) {
d.source += dataGraph.batadv.nodes.length; d.source += dataGraph.batadv.nodes.length;
d.target += dataGraph.batadv.nodes.length; d.target += dataGraph.batadv.nodes.length;
@ -17,7 +16,7 @@ function (moment, Router, L, GUI, numeral) {
for (var i = 0; i < data.length; ++i) { for (var i = 0; i < data.length; ++i) {
var vererr; var vererr;
if(i % 2) if (i % 2) {
if (data[i].version !== 1) { if (data[i].version !== 1) {
vererr = "Unsupported graph version: " + data[i].version; vererr = "Unsupported graph version: " + data[i].version;
console.log(vererr); //silent fail console.log(vererr); //silent fail
@ -27,8 +26,7 @@ function (moment, Router, L, GUI, numeral) {
dataGraph.batadv.links = dataGraph.batadv.links.concat(data[i].batadv.links); dataGraph.batadv.links = dataGraph.batadv.links.concat(data[i].batadv.links);
dataGraph.timestamp = data[i].timestamp; dataGraph.timestamp = data[i].timestamp;
} }
else } else if (data[i].version !== 2) {
if (data[i].version !== 2) {
vererr = "Unsupported nodes version: " + data[i].version; vererr = "Unsupported nodes version: " + data[i].version;
console.log(vererr); //silent fail console.log(vererr); //silent fail
} else { } else {
@ -37,11 +35,11 @@ function (moment, Router, L, GUI, numeral) {
} }
} }
var nodes = dataNodes.nodes.filter( function (d) { var nodes = dataNodes.nodes.filter(function (d) {
return "firstseen" in d && "lastseen" in d; return "firstseen" in d && "lastseen" in d;
}); });
nodes.forEach( function(node) { nodes.forEach(function (node) {
node.firstseen = moment.utc(node.firstseen).local(); node.firstseen = moment.utc(node.firstseen).local();
node.lastseen = moment.utc(node.lastseen).local(); node.lastseen = moment.utc(node.lastseen).local();
}); });
@ -54,13 +52,13 @@ function (moment, Router, L, GUI, numeral) {
var graphnodes = {}; var graphnodes = {};
dataNodes.nodes.forEach( function (d) { dataNodes.nodes.forEach(function (d) {
graphnodes[d.nodeinfo.node_id] = d; graphnodes[d.nodeinfo.node_id] = d;
}); });
var graph = dataGraph.batadv; var graph = dataGraph.batadv;
graph.nodes.forEach( function (d) { graph.nodes.forEach(function (d) {
if (d.node_id in graphnodes) { if (d.node_id in graphnodes) {
d.node = graphnodes[d.node_id]; d.node = graphnodes[d.node_id];
if (d.unseen) { if (d.unseen) {
@ -70,36 +68,37 @@ function (moment, Router, L, GUI, numeral) {
} }
}); });
graph.links.forEach( function (d) { graph.links.forEach(function (d) {
d.source = graph.nodes[d.source]; d.source = graph.nodes[d.source];
if (graph.nodes[d.target].node) if (graph.nodes[d.target].node) {
d.target = graph.nodes[d.target]; d.target = graph.nodes[d.target];
else } else {
d.target = undefined; d.target = undefined;
}
}); });
var links = graph.links.filter( function (d) { var links = graph.links.filter(function (d) {
return d.target !== undefined; return d.target !== undefined;
}); });
links.forEach( function (d) { links.forEach(function (d) {
var unknown = (d.source.node === undefined); var unknown = (d.source.node === undefined);
var ids; var ids;
if (unknown) if (unknown) {
ids = [d.source.id.replace(/:/g, ""), d.target.node.nodeinfo.node_id]; ids = [d.source.id.replace(/:/g, ""), d.target.node.nodeinfo.node_id];
else } else {
ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id]; ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id];
}
d.id = ids.join("-"); d.id = ids.join("-");
if (unknown || if (unknown || !d.source.node.nodeinfo.location || !d.target.node.nodeinfo.location ||
!d.source.node.nodeinfo.location ||
!d.target.node.nodeinfo.location ||
isNaN(d.source.node.nodeinfo.location.latitude) || isNaN(d.source.node.nodeinfo.location.latitude) ||
isNaN(d.source.node.nodeinfo.location.longitude) || isNaN(d.source.node.nodeinfo.location.longitude) ||
isNaN(d.target.node.nodeinfo.location.latitude) || isNaN(d.target.node.nodeinfo.location.latitude) ||
isNaN(d.target.node.nodeinfo.location.longitude)) isNaN(d.target.node.nodeinfo.location.longitude)) {
return; return;
}
d.latlngs = []; d.latlngs = [];
d.latlngs.push(L.latLng(d.source.node.nodeinfo.location.latitude, d.source.node.nodeinfo.location.longitude)); d.latlngs.push(L.latLng(d.source.node.nodeinfo.location.latitude, d.source.node.nodeinfo.location.longitude));
@ -108,38 +107,41 @@ function (moment, Router, L, GUI, numeral) {
d.distance = d.latlngs[0].distanceTo(d.latlngs[1]); d.distance = d.latlngs[0].distanceTo(d.latlngs[1]);
}); });
nodes.forEach( function (d) { nodes.forEach(function (d) {
d.neighbours = []; d.neighbours = [];
}); });
links.forEach( function (d) { links.forEach(function (d) {
if (d.type === "tunnel" || d.type === "fastd") if (d.type === "tunnel" || d.type === "fastd") {
d.type = "fastd"; d.type = "fastd";
else if (d.type === "l2tp") { } else if (d.type === "l2tp") {
d.type = "L2TP"; d.type = "L2TP";
d.target.node.flags.uplink = true; d.target.node.flags.uplink = true;
} else if (d.type === "wireless") } else if (d.type === "wireless") {
d.type = "Wifi"; d.type = "Wifi";
else if (d.type === "other") } else if (d.type === "other") {
d.type = "Kabel"; d.type = "Kabel";
else } else {
d.type = "N/A"; d.type = "N/A";
}
var unknown = (d.source.node === undefined); var unknown = (d.source.node === undefined);
if (unknown) { if (unknown) {
d.target.node.neighbours.push({ id: d.source.id, link: d, incoming: true }); d.target.node.neighbours.push({id: d.source.id, link: d, incoming: true});
return; return;
} }
d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false }); d.source.node.neighbours.push({node: d.target.node, link: d, incoming: false});
d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true }); d.target.node.neighbours.push({node: d.source.node, link: d, incoming: true});
if (d.type !== "fastd" && d.type !== "L2TP") if (d.type !== "fastd" && d.type !== "L2TP") {
d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1; d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1;
}
}); });
links.sort( function (a, b) { links.sort(function (a, b) {
return b.tq - a.tq; return b.tq - a.tq;
}); });
return { now: now, return {
now: now,
timestamp: moment.utc(dataNodes.timestamp).local(), timestamp: moment.utc(dataNodes.timestamp).local(),
nodes: { nodes: {
all: nodes, all: nodes,
@ -160,8 +162,9 @@ function (moment, Router, L, GUI, numeral) {
var urls = []; var urls = [];
if (typeof config.dataPath === "string" || config.dataPath instanceof String) if (typeof config.dataPath === "string" || config.dataPath instanceof String) {
config.dataPath = [config.dataPath]; config.dataPath = [config.dataPath];
}
for (var i in config.dataPath) { for (var i in config.dataPath) {
urls.push(config.dataPath[i] + "nodes.json"); urls.push(config.dataPath[i] + "nodes.json");
@ -192,4 +195,4 @@ function (moment, Router, L, GUI, numeral) {
console.log(e); console.log(e);
}); });
}; };
}); });

View File

@ -2,7 +2,8 @@ define(["map/clientlayer", "map/labelslayer",
"d3", "leaflet", "moment", "locationmarker", "rbush", "d3", "leaflet", "moment", "locationmarker", "rbush",
"leaflet.label", "leaflet.providers"], "leaflet.label", "leaflet.providers"],
function (ClientLayer, LabelsLayer, d3, L, moment, LocationMarker, rbush) { function (ClientLayer, LabelsLayer, d3, L, moment, LocationMarker, rbush) {
var options = { worldCopyJump: true, var options = {
worldCopyJump: true,
zoomControl: false zoomControl: false
}; };
@ -56,11 +57,11 @@ define(["map/clientlayer", "map/labelslayer",
return button; return button;
}, },
update: function() { update: function () {
this.button.classList.toggle("active", this.active); this.button.classList.toggle("active", this.active);
}, },
set: function(v) { set: function (v) {
this.active = v; this.active = v;
this.update(); this.update();
}, },
@ -96,11 +97,11 @@ define(["map/clientlayer", "map/labelslayer",
return button; return button;
}, },
update: function() { update: function () {
this.button.classList.toggle("active", this.active); this.button.classList.toggle("active", this.active);
}, },
set: function(v) { set: function (v) {
this.active = v; this.active = v;
this.update(); this.update();
}, },
@ -130,12 +131,13 @@ define(["map/clientlayer", "map/labelslayer",
} }
function addLinksToMap(dict, linkScale, graph, router) { function addLinksToMap(dict, linkScale, graph, router) {
graph = graph.filter( function (d) { graph = graph.filter(function (d) {
return "distance" in d && d.type !== "VPN"; return "distance" in d && d.type !== "VPN";
}); });
var lines = graph.map( function (d) { var lines = graph.map(function (d) {
var opts = { color: d.type === "Kabel" ? "#50B0F0" : linkScale(d.tq).hex(), var opts = {
color: d.type === "Kabel" ? "#50B0F0" : linkScale(d.tq).hex(),
weight: 4, weight: 4,
opacity: 0.5, opacity: 0.5,
dashArray: "none" dashArray: "none"
@ -158,11 +160,11 @@ define(["map/clientlayer", "map/labelslayer",
return lines; return lines;
} }
var iconOnline = { color: "#1566A9", fillColor: "#1566A9", radius: 6, fillOpacity: 0.5, opacity: 0.5, weight: 2, className: "stroke-first" }; var iconOnline = {color: "#1566A9", fillColor: "#1566A9", radius: 6, fillOpacity: 0.5, opacity: 0.5, weight: 2, className: "stroke-first"};
var iconOffline = { color: "#D43E2A", fillColor: "#D43E2A", radius: 3, fillOpacity: 0.5, opacity: 0.5, weight: 1, className: "stroke-first" }; var iconOffline = {color: "#D43E2A", fillColor: "#D43E2A", radius: 3, fillOpacity: 0.5, opacity: 0.5, weight: 1, className: "stroke-first"};
var iconLost = { color: "#D43E2A", fillColor: "#D43E2A", radius: 6, fillOpacity: 0.8, opacity: 0.8, weight: 1, className: "stroke-first" }; var iconLost = {color: "#D43E2A", fillColor: "#D43E2A", radius: 6, fillOpacity: 0.8, opacity: 0.8, weight: 1, className: "stroke-first"};
var iconAlert = { color: "#D43E2A", fillColor: "#D43E2A", radius: 6, fillOpacity: 0.8, opacity: 0.8, weight: 2, className: "stroke-first node-alert" }; var iconAlert = {color: "#D43E2A", fillColor: "#D43E2A", radius: 6, fillOpacity: 0.8, opacity: 0.8, weight: 2, className: "stroke-first node-alert"};
var iconNew = { color: "#1566A9", fillColor: "#93E929", radius: 6, fillOpacity: 1.0, opacity: 0.5, weight: 2 }; var iconNew = {color: "#1566A9", fillColor: "#93E929", radius: 6, fillOpacity: 1.0, opacity: 0.5, weight: 2};
return function (config, linkScale, sidebar, router, buttons) { return function (config, linkScale, sidebar, router, buttons) {
var self = this; var self = this;
@ -176,10 +178,11 @@ define(["map/clientlayer", "map/labelslayer",
var baseLayers = {}; var baseLayers = {};
var locateUserButton = new LocateButton(function (d) { var locateUserButton = new LocateButton(function (d) {
if (d) if (d) {
enableTracking(); enableTracking();
else } else {
disableTracking(); disableTracking();
}
}); });
var mybuttons = []; var mybuttons = [];
@ -191,25 +194,29 @@ define(["map/clientlayer", "map/labelslayer",
} }
function clearButtons() { function clearButtons() {
mybuttons.forEach( function (d) { mybuttons.forEach(function (d) {
buttons.removeChild(d); buttons.removeChild(d);
}); });
} }
var showCoordsPickerButton = new CoordsPickerButton(function (d) { var showCoordsPickerButton = new CoordsPickerButton(function (d) {
if (d) if (d) {
enableCoords(); enableCoords();
else } else {
disableCoords(); disableCoords();
}
}); });
function saveView() { function saveView() {
savedView = {center: map.getCenter(), savedView = {
zoom: map.getZoom()}; center: map.getCenter(),
zoom: map.getZoom()
};
} }
function enableTracking() { function enableTracking() {
map.locate({watch: true, map.locate({
watch: true,
enableHighAccuracy: true, enableHighAccuracy: true,
setView: true setView: true
}); });
@ -241,8 +248,9 @@ define(["map/clientlayer", "map/labelslayer",
} }
function locationFound(e) { function locationFound(e) {
if (!userLocation) if (!userLocation) {
userLocation = new LocationMarker(e.latlng).addTo(map); userLocation = new LocationMarker(e.latlng).addTo(map);
}
userLocation.setLatLng(e.latlng); userLocation.setLatLng(e.latlng);
userLocation.setAccuracy(e.accuracy); userLocation.setAccuracy(e.accuracy);
@ -256,19 +264,22 @@ define(["map/clientlayer", "map/labelslayer",
} }
function addLayer(layerName) { function addLayer(layerName) {
if (layerName in baseLayers) if (layerName in baseLayers) {
return; return;
}
if (layerName in customLayers) if (layerName in customLayers) {
return; return;
}
try { try {
var layer = L.tileLayer.provider(layerName); var layer = L.tileLayer.provider(layerName);
layerControl.addBaseLayer(layer, layerName); layerControl.addBaseLayer(layer, layerName);
customLayers[layerName] = layer; customLayers[layerName] = layer;
if (localStorageTest()) if (localStorageTest()) {
localStorage.setItem("map/customLayers", JSON.stringify(Object.keys(customLayers))); localStorage.setItem("map/customLayers", JSON.stringify(Object.keys(customLayers)));
}
} catch (e) { } catch (e) {
console.log(e); console.log(e);
} }
@ -283,7 +294,7 @@ define(["map/clientlayer", "map/labelslayer",
map = L.map(el, options); map = L.map(el, options);
var layers = config.mapLayers.map( function (d) { var layers = config.mapLayers.map(function (d) {
return { return {
"name": d.name, "name": d.name,
"layer": "url" in d ? L.tileLayer(d.url, d.config) : L.tileLayer.provider(d.name) "layer": "url" in d ? L.tileLayer(d.url, d.config) : L.tileLayer.provider(d.name)
@ -292,7 +303,7 @@ define(["map/clientlayer", "map/labelslayer",
layers[0].layer.addTo(map); layers[0].layer.addTo(map);
layers.forEach( function (d) { layers.forEach(function (d) {
baseLayers[d.name] = d.layer; baseLayers[d.name] = d.layer;
}); });
@ -316,8 +327,9 @@ define(["map/clientlayer", "map/labelslayer",
if (localStorageTest()) { if (localStorageTest()) {
var d = JSON.parse(localStorage.getItem("map/customLayers")); var d = JSON.parse(localStorage.getItem("map/customLayers"));
if (d) if (d) {
d.forEach(addLayer); d.forEach(addLayer);
}
d = JSON.parse(localStorage.getItem("map/selectedLayer")); d = JSON.parse(localStorage.getItem("map/selectedLayer"));
d = d && d.name in baseLayers ? baseLayers[d.name] : d && d.name in customLayers ? customLayers[d.name] : false; d = d && d.name in baseLayers ? baseLayers[d.name] : d && d.name in customLayers ? customLayers[d.name] : false;
@ -336,13 +348,16 @@ define(["map/clientlayer", "map/labelslayer",
labelsLayer.addTo(map); labelsLayer.addTo(map);
labelsLayer.setZIndex(6); labelsLayer.setZIndex(6);
map.on("baselayerchange", function(e) { map.on("baselayerchange", function (e) {
map.options.maxZoom = e.layer.options.maxZoom; map.options.maxZoom = e.layer.options.maxZoom;
clientLayer.options.maxZoom = map.options.maxZoom; clientLayer.options.maxZoom = map.options.maxZoom;
labelsLayer.options.maxZoom = map.options.maxZoom; labelsLayer.options.maxZoom = map.options.maxZoom;
if (map.getZoom() > map.options.maxZoom) map.setZoom(map.options.maxZoom); if (map.getZoom() > map.options.maxZoom) {
if (localStorageTest()) map.setZoom(map.options.maxZoom);
}
if (localStorageTest()) {
localStorage.setItem("map/selectedLayer", JSON.stringify({name: e.name})); localStorage.setItem("map/selectedLayer", JSON.stringify({name: e.name}));
}
}); });
var nodeDict = {}; var nodeDict = {};
@ -350,11 +365,11 @@ define(["map/clientlayer", "map/labelslayer",
var highlight; var highlight;
function resetMarkerStyles(nodes, links) { function resetMarkerStyles(nodes, links) {
Object.keys(nodes).forEach( function (d) { Object.keys(nodes).forEach(function (d) {
nodes[d].resetStyle(); nodes[d].resetStyle();
}); });
Object.keys(links).forEach( function (d) { Object.keys(links).forEach(function (d) {
links[d].resetStyle(); links[d].resetStyle();
}); });
} }
@ -364,17 +379,19 @@ define(["map/clientlayer", "map/labelslayer",
} }
function resetZoom() { function resetZoom() {
if (barycenter) if (barycenter) {
setView(barycenter.getBounds()); setView(barycenter.getBounds());
} }
}
function goto(m) { function goto(m) {
var bounds; var bounds;
if ("getBounds" in m) if ("getBounds" in m) {
bounds = m.getBounds(); bounds = m.getBounds();
else } else {
bounds = L.latLngBounds([m.getLatLng()]); bounds = L.latLngBounds([m.getLatLng()]);
}
setView(bounds); setView(bounds);
@ -385,45 +402,59 @@ define(["map/clientlayer", "map/labelslayer",
resetMarkerStyles(nodeDict, linkDict); resetMarkerStyles(nodeDict, linkDict);
var m; var m;
if (highlight !== undefined) if (highlight !== undefined) {
if (highlight.type === "node") { if (highlight.type === "node") {
m = nodeDict[highlight.o.nodeinfo.node_id]; m = nodeDict[highlight.o.nodeinfo.node_id];
if (m) if (m) {
m.setStyle({ color: "orange", weight: 20, fillOpacity: 1, opacity: 0.7, className: "stroke-first" }); m.setStyle({color: "orange", weight: 20, fillOpacity: 1, opacity: 0.7, className: "stroke-first"});
}
} else if (highlight.type === "link") { } else if (highlight.type === "link") {
m = linkDict[highlight.o.id]; m = linkDict[highlight.o.id];
if (m) if (m) {
m.setStyle({ weight: 7, opacity: 1, dashArray: "10, 10" }); m.setStyle({weight: 7, opacity: 1, dashArray: "10, 10"});
}
}
} }
if (!nopanzoom) if (!nopanzoom) {
if (m) if (m) {
goto(m); goto(m);
else if (savedView) } else if (savedView) {
map.setView(savedView.center, savedView.zoom); map.setView(savedView.center, savedView.zoom);
else } else {
resetZoom(); resetZoom();
} }
}
}
function calcBarycenter(nodes) { function calcBarycenter(nodes) {
nodes = nodes.map(function (d) { return d.nodeinfo.location; }); nodes = nodes.map(function (d) {
return d.nodeinfo.location;
});
if (nodes.length === 0) if (nodes.length === 0) {
return undefined; return undefined;
}
var lats = nodes.map(function (d) { return d.latitude; }); var lats = nodes.map(function (d) {
var lngs = nodes.map(function (d) { return d.longitude; }); return d.latitude;
});
var lngs = nodes.map(function (d) {
return d.longitude;
});
var barycenter = L.latLng(d3.median(lats), d3.median(lngs)); var barycenter = L.latLng(d3.median(lats), d3.median(lngs));
var barycenterDev = [d3.deviation(lats), d3.deviation(lngs)]; var barycenterDev = [d3.deviation(lats), d3.deviation(lngs)];
if (barycenterDev[0] === undefined) if (barycenterDev[0] === undefined) {
barycenterDev[0] = 0; barycenterDev[0] = 0;
}
if (barycenterDev[1] === undefined) if (barycenterDev[1] === undefined) {
barycenterDev[1] = 0; barycenterDev[1] = 0;
}
var barycenterCircle = L.latLng(barycenter.lat + barycenterDev[0], var barycenterCircle = L.latLng(barycenter.lat + barycenterDev[0],
barycenter.lng + barycenterDev[1]); barycenter.lng + barycenterDev[1]);
@ -434,7 +465,7 @@ define(["map/clientlayer", "map/labelslayer",
} }
function mapRTree(d) { function mapRTree(d) {
var o = [ d.nodeinfo.location.latitude, d.nodeinfo.location.longitude, var o = [d.nodeinfo.location.latitude, d.nodeinfo.location.longitude,
d.nodeinfo.location.latitude, d.nodeinfo.location.longitude]; d.nodeinfo.location.latitude, d.nodeinfo.location.longitude];
o.node = d; o.node = d;
@ -446,45 +477,58 @@ define(["map/clientlayer", "map/labelslayer",
nodeDict = {}; nodeDict = {};
linkDict = {}; linkDict = {};
if (groupOffline) if (groupOffline) {
groupOffline.clearLayers(); groupOffline.clearLayers();
}
if (groupOnline) if (groupOnline) {
groupOnline.clearLayers(); groupOnline.clearLayers();
}
if (groupNew) if (groupNew) {
groupNew.clearLayers(); groupNew.clearLayers();
}
if (groupLost) if (groupLost) {
groupLost.clearLayers(); groupLost.clearLayers();
}
if (groupLines) if (groupLines) {
groupLines.clearLayers(); groupLines.clearLayers();
}
var lines = addLinksToMap(linkDict, linkScale, data.graph.links, router); var lines = addLinksToMap(linkDict, linkScale, data.graph.links, router);
groupLines = L.featureGroup(lines).addTo(map); groupLines = L.featureGroup(lines).addTo(map);
if (typeof config.fixedCenter === "undefined") if (typeof config.fixedCenter === "undefined") {
barycenter = calcBarycenter(data.nodes.all.filter(has_location)); barycenter = calcBarycenter(data.nodes.all.filter(has_location));
else } else {
barycenter = L.circle(L.latLng(new L.LatLng(config.fixedCenter.lat, config.fixedCenter.lng)), config.fixedCenter.radius * 1000); barycenter = L.circle(L.latLng(new L.LatLng(config.fixedCenter.lat, config.fixedCenter.lng)), config.fixedCenter.radius * 1000);
}
var nodesOnline = subtract(data.nodes.all.filter(online), data.nodes.new); var nodesOnline = subtract(data.nodes.all.filter(online), data.nodes.new);
var nodesOffline = subtract(data.nodes.all.filter(offline), data.nodes.lost); var nodesOffline = subtract(data.nodes.all.filter(offline), data.nodes.lost);
var markersOnline = nodesOnline.filter(has_location) var markersOnline = nodesOnline.filter(has_location)
.map(mkMarker(nodeDict, function () { return iconOnline; }, router)); .map(mkMarker(nodeDict, function () {
return iconOnline;
}, router));
var markersOffline = nodesOffline.filter(has_location) var markersOffline = nodesOffline.filter(has_location)
.map(mkMarker(nodeDict, function () { return iconOffline; }, router)); .map(mkMarker(nodeDict, function () {
return iconOffline;
}, router));
var markersNew = data.nodes.new.filter(has_location) var markersNew = data.nodes.new.filter(has_location)
.map(mkMarker(nodeDict, function () { return iconNew; }, router)); .map(mkMarker(nodeDict, function () {
return iconNew;
}, router));
var markersLost = data.nodes.lost.filter(has_location) var markersLost = data.nodes.lost.filter(has_location)
.map(mkMarker(nodeDict, function (d) { .map(mkMarker(nodeDict, function (d) {
if (d.lastseen.isAfter(moment(data.now).subtract(3, "days"))) if (d.lastseen.isAfter(moment(data.now).subtract(3, "days"))) {
return iconAlert; return iconAlert;
}
return iconLost; return iconLost;
}, router)); }, router));
@ -499,7 +543,8 @@ define(["map/clientlayer", "map/labelslayer",
rtreeOnlineAll.load(data.nodes.all.filter(online).filter(has_location).map(mapRTree)); rtreeOnlineAll.load(data.nodes.all.filter(online).filter(has_location).map(mapRTree));
clientLayer.setData(rtreeOnlineAll); clientLayer.setData(rtreeOnlineAll);
labelsLayer.setData({online: nodesOnline.filter(has_location), labelsLayer.setData({
online: nodesOnline.filter(has_location),
offline: nodesOffline.filter(has_location), offline: nodesOffline.filter(has_location),
new: data.nodes.new.filter(has_location), new: data.nodes.new.filter(has_location),
lost: data.nodes.lost.filter(has_location) lost: data.nodes.lost.filter(has_location)
@ -534,8 +579,9 @@ define(["map/clientlayer", "map/labelslayer",
clearButtons(); clearButtons();
map.remove(); map.remove();
if (el.parentNode) if (el.parentNode) {
el.parentNode.removeChild(el); el.parentNode.removeChild(el);
}
}; };
self.render = function (d) { self.render = function (d) {
@ -545,4 +591,4 @@ define(["map/clientlayer", "map/labelslayer",
return self; return self;
}; };
}); });

View File

@ -21,8 +21,9 @@ define(["leaflet", "jshashes"],
return [br.lat, tl.lng, tl.lat, br.lng]; return [br.lat, tl.lng, tl.lat, br.lng];
} }
if (!this.data) if (!this.data) {
return; return;
}
var tileSize = this.options.tileSize; var tileSize = this.options.tileSize;
var s = tilePoint.multiplyBy(tileSize); var s = tilePoint.multiplyBy(tileSize);
@ -33,8 +34,9 @@ define(["leaflet", "jshashes"],
var nodes = this.data.search(bbox); var nodes = this.data.search(bbox);
if (nodes.length === 0) if (nodes.length === 0) {
return; return;
}
var ctx = canvas.getContext("2d"); var ctx = canvas.getContext("2d");
@ -47,8 +49,9 @@ define(["leaflet", "jshashes"],
var p = map.project([d.node.nodeinfo.location.latitude, d.node.nodeinfo.location.longitude]); var p = map.project([d.node.nodeinfo.location.latitude, d.node.nodeinfo.location.longitude]);
var clients = d.node.statistics.clients; var clients = d.node.statistics.clients;
if (clients === 0) if (clients === 0) {
return; return;
}
p.x -= s.x; p.x -= s.x;
p.y -= s.y; p.y -= s.y;
@ -73,4 +76,4 @@ define(["leaflet", "jshashes"],
ctx.fill(); ctx.fill();
} }
}); });
}); });

View File

@ -30,7 +30,8 @@ define(["leaflet", "rbush"],
function prepareLabel(fillStyle, fontSize, offset, stroke, minZoom) { function prepareLabel(fillStyle, fontSize, offset, stroke, minZoom) {
return function (d) { return function (d) {
var font = fontSize + "px " + fontFamily; var font = fontSize + "px " + fontFamily;
return { position: L.latLng(d.nodeinfo.location.latitude, d.nodeinfo.location.longitude), return {
position: L.latLng(d.nodeinfo.location.latitude, d.nodeinfo.location.longitude),
label: d.nodeinfo.hostname, label: d.nodeinfo.hostname,
offset: offset, offset: offset,
fillStyle: fillStyle, fillStyle: fillStyle,
@ -44,7 +45,7 @@ define(["leaflet", "rbush"],
} }
function calcOffset(offset, loc) { function calcOffset(offset, loc) {
return [ offset * Math.cos(loc[2] * 2 * Math.PI), return [offset * Math.cos(loc[2] * 2 * Math.PI),
-offset * Math.sin(loc[2] * 2 * Math.PI)]; -offset * Math.sin(loc[2] * 2 * Math.PI)];
} }
@ -54,12 +55,14 @@ define(["leaflet", "rbush"],
var width = label.width * margin; var width = label.width * margin;
var height = label.height * margin; var height = label.height * margin;
var dx = { left: 0, var dx = {
left: 0,
right: -width, right: -width,
center: -width / 2 center: -width / 2
}; };
var dy = { top: 0, var dy = {
top: 0,
ideographic: -height, ideographic: -height,
middle: -height / 2 middle: -height / 2
}; };
@ -73,13 +76,15 @@ define(["leaflet", "rbush"],
var c = L.TileLayer.Canvas.extend({ var c = L.TileLayer.Canvas.extend({
onAdd: function (map) { onAdd: function (map) {
L.TileLayer.Canvas.prototype.onAdd.call(this, map); L.TileLayer.Canvas.prototype.onAdd.call(this, map);
if (this.data) if (this.data) {
this.prepareLabels(); this.prepareLabels();
}
}, },
setData: function (d) { setData: function (d) {
this.data = d; this.data = d;
if (this._map) if (this._map) {
this.prepareLabels(); this.prepareLabels();
}
}, },
prepareLabels: function () { prepareLabels: function () {
var d = this.data; var d = this.data;
@ -133,9 +138,10 @@ define(["leaflet", "rbush"],
var rect = labelRect(p, offset, loc, d, minZoom, maxZoom, z); var rect = labelRect(p, offset, loc, d, minZoom, maxZoom, z);
var candidates = trees[z].search(rect); var candidates = trees[z].search(rect);
if (candidates.length > 0) if (candidates.length > 0) {
break; break;
} }
}
return {loc: loc, z: z + 1}; return {loc: loc, z: z + 1};
}).filter(function (d) { }).filter(function (d) {
@ -156,16 +162,20 @@ define(["leaflet", "rbush"],
} }
return d; return d;
} else } else {
return undefined; return undefined;
}).filter(function (d) { return d !== undefined; }); }
}).filter(function (d) {
return d !== undefined;
});
this.margin = 16; this.margin = 16;
if (labels.length > 0) if (labels.length > 0) {
this.margin += labels.map(function (d) { this.margin += labels.map(function (d) {
return d.width; return d.width;
}).sort().reverse()[0]; }).sort().reverse()[0];
}
this.labels = rbush(9); this.labels = rbush(9);
this.labels.load(labels.map(mapRTree)); this.labels.load(labels.map(mapRTree));
@ -180,8 +190,9 @@ define(["leaflet", "rbush"],
return [br.lat, tl.lng, tl.lat, br.lng]; return [br.lat, tl.lng, tl.lat, br.lng];
} }
if (!this.labels) if (!this.labels) {
return; return;
}
var tileSize = this.options.tileSize; var tileSize = this.options.tileSize;
var s = tilePoint.multiplyBy(tileSize); var s = tilePoint.multiplyBy(tileSize);
@ -212,8 +223,9 @@ define(["leaflet", "rbush"],
ctx.textBaseline = d.label.anchor[1]; ctx.textBaseline = d.label.anchor[1];
ctx.fillStyle = d.label.fillStyle; ctx.fillStyle = d.label.fillStyle;
if (d.label.stroke) if (d.label.stroke) {
ctx.strokeText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]); ctx.strokeText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]);
}
ctx.fillText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]); ctx.fillText(d.label.label, d.p.x + d.label.offset[0], d.p.y + d.label.offset[1]);
} }
@ -225,4 +237,4 @@ define(["leaflet", "rbush"],
}); });
return c; return c;
}); });

View File

@ -8,18 +8,22 @@ define(function () {
var totalOnlineNodes = sum(d.nodes.all.filter(online).map(one)); var totalOnlineNodes = sum(d.nodes.all.filter(online).map(one));
var totalNewNodes = sum(d.nodes.new.map(one)); var totalNewNodes = sum(d.nodes.new.map(one));
var totalLostNodes = sum(d.nodes.lost.map(one)); var totalLostNodes = sum(d.nodes.lost.map(one));
var totalClients = sum(d.nodes.all.filter(online).map( function (d) { var totalClients = sum(d.nodes.all.filter(online).map(function (d) {
return d.statistics.clients ? d.statistics.clients : 0; return d.statistics.clients ? d.statistics.clients : 0;
})); }));
var totalGateways = sum(d.nodes.all.filter(online).filter( function (d) { var totalGateways = sum(d.nodes.all.filter(online).filter(function (d) {
return d.flags.gateway; return d.flags.gateway;
}).map(one)); }).map(one));
var nodetext = [{ count: totalOnlineNodes, label: "online" }, var nodetext = [{count: totalOnlineNodes, label: "online"},
{ count: totalNewNodes, label: "neu" }, {count: totalNewNodes, label: "neu"},
{ count: totalLostNodes, label: "verschwunden" } {count: totalLostNodes, label: "verschwunden"}
].filter( function (d) { return d.count > 0; } ) ].filter(function (d) {
.map( function (d) { return [d.count, d.label].join(" "); } ) return d.count > 0;
})
.map(function (d) {
return [d.count, d.label].join(" ");
})
.join(", "); .join(", ");
stats.textContent = totalNodes + " Knoten " + stats.textContent = totalNodes + " Knoten " +

View File

@ -1,43 +1,50 @@
define(["sorttable", "virtual-dom", "numeral"], function (SortTable, V, numeral) { define(["sorttable", "virtual-dom", "numeral"], function (SortTable, V, numeral) {
function getUptime(now, d) { function getUptime(now, d) {
if (d.flags.online && "uptime" in d.statistics) if (d.flags.online && "uptime" in d.statistics) {
return Math.round(d.statistics.uptime); return Math.round(d.statistics.uptime);
else if (!d.flags.online && "lastseen" in d) } else if (!d.flags.online && "lastseen" in d) {
return Math.round(-(now.unix() - d.lastseen.unix())); return Math.round(-(now.unix() - d.lastseen.unix()));
} }
}
function showUptime(uptime) { function showUptime(uptime) {
var s = ""; var s = "";
uptime /= 3600; uptime /= 3600;
if (uptime !== undefined) if (uptime !== undefined) {
if (Math.abs(uptime) >= 24) if (Math.abs(uptime) >= 24) {
s = Math.round(uptime / 24) + "d"; s = Math.round(uptime / 24) + "d";
else } else {
s = Math.round(uptime) + "h"; s = Math.round(uptime) + "h";
}
}
return s; return s;
} }
var headings = [{ name: "Knoten", var headings = [{
name: "Knoten",
sort: function (a, b) { sort: function (a, b) {
return a.nodeinfo.hostname.localeCompare(b.nodeinfo.hostname); return a.nodeinfo.hostname.localeCompare(b.nodeinfo.hostname);
}, },
reverse: false reverse: false
}, },
{ name: "Uptime", {
name: "Uptime",
sort: function (a, b) { sort: function (a, b) {
return a.uptime - b.uptime; return a.uptime - b.uptime;
}, },
reverse: true reverse: true
}, },
{ name: "#Links", {
name: "#Links",
sort: function (a, b) { sort: function (a, b) {
return a.meshlinks - b.meshlinks; return a.meshlinks - b.meshlinks;
}, },
reverse: true reverse: true
}, },
{ name: "Clients", {
name: "Clients",
sort: function (a, b) { sort: function (a, b) {
return ("clients" in a.statistics ? a.statistics.clients : -1) - return ("clients" in a.statistics ? a.statistics.clients : -1) -
("clients" in b.statistics ? b.statistics.clients : -1); ("clients" in b.statistics ? b.statistics.clients : -1);
@ -45,18 +52,20 @@ define(["sorttable", "virtual-dom", "numeral"], function (SortTable, V, numeral)
reverse: true reverse: true
}]; }];
return function(router) { return function (router) {
function renderRow(d) { function renderRow(d) {
var td1Content = []; var td1Content = [];
var aClass = ["hostname", d.flags.online ? "online" : "offline"]; var aClass = ["hostname", d.flags.online ? "online" : "offline"];
td1Content.push(V.h("a", { className: aClass.join(" "), td1Content.push(V.h("a", {
className: aClass.join(" "),
onclick: router.node(d), onclick: router.node(d),
href: "#" href: "#"
}, d.nodeinfo.hostname)); }, d.nodeinfo.hostname));
if (has_location(d)) if (has_location(d)) {
td1Content.push(V.h("span", {className: "icon ion-location"})); td1Content.push(V.h("span", {className: "icon ion-location"}));
}
var td1 = V.h("td", td1Content); var td1 = V.h("td", td1Content);
var td2 = V.h("td", showUptime(d.uptime)); var td2 = V.h("td", showUptime(d.uptime));

View File

@ -1,4 +1,4 @@
define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "vercomp" ], define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "vercomp"],
function (Chroma, V, numeral, Filter, vercomp) { function (Chroma, V, numeral, Filter, vercomp) {
return function (config, filterManager) { return function (config, filterManager) {
@ -39,40 +39,47 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc
function count(nodes, key, f) { function count(nodes, key, f) {
var dict = {}; var dict = {};
nodes.forEach( function (d) { nodes.forEach(function (d) {
var v = dictGet(d, key.slice(0)); var v = dictGet(d, key.slice(0));
if (f !== undefined) if (f !== undefined) {
v = f(v); v = f(v);
}
if (v === null) if (v === null) {
return; return;
}
dict[v] = 1 + (v in dict ? dict[v] : 0); dict[v] = 1 + (v in dict ? dict[v] : 0);
}); });
return Object.keys(dict).map(function (d) { return [d, dict[d], key, f]; }); return Object.keys(dict).map(function (d) {
return [d, dict[d], key, f];
});
} }
function countClients(nodes, key, f) { function countClients(nodes, key, f) {
var dict = {}; var dict = {};
nodes.forEach( function (d) { nodes.forEach(function (d) {
var v = dictGet(d, key.slice(0)); var v = dictGet(d, key.slice(0));
if (f !== undefined) if (f !== undefined) {
v = f(v); v = f(v);
}
if (v === null) if (v === null) {
return; return;
}
dict[v] = d.statistics.clients + (v in dict ? dict[v] : 0); dict[v] = d.statistics.clients + (v in dict ? dict[v] : 0);
}); });
return Object.keys(dict).map(function (d) { return [d, dict[d], key, f]; }); return Object.keys(dict).map(function (d) {
return [d, dict[d], key, f];
});
} }
function addFilter(filter) { function addFilter(filter) {
return function () { return function () {
filterManager.addFilter(filter); filterManager.addFilter(filter);
@ -82,13 +89,15 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc
} }
function fillTable(name, table, data) { function fillTable(name, table, data) {
if (!table.last) if (!table.last) {
table.last = V.h("table"); table.last = V.h("table");
}
var max = 0; var max = 0;
data.forEach(function (d) { data.forEach(function (d) {
if (d[1] > max) if (d[1] > max) {
max = d[1]; max = d[1];
}
}); });
var items = data.map(function (d) { var items = data.map(function (d) {
@ -98,14 +107,16 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc
var filter = new Filter(name, d[2], d[0], d[3]); var filter = new Filter(name, d[2], d[0], d[3]);
var a = V.h("a", { href: "#", onclick: addFilter(filter) }, d[0]); var a = V.h("a", {href: "#", onclick: addFilter(filter)}, d[0]);
var th = V.h("th", a); var th = V.h("th", a);
var td = V.h("td", V.h("span", {style: { var td = V.h("td", V.h("span", {
style: {
width: Math.round(v * 100) + "%", width: Math.round(v * 100) + "%",
backgroundColor: scale(v).hex(), backgroundColor: scale(v).hex(),
color: c1 > c2 ? "white" : "black" color: c1 > c2 ? "white" : "black"
}}, numeral(d[1]).format("0,0"))); }
}, numeral(d[1]).format("0,0")));
return V.h("tr", [th, td]); return V.h("tr", [th, td]);
}); });
@ -134,12 +145,13 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc
}); });
var autoDict = count(nodes, ["nodeinfo", "software", "autoupdater"], function (d) { var autoDict = count(nodes, ["nodeinfo", "software", "autoupdater"], function (d) {
if (d === null) if (d === null) {
return null; return null;
else if (d.enabled) } else if (d.enabled) {
return d.branch; return d.branch;
else } else {
return "(deaktiviert)"; return "(deaktiviert)";
}
}); });
var uplinkDict = count(nodes, ["flags", "uplink"], function (d) { var uplinkDict = count(nodes, ["flags", "uplink"], function (d) {
@ -147,47 +159,70 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc
}); });
var gwNodesDict = count(onlineNodes, ["statistics", "gateway"], function (d) { var gwNodesDict = count(onlineNodes, ["statistics", "gateway"], function (d) {
if (d === null) if (d === null) {
return null; return null;
}
if (d in nodeDict) if (d in nodeDict) {
return nodeDict[d].nodeinfo.hostname; return nodeDict[d].nodeinfo.hostname;
}
return d; return d;
}); });
var gwClientsDict = countClients(onlineNodes, ["statistics", "gateway"], function (d) { var gwClientsDict = countClients(onlineNodes, ["statistics", "gateway"], function (d) {
if (d === null) if (d === null) {
return null; return null;
}
if (d in nodeDict) if (d in nodeDict) {
return nodeDict[d].nodeinfo.hostname; return nodeDict[d].nodeinfo.hostname;
}
return d; return d;
}); });
var siteDict = count(nodes, ["nodeinfo", "system", "site_code"], function (d) { var siteDict = count(nodes, ["nodeinfo", "system", "site_code"], function (d) {
var rt = d; var rt = d;
if (config.siteNames) if (config.siteNames) {
config.siteNames.forEach( function (t) { config.siteNames.forEach(function (t) {
if(d === t.site) if (d === t.site) {
rt = t.name; rt = t.name;
}
}); });
}
return rt; return rt;
}); });
fillTable("Status", statusTable, statusDict.sort(function (a, b) { return b[1] - a[1]; })); fillTable("Status", statusTable, statusDict.sort(function (a, b) {
fillTable("Firmware", fwTable, fwDict.sort(function (a, b) { return vercomp(b[0], a[0]); })); return b[1] - a[1];
fillTable("Hardware", hwTable, hwDict.sort(function (a, b) { return b[1] - a[1]; })); }));
fillTable("Koordinaten", geoTable, geoDict.sort(function (a, b) { return b[1] - a[1]; })); fillTable("Firmware", fwTable, fwDict.sort(function (a, b) {
fillTable("Uplink", uplinkTable, uplinkDict.sort(function (a, b) { return b[1] - a[1]; })); return vercomp(b[0], a[0]);
fillTable("Autom. Updates", autoTable, autoDict.sort(function (a, b) { return b[1] - a[1]; })); }));
fillTable("Nodes an Gateway", gwNodesTable, gwNodesDict.sort(function (a, b) { return b[1] - a[1]; })); fillTable("Hardware", hwTable, hwDict.sort(function (a, b) {
fillTable("Clients an Gateway", gwClientsTable, gwClientsDict.sort(function (a, b) { return b[1] - a[1]; })); return b[1] - a[1];
fillTable("Site", siteTable, siteDict.sort(function (a, b) { return b[1] - a[1]; })); }));
fillTable("Koordinaten", geoTable, geoDict.sort(function (a, b) {
return b[1] - a[1];
}));
fillTable("Uplink", uplinkTable, uplinkDict.sort(function (a, b) {
return b[1] - a[1];
}));
fillTable("Autom. Updates", autoTable, autoDict.sort(function (a, b) {
return b[1] - a[1];
}));
fillTable("Nodes an Gateway", gwNodesTable, gwNodesDict.sort(function (a, b) {
return b[1] - a[1];
}));
fillTable("Clients an Gateway", gwClientsTable, gwClientsDict.sort(function (a, b) {
return b[1] - a[1];
}));
fillTable("Site", siteTable, siteDict.sort(function (a, b) {
return b[1] - a[1];
}));
}; };
self.render = function (el) { self.render = function (el) {
var h2; var h2;
self.renderSingle(el, "Status", statusTable); self.renderSingle(el, "Status", statusTable);
@ -200,13 +235,14 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc
self.renderSingle(el, "Autoupdater", autoTable); self.renderSingle(el, "Autoupdater", autoTable);
self.renderSingle(el, "Site", siteTable); self.renderSingle(el, "Site", siteTable);
if (config.globalInfos) if (config.globalInfos) {
config.globalInfos.forEach(function (globalInfo) { config.globalInfos.forEach(function (globalInfo) {
h2 = document.createElement("h2"); h2 = document.createElement("h2");
h2.textContent = globalInfo.name; h2.textContent = globalInfo.name;
el.appendChild(h2); el.appendChild(h2);
el.appendChild(showStatGlobal(globalInfo)); el.appendChild(showStatGlobal(globalInfo));
}); });
}
}; };
self.renderSingle = function (el, heading, table) { self.renderSingle = function (el, heading, table) {
@ -221,4 +257,4 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc
}; };
return self; return self;
}; };
}); });

View File

@ -1,7 +1,7 @@
define(function () { define(function () {
return function () { return function () {
var self = this; var self = this;
var objects = { nodes: {}, links: {} }; var objects = {nodes: {}, links: {}};
var targets = []; var targets = [];
var views = {}; var views = {};
var currentView; var currentView;
@ -11,16 +11,19 @@ define(function () {
function saveState() { function saveState() {
var e = []; var e = [];
if (currentView) if (currentView) {
e.push("v:" + currentView); e.push("v:" + currentView);
}
if (currentObject) { if (currentObject) {
if ("node" in currentObject) if ("node" in currentObject) {
e.push("n:" + encodeURIComponent(currentObject.node.nodeinfo.node_id)); e.push("n:" + encodeURIComponent(currentObject.node.nodeinfo.node_id));
}
if ("link" in currentObject) if ("link" in currentObject) {
e.push("l:" + encodeURIComponent(currentObject.link.id)); e.push("l:" + encodeURIComponent(currentObject.link.id));
} }
}
var s = "#!" + e.join(";"); var s = "#!" + e.join(";");
@ -30,7 +33,7 @@ define(function () {
function resetView(push) { function resetView(push) {
push = trueDefault(push); push = trueDefault(push);
targets.forEach( function (t) { targets.forEach(function (t) {
t.resetView(); t.resetView();
}); });
@ -41,10 +44,11 @@ define(function () {
} }
function gotoNode(d) { function gotoNode(d) {
if (!d) if (!d) {
return false; return false;
}
targets.forEach( function (t) { targets.forEach(function (t) {
t.gotoNode(d); t.gotoNode(d);
}); });
@ -52,10 +56,11 @@ define(function () {
} }
function gotoLink(d) { function gotoLink(d) {
if (!d) if (!d) {
return false; return false;
}
targets.forEach( function (t) { targets.forEach(function (t) {
t.gotoLink(d); t.gotoLink(d);
}); });
@ -63,11 +68,14 @@ define(function () {
} }
function gotoLocation(d) { function gotoLocation(d) {
if (!d) if (!d) {
return false; return false;
}
targets.forEach( function (t) { targets.forEach(function (t) {
if(!t.gotoLocation)console.warn("has no gotoLocation", t); if (!t.gotoLocation) {
console.warn("has no gotoLocation", t);
}
t.gotoLocation(d); t.gotoLocation(d);
}); });
@ -75,13 +83,15 @@ define(function () {
} }
function loadState(s) { function loadState(s) {
if (!s) if (!s) {
return false; return false;
}
s = decodeURIComponent(s); s = decodeURIComponent(s);
if (!s.startsWith("#!")) if (!s.startsWith("#!")) {
return false; return false;
}
var targetSet = false; var targetSet = false;
@ -98,7 +108,7 @@ define(function () {
if (args[0] === "n") { if (args[0] === "n") {
id = args[1]; id = args[1];
if (id in objects.nodes) { if (id in objects.nodes) {
currentObject = { node: objects.nodes[id] }; currentObject = {node: objects.nodes[id]};
gotoNode(objects.nodes[id]); gotoNode(objects.nodes[id]);
targetSet = true; targetSet = true;
} }
@ -107,7 +117,7 @@ define(function () {
if (args[0] === "l") { if (args[0] === "l") {
id = args[1]; id = args[1];
if (id in objects.links) { if (id in objects.links) {
currentObject = { link: objects.links[id] }; currentObject = {link: objects.links[id]};
gotoLink(objects.links[id]); gotoLink(objects.links[id]);
targetSet = true; targetSet = true;
} }
@ -120,12 +130,14 @@ define(function () {
self.start = function () { self.start = function () {
running = true; running = true;
if (!loadState(window.location.hash)) if (!loadState(window.location.hash)) {
resetView(false); resetView(false);
}
window.onpopstate = function (d) { window.onpopstate = function (d) {
if (!loadState(d.state)) if (!loadState(d.state)) {
resetView(false); resetView(false);
}
}; };
}; };
@ -133,11 +145,13 @@ define(function () {
if (d in views) { if (d in views) {
views[d](); views[d]();
if (!currentView || running) if (!currentView || running) {
currentView = d; currentView = d;
}
if (!running) if (!running) {
return; return;
}
saveState(); saveState();
@ -146,18 +160,20 @@ define(function () {
return; return;
} }
if ("node" in currentObject) if ("node" in currentObject) {
gotoNode(currentObject.node); gotoNode(currentObject.node);
}
if ("link" in currentObject) if ("link" in currentObject) {
gotoLink(currentObject.link); gotoLink(currentObject.link);
} }
}
}; };
self.node = function (d) { self.node = function (d) {
return function () { return function () {
if (gotoNode(d)) { if (gotoNode(d)) {
currentObject = { node: d }; currentObject = {node: d};
saveState(); saveState();
} }
@ -168,7 +184,7 @@ define(function () {
self.link = function (d) { self.link = function (d) {
return function () { return function () {
if (gotoLink(d)) { if (gotoLink(d)) {
currentObject = { link: d }; currentObject = {link: d};
saveState(); saveState();
} }
@ -187,7 +203,7 @@ define(function () {
}; };
self.removeTarget = function (d) { self.removeTarget = function (d) {
targets = targets.filter( function (e) { targets = targets.filter(function (e) {
return d !== e; return d !== e;
}); });
}; };
@ -200,11 +216,11 @@ define(function () {
objects.nodes = {}; objects.nodes = {};
objects.links = {}; objects.links = {};
data.nodes.all.forEach( function (d) { data.nodes.all.forEach(function (d) {
objects.nodes[d.nodeinfo.node_id] = d; objects.nodes[d.nodeinfo.node_id] = d;
}); });
data.graph.links.forEach( function (d) { data.graph.links.forEach(function (d) {
objects.links[d.id] = d; objects.links[d.id] = d;
}); });
}; };

View File

@ -19,8 +19,9 @@ define([], function () {
sidebar.appendChild(container); sidebar.appendChild(container);
self.getWidth = function () { self.getWidth = function () {
if (sidebar.classList.contains("hidden")) if (sidebar.classList.contains("hidden")) {
return 0; return 0;
}
var small = window.matchMedia("(max-width: 630pt)"); var small = window.matchMedia("(max-width: 630pt)");
return small.matches ? 0 : sidebar.offsetWidth; return small.matches ? 0 : sidebar.offsetWidth;

View File

@ -1,5 +1,5 @@
define(["moment", "virtual-dom"], function (moment, V) { define(["moment", "virtual-dom"], function (moment, V) {
return function(nodes, field, router, title) { return function (nodes, field, router, title) {
var self = this; var self = this;
var el, tbody; var el, tbody;
@ -12,8 +12,9 @@ define(["moment", "virtual-dom"], function (moment, V) {
var list = data.nodes[nodes]; var list = data.nodes[nodes];
if (list.length === 0) { if (list.length === 0) {
while (el.firstChild) while (el.firstChild) {
el.removeChild(el.firstChild); el.removeChild(el.firstChild);
}
tbody = null; tbody = null;
@ -33,19 +34,21 @@ define(["moment", "virtual-dom"], function (moment, V) {
table.appendChild(tbody); table.appendChild(tbody);
} }
var items = list.map( function (d) { var items = list.map(function (d) {
var time = moment(d[field]).from(data.now); var time = moment(d[field]).from(data.now);
var td1Content = []; var td1Content = [];
var aClass = ["hostname", d.flags.online ? "online" : "offline"]; var aClass = ["hostname", d.flags.online ? "online" : "offline"];
td1Content.push(V.h("a", { className: aClass.join(" "), td1Content.push(V.h("a", {
className: aClass.join(" "),
onclick: router.node(d), onclick: router.node(d),
href: "#" href: "#"
}, d.nodeinfo.hostname)); }, d.nodeinfo.hostname));
if (has_location(d)) if (has_location(d)) {
td1Content.push(V.h("span", {className: "icon ion-location"})); td1Content.push(V.h("span", {className: "icon ion-location"}));
}
var td1 = V.h("td", td1Content); var td1 = V.h("td", td1Content);
var td2 = V.h("td", time); var td2 = V.h("td", time);

View File

@ -1,5 +1,5 @@
define(["virtual-dom"], function (V) { define(["virtual-dom"], function (V) {
return function(headings, sortIndex, renderRow) { return function (headings, sortIndex, renderRow) {
var data; var data;
var sortReverse = false; var sortReverse = false;
var el = document.createElement("table"); var el = document.createElement("table");
@ -13,7 +13,9 @@ define(["virtual-dom"], function (V) {
} }
function sortTableHandler(i) { function sortTableHandler(i) {
return function () { sortTable(i); }; return function () {
sortTable(i);
};
} }
function updateView() { function updateView() {
@ -21,20 +23,23 @@ define(["virtual-dom"], function (V) {
if (data.length !== 0) { if (data.length !== 0) {
var th = headings.map(function (d, i) { var th = headings.map(function (d, i) {
var properties = { onclick: sortTableHandler(i), var properties = {
onclick: sortTableHandler(i),
className: "sort-header" className: "sort-header"
}; };
if (sortIndex === i) if (sortIndex === i) {
properties.className += sortReverse ? " sort-up" : " sort-down"; properties.className += sortReverse ? " sort-up" : " sort-down";
}
return V.h("th", properties, d.name); return V.h("th", properties, d.name);
}); });
var links = data.slice(0).sort(headings[sortIndex].sort); var links = data.slice(0).sort(headings[sortIndex].sort);
if (headings[sortIndex].reverse ? !sortReverse : sortReverse) if (headings[sortIndex].reverse ? !sortReverse : sortReverse) {
links = links.reverse(); links = links.reverse();
}
children.push(V.h("thead", V.h("tr", th))); children.push(V.h("thead", V.h("tr", th)));
children.push(V.h("tbody", links.map(renderRow))); children.push(V.h("tbody", links.map(renderRow)));

View File

@ -8,11 +8,13 @@ define([], function () {
var container = document.createElement("div"); var container = document.createElement("div");
function gotoTab(li) { function gotoTab(li) {
for (var i = 0; i < tabs.children.length; i++) for (var i = 0; i < tabs.children.length; i++) {
tabs.children[i].classList.remove("visible"); tabs.children[i].classList.remove("visible");
}
while (container.firstChild) while (container.firstChild) {
container.removeChild(container.firstChild); container.removeChild(container.firstChild);
}
li.classList.add("visible"); li.classList.add("visible");
@ -37,14 +39,16 @@ define([], function () {
var anyVisible = false; var anyVisible = false;
for (var i = 0; i < tabs.children.length; i++) for (var i = 0; i < tabs.children.length; i++) {
if (tabs.children[i].classList.contains("visible")) { if (tabs.children[i].classList.contains("visible")) {
anyVisible = true; anyVisible = true;
break; break;
} }
}
if (!anyVisible) if (!anyVisible) {
gotoTab(li); gotoTab(li);
}
}; };
self.render = function (el) { self.render = function (el) {

View File

@ -3,8 +3,9 @@ define(function () {
function setTitle(d) { function setTitle(d) {
var title = [config.siteName]; var title = [config.siteName];
if (d !== undefined) if (d !== undefined) {
title.push(d); title.push(d);
}
document.title = title.join(": "); document.title = title.join(": ");
} }
@ -14,16 +15,18 @@ define(function () {
}; };
this.gotoNode = function (d) { this.gotoNode = function (d) {
if (d) if (d) {
setTitle(d.nodeinfo.hostname); setTitle(d.nodeinfo.hostname);
}
}; };
this.gotoLink = function (d) { this.gotoLink = function (d) {
if (d) if (d) {
setTitle((d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " " + d.target.node.nodeinfo.hostname); setTitle((d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " " + d.target.node.nodeinfo.hostname);
}
}; };
this.gotoLocation = function() { this.gotoLocation = function () {
//ignore //ignore
}; };

View File

@ -1,16 +1,17 @@
define([], function () { define([], function () {
function order(c) { function order(c) {
if (/^\d$/.test(c)) if (/^\d$/.test(c)) {
return 0; return 0;
else if (/^[a-z]$/i.test(c)) } else if (/^[a-z]$/i.test(c)) {
return c.charCodeAt(0); return c.charCodeAt(0);
else if (c === "~") } else if (c === "~") {
return -1; return -1;
else if (c) } else if (c) {
return c.charCodeAt(0) + 256; return c.charCodeAt(0) + 256;
else } else {
return 0; return 0;
} }
}
// Based on dpkg code // Based on dpkg code
function vercomp(a, b) { function vercomp(a, b) {
@ -22,36 +23,43 @@ define([], function () {
var ac = order(a[apos]); var ac = order(a[apos]);
var bc = order(b[bpos]); var bc = order(b[bpos]);
if (ac !== bc) if (ac !== bc) {
return ac - bc; return ac - bc;
}
apos++; apos++;
bpos++; bpos++;
} }
while (a[apos] === "0") while (a[apos] === "0") {
apos++; apos++;
}
while (b[bpos] === "0") while (b[bpos] === "0") {
bpos++; bpos++;
}
while (/^\d$/.test(a[apos]) && /^\d$/.test(b[bpos])) { while (/^\d$/.test(a[apos]) && /^\d$/.test(b[bpos])) {
if (firstDiff === 0) if (firstDiff === 0) {
firstDiff = a.charCodeAt(apos) - b.charCodeAt(bpos); firstDiff = a.charCodeAt(apos) - b.charCodeAt(bpos);
}
apos++; apos++;
bpos++; bpos++;
} }
if (/^\d$/.test(a[apos])) if (/^\d$/.test(a[apos])) {
return 1; return 1;
}
if (/^\d$/.test(b[bpos])) if (/^\d$/.test(b[bpos])) {
return -1; return -1;
}
if (firstDiff !== 0) if (firstDiff !== 0) {
return firstDiff; return firstDiff;
} }
}
return 0; return 0;
} }

View File

@ -1,4 +1,4 @@
module.exports = function(grunt) { module.exports = function (grunt) {
grunt.config.merge({ grunt.config.merge({
bowerdir: "bower_components", bowerdir: "bower_components",
copy: { copy: {
@ -19,13 +19,13 @@ module.exports = function(grunt) {
dest: "build/" dest: "build/"
}, },
vendorjs: { vendorjs: {
src: [ "es6-shim/es6-shim.min.js" ], src: ["es6-shim/es6-shim.min.js"],
expand: true, expand: true,
cwd: "bower_components/", cwd: "bower_components/",
dest: "build/vendor/" dest: "build/vendor/"
}, },
robotoSlab: { robotoSlab: {
src: [ "fonts/*", src: ["fonts/*",
"roboto-slab-fontface.css" "roboto-slab-fontface.css"
], ],
expand: true, expand: true,
@ -33,7 +33,7 @@ module.exports = function(grunt) {
cwd: "bower_components/roboto-slab-fontface" cwd: "bower_components/roboto-slab-fontface"
}, },
roboto: { roboto: {
src: [ "fonts/*", src: ["fonts/*",
"roboto-fontface.css" "roboto-fontface.css"
], ],
expand: true, expand: true,
@ -41,7 +41,7 @@ module.exports = function(grunt) {
cwd: "bower_components/roboto-fontface" cwd: "bower_components/roboto-fontface"
}, },
ionicons: { ionicons: {
src: [ "fonts/*", src: ["fonts/*",
"css/ionicons.min.css" "css/ionicons.min.css"
], ],
expand: true, expand: true,
@ -49,7 +49,7 @@ module.exports = function(grunt) {
cwd: "bower_components/ionicons/" cwd: "bower_components/ionicons/"
}, },
leafletImages: { leafletImages: {
src: [ "images/*" ], src: ["images/*"],
expand: true, expand: true,
dest: "build/", dest: "build/",
cwd: "bower_components/leaflet/dist/" cwd: "bower_components/leaflet/dist/"
@ -82,7 +82,7 @@ module.exports = function(grunt) {
cssmin: { cssmin: {
target: { target: {
files: { files: {
"build/style.css": [ "bower_components/leaflet/dist/leaflet.css", "build/style.css": ["bower_components/leaflet/dist/leaflet.css",
"bower_components/Leaflet.label/dist/leaflet.label.css", "bower_components/Leaflet.label/dist/leaflet.label.css",
"style.css" "style.css"
] ]

View File

@ -14,7 +14,6 @@ module.exports = function (grunt) {
eslint: { eslint: {
options: { options: {
rules: { rules: {
"curly": [2, "multi"],
"strict": [2, "never"], "strict": [2, "never"],
"no-multi-spaces": 0, "no-multi-spaces": 0,
"no-new": 0, "no-new": 0,