diff --git a/lib/filters/hostname.js b/lib/filters/hostname.js
index b311c07..5da75f3 100644
--- a/lib/filters/hostname.js
+++ b/lib/filters/hostname.js
@@ -16,7 +16,7 @@ define(function () {
}
function run(d) {
- return (d.nodeinfo !== undefined ? d.nodeinfo.hostname.toLowerCase().includes(input.value.toLowerCase()) : '');
+ return (d !== undefined ? d.hostname.toLowerCase().includes(input.value.toLowerCase()) : '');
}
function setRefresh(f) {
diff --git a/lib/forcegraph.js b/lib/forcegraph.js
index 2cc5d34..dd49757 100644
--- a/lib/forcegraph.js
+++ b/lib/forcegraph.js
@@ -82,7 +82,7 @@ define(['d3-selection', 'd3-force', 'd3-zoom', 'd3-drag', 'd3-timer', 'd3-ease',
var n = force.find(e[0], e[1], NODE_RADIUS_SELECT);
if (n !== undefined) {
- router.fullUrl({ node: n.o.node.nodeinfo.node_id });
+ router.fullUrl({ node: n.o.node_id });
return;
}
@@ -121,16 +121,16 @@ define(['d3-selection', 'd3-force', 'd3-zoom', 'd3-drag', 'd3-timer', 'd3-ease',
forceLink = d3Force.forceLink()
.distance(function (d) {
- if (d.o.vpn) {
+ if (d.o.type === 'vpn') {
return 0;
}
return 75;
})
.strength(function (d) {
- if (d.o.vpn) {
+ if (d.o.type === 'vpn') {
return 0.02;
}
- return Math.max(0.5, 1 / d.o.tq);
+ return Math.max(0.5, d.o.source_tq);
});
var zoom = d3Zoom.zoom()
@@ -197,13 +197,13 @@ define(['d3-selection', 'd3-force', 'd3-zoom', 'd3-drag', 'd3-timer', 'd3-ease',
});
self.setData = function setData(data) {
- intNodes = data.graph.nodes.map(function (d) {
+ intNodes = data.nodes.all.map(function (d) {
var e;
- if (d.id in dictNodes) {
- e = dictNodes[d.id];
+ if (d.node_id in dictNodes) {
+ e = dictNodes[d.node_id];
} else {
e = {};
- dictNodes[d.id] = e;
+ dictNodes[d.node_id] = e;
}
e.o = d;
@@ -211,12 +211,13 @@ define(['d3-selection', 'd3-force', 'd3-zoom', 'd3-drag', 'd3-timer', 'd3-ease',
return e;
});
- intLinks = data.graph.links.map(function (d) {
+ intLinks = data.links.map(function (d) {
var e = {};
e.o = d;
- e.source = dictNodes[d.source.id];
- e.target = dictNodes[d.target.id];
- e.color = linkScale(1 / d.tq);
+ e.source = dictNodes[d.source.node_id];
+ e.target = dictNodes[d.target.node_id];
+ e.color = linkScale(d.source_tq);
+ e.color_to = linkScale(d.target_tq);
return e;
});
@@ -239,10 +240,10 @@ define(['d3-selection', 'd3-force', 'd3-zoom', 'd3-drag', 'd3-timer', 'd3-ease',
moveTo(function calcToNode() {
for (var i = 0; i < intNodes.length; i++) {
var n = intNodes[i];
- if (n.o.node.nodeinfo.node_id !== d.nodeinfo.node_id) {
+ if (n.o.node_id !== d.node_id) {
continue;
}
- draw.setHighlight({ type: 'node', o: n.o.node });
+ draw.setHighlight({ type: 'node', o: n.o });
return [n.x, n.y, (ZOOM_MAX + 1) / 2];
}
return [0, 0, (ZOOM_MIN + 1) / 2];
diff --git a/lib/forcegraph/draw.js b/lib/forcegraph/draw.js
index 62b0eff..c10c4d1 100644
--- a/lib/forcegraph/draw.js
+++ b/lib/forcegraph/draw.js
@@ -21,13 +21,13 @@ define(['helper'], function (helper) {
function drawDetailNode(d) {
if (transform.k > 1) {
ctx.beginPath();
- helper.positionClients(ctx, d, Math.PI, d.o.node.statistics.clients, 15);
+ helper.positionClients(ctx, d, Math.PI, d.o.clients, 15);
ctx.fillStyle = clientColor;
ctx.fill();
ctx.beginPath();
var name = d.o.node_id;
- if (d.o.node && d.o.node.nodeinfo) {
- name = d.o.node.nodeinfo.hostname;
+ if (d.o) {
+ name = d.o.hostname;
}
ctx.textAlign = 'center';
ctx.fillStyle = labelColor;
@@ -36,7 +36,7 @@ define(['helper'], function (helper) {
}
function drawHighlightNode(d) {
- if (highlight && highlight.type === 'node' && d.o.node === highlight.o) {
+ if (highlight && highlight.type === 'node' && d.o === highlight.o) {
ctx.arc(d.x, d.y, NODE_RADIUS * 1.5, 0, 2 * Math.PI);
ctx.fillStyle = highlightColor;
ctx.fill();
@@ -76,7 +76,7 @@ define(['helper'], function (helper) {
var zero = transform.invert([0, 0]);
var area = transform.invert([width, height]);
if (d.source.x < zero[0] && d.target.x < zero[0] || d.source.y < zero[1] && d.target.y < zero[1] ||
- d.source.x > area[0] && d.target.x > area[0] || d.source.y > area[1] && d.target.y > area[1]) {
+ d.source.x > area[0] && d.target.x > area[0] || d.source.y > area[1] && d.target.y > area[1]) {
return;
}
ctx.beginPath();
@@ -85,9 +85,13 @@ define(['helper'], function (helper) {
to = drawHighlightLink(d, to);
+ var grd = ctx.createLinearGradient(d.source.x, d.source.y, d.target.x, d.target.y);
+ grd.addColorStop(0.45, d.color);
+ grd.addColorStop(0.55, d.color_to);
+
ctx.lineTo(to[0], to[1]);
- ctx.strokeStyle = d.color;
- if (d.o.vpn) {
+ ctx.strokeStyle = grd;
+ if (d.o.type === 'vpn') {
ctx.globalAlpha = 0.2;
ctx.lineWidth = 1.5;
} else {
diff --git a/lib/gui.js b/lib/gui.js
index d001d5f..a8faab2 100644
--- a/lib/gui.js
+++ b/lib/gui.js
@@ -80,7 +80,7 @@ function (d3Interpolate, Map, Sidebar, Tabs, Container, Legend, Linklist,
var title = new Title(config);
var header = new Container('header');
- var infobox = new Infobox(config, sidebar, router);
+ var infobox = new Infobox(config, sidebar, router, linkScale);
var tabs = new Tabs();
var overview = new Container();
var legend = new Legend(config, language);
@@ -94,6 +94,7 @@ function (d3Interpolate, Map, Sidebar, Tabs, Container, Legend, Linklist,
fanoutUnfiltered.add(legend);
fanoutUnfiltered.add(newnodeslist);
fanoutUnfiltered.add(lostnodeslist);
+ fanoutUnfiltered.add(infobox);
fanout.add(nodelist);
fanout.add(linklist);
fanout.add(statistics);
diff --git a/lib/infobox/link.js b/lib/infobox/link.js
index 017e5dc..8457c9c 100644
--- a/lib/infobox/link.js
+++ b/lib/infobox/link.js
@@ -1,53 +1,76 @@
-define(['helper'], function (helper) {
+define(['helper', 'snabbdom'], function (helper, V) {
'use strict';
+ V = V.default;
function showStatImg(o, d, time) {
var subst = {};
subst['{SOURCE_ID}'] = d.source.node_id;
- subst['{SOURCE_NAME}'] = d.source.node.nodeinfo.hostname.replace(/[^a-z0-9\-]/ig, '_');
+ subst['{SOURCE_NAME}'] = d.source.hostname.replace(/[^a-z0-9\-]/ig, '_');
subst['{TARGET_ID}'] = d.target.node_id;
- subst['{TARGET_NAME}'] = d.target.node.nodeinfo.hostname.replace(/[^a-z0-9\-]/ig, '_');
+ subst['{TARGET_NAME}'] = d.target.hostname.replace(/[^a-z0-9\-]/ig, '_');
subst['{TIME}'] = time;
subst['{LOCALE}'] = _.locale();
- return helper.showStat(o, subst);
+ return helper.showStat(V, o, subst);
}
- return function (config, el, router, d) {
- var h2 = document.createElement('h2');
- var a1 = document.createElement('a');
- a1.href = router.generateLink({ node: d.source.node_id });
- a1.textContent = d.source.node.nodeinfo.hostname;
- h2.appendChild(a1);
+ return function (config, el, router, d, linkScale) {
+ var self = this;
+ var header = document.createElement('div');
+ var table = document.createElement('table');
+ var images = document.createElement('div');
+ el.appendChild(header);
+ el.appendChild(table);
+ el.appendChild(images);
- var arrow = document.createElement('span');
- arrow.classList.add('ion-arrow-right-c');
- h2.appendChild(arrow);
+ self.render = function render() {
+ var children = [];
+ var headers = [];
+ headers.push(V.h('h2', [
+ V.h('a', {
+ props: { href: router.generateLink({ node: d.source.node_id }) }
+ }, d.source.hostname),
+ V.h('span', ' - '),
+ V.h('a', {
+ props: { href: router.generateLink({ node: d.target.node_id }) }
+ }, d.target.hostname)
+ ]));
- var a2 = document.createElement('a');
- a2.href = router.generateLink({ node: d.target.node_id });
- a2.textContent = d.target.node.nodeinfo.hostname;
- h2.appendChild(a2);
- el.appendChild(h2);
+ header = V.patch(header, V.h('div', headers));
- var attributes = document.createElement('table');
- attributes.classList.add('attributes');
+ children.push(helper.attributeEntry(V, 'node.connectionType', d.type));
+ children.push(helper.attributeEntry(V, 'node.tq', V.h('span',
+ {
+ style:
+ {
+ color: linkScale((d.source_tq + d.target_tq) / 2)
+ }
+ }, helper.showTq(d.source_tq) + ' - ' + helper.showTq(d.target_tq))));
+ children.push(helper.attributeEntry(V, 'node.distance', helper.showDistance(d)));
+ children.push(helper.attributeEntry(V, 'node.hardware',
+ helper.dictGet(d.source, ['model']) + ' – ' + helper.dictGet(d.target, ['model']))
+ );
- helper.attributeEntry(attributes, 'node.tq', helper.showTq(d));
- helper.attributeEntry(attributes, 'node.distance', helper.showDistance(d));
- var hw1 = helper.dictGet(d.source.node.nodeinfo, ['hardware', 'model']);
- var hw2 = helper.dictGet(d.target.node.nodeinfo, ['hardware', 'model']);
- helper.attributeEntry(attributes, 'node.hardware', hw1 + ' – ' + hw2);
+ var elNew = V.h('table', children);
+ table = V.patch(table, elNew);
+ table.elm.classList.add('attributes');
- el.appendChild(attributes);
+ if (config.linkInfos) {
+ var time = d.target.lastseen.format('DDMMYYYYHmmss');
+ var img = [];
+ config.linkInfos.forEach(function (linkInfo) {
+ img.push(V.h('h4', linkInfo.name));
+ img.push(showStatImg(linkInfo, d, time));
+ });
+ images = V.patch(images, V.h('div', img));
+ }
+ };
- if (config.linkInfos) {
- var time = d.target.node.lastseen.format('DDMMYYYYHmmss');
- config.linkInfos.forEach(function (linkInfo) {
- var h4 = document.createElement('h4');
- h4.textContent = linkInfo.name;
- el.appendChild(h4);
- el.appendChild(showStatImg(linkInfo, d, time));
+ self.setData = function setData(data) {
+ d = data.links.find(function (a) {
+ return a.id === d.id;
});
- }
+ self.render();
+ };
+ return self;
};
});
diff --git a/lib/infobox/main.js b/lib/infobox/main.js
index e436efd..564c794 100644
--- a/lib/infobox/main.js
+++ b/lib/infobox/main.js
@@ -1,9 +1,11 @@
-define(['infobox/link', 'infobox/node', 'infobox/location'], function (link, node, location) {
+define(['infobox/link', 'infobox/node', 'infobox/location'], function (Link, Node, location) {
'use strict';
- return function (config, sidebar, router) {
+ return function (config, sidebar, router, linkScale) {
var self = this;
var el;
+ var node;
+ var link;
function destroy() {
if (el && el.parentNode) {
@@ -38,12 +40,14 @@ define(['infobox/link', 'infobox/node', 'infobox/location'], function (link, nod
self.gotoNode = function gotoNode(d, gateways) {
create();
- node(config, el, router, d, gateways);
+ node = new Node(config, el, router, d, linkScale, gateways);
+ node.render();
};
self.gotoLink = function gotoLink(d) {
create();
- link(config, el, router, d);
+ link = new Link(config, el, router, d, linkScale);
+ link.render();
};
self.gotoLocation = function gotoLocation(d) {
@@ -51,6 +55,16 @@ define(['infobox/link', 'infobox/node', 'infobox/location'], function (link, nod
location(config, el, router, d);
};
+ self.setData = function setData(d) {
+ if (typeof node === 'object') {
+ node.setData(d);
+ }
+ if (typeof link === 'object') {
+ link.setData(d);
+ }
+ };
+
+
return self;
};
});
diff --git a/lib/infobox/node.js b/lib/infobox/node.js
index ce13df9..edddd68 100644
--- a/lib/infobox/node.js
+++ b/lib/infobox/node.js
@@ -8,35 +8,34 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
return undefined;
}
- return function (el) {
- var a = document.createElement('a');
- a.textContent = Number(d.nodeinfo.location.latitude.toFixed(6)) + ', ' + Number(d.nodeinfo.location.longitude.toFixed(6));
- a.href = 'geo:' + d.nodeinfo.location.latitude + ',' + d.nodeinfo.location.longitude;
- el.appendChild(a);
- };
+ return V.h('td',
+ V.h('a',
+ { props: { href: 'geo:' + d.location.latitude + ',' + d.location.longitude } },
+ Number(d.location.latitude.toFixed(6)) + ', ' + Number(d.location.longitude.toFixed(6))
+ )
+ );
}
function showStatus(d) {
- return function (el) {
- el.classList.add(d.flags.unseen ? 'unseen' : (d.flags.online ? 'online' : 'offline'));
- el.textContent = _.t((d.flags.online ? 'node.lastOnline' : 'node.lastOffline'), {
+ return V.h('td',
+ { props: { className: d.is_unseen ? 'unseen' : (d.is_online ? 'online' : 'offline') } },
+ _.t((d.is_online ? 'node.lastOnline' : 'node.lastOffline'), {
time: d.lastseen.fromNow(),
date: d.lastseen.format('DD.MM.YYYY, H:mm:ss')
- });
- };
+ }));
}
function showFirmware(d) {
return [
- helper.dictGet(d.nodeinfo, ['software', 'firmware', 'release']),
- helper.dictGet(d.nodeinfo, ['software', 'firmware', 'base'])
+ helper.dictGet(d, ['firmware', 'release']),
+ helper.dictGet(d, ['firmware', 'base'])
].filter(function (n) {
return n !== null;
}).join(' / ') || undefined;
}
function showSite(d, config) {
- var site = helper.dictGet(d.nodeinfo, ['system', 'site_code']);
+ var site = helper.dictGet(d, ['site_code']);
var rt = site;
if (config.siteNames) {
config.siteNames.forEach(function (t) {
@@ -49,11 +48,11 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
}
function showUptime(d) {
- if (!('uptime' in d.statistics)) {
+ if (!('uptime' in d)) {
return undefined;
}
- return moment.duration(d.statistics.uptime, 'seconds').humanize();
+ return moment.duration(d.uptime, 'seconds').humanize();
}
function showFirstseen(d) {
@@ -65,101 +64,89 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
}
function showClients(d) {
- if (!d.flags.online) {
+ if (!d.is_online) {
return undefined;
}
- return function (el) {
- el.appendChild(document.createTextNode(d.statistics.clients > 0 ? d.statistics.clients : _.t('none')));
- el.appendChild(document.createElement('br'));
+ var clients = [
+ d.clients > 0 ? d.clients : _.t('none'),
+ V.h('br')
+ ];
- var span = document.createElement('span');
- span.classList.add('clients');
- span.innerHTML = ''.repeat(d.statistics.clients);
- el.appendChild(span);
- };
+ for (var i = 0; i < d.clients; i++) {
+ clients.push(V.h('i', { props: { className: 'ion-person' } }));
+ }
+ return V.h('td', clients);
}
function showIPs(d) {
- var ips = helper.dictGet(d.nodeinfo, ['network', 'addresses']);
+ var ips = helper.dictGet(d, ['network', 'addresses']);
if (ips === null) {
return undefined;
}
ips.sort();
- return function (el) {
- ips.forEach(function (ip, i) {
- var link = !ip.startsWith('fe80:');
+ var string = [];
+ ips.forEach(function (ip, i) {
+ var link = !ip.startsWith('fe80:');
- if (i > 0) {
- el.appendChild(document.createElement('br'));
- }
+ if (i > 0) {
+ string.push(V.h('br'));
+ }
- if (link) {
- var a = document.createElement('a');
- a.href = 'http://[' + ip + ']/';
- a.textContent = ip;
- el.appendChild(a);
- } else {
- el.appendChild(document.createTextNode(ip));
- }
- });
- };
+ if (link) {
+ string.push(V.h('a', { props: { href: 'http://[' + ip + ']/', target: '_blank' } }, ip));
+ } else {
+ string.push(ip);
+ }
+ });
+ return V.h('td', string);
}
function showBar(v, width, warning) {
- var span = document.createElement('span');
- span.classList.add('bar');
-
- var bar = document.createElement('span');
- bar.style.width = (width * 100) + '%';
- if (warning) {
- span.classList.add('warning');
- }
- span.appendChild(bar);
-
- var label = document.createElement('label');
- label.textContent = v;
- span.appendChild(label);
-
- return span;
+ return V.h('span',
+ { props: { className: 'bar' + (warning ? ' warning' : '') } },
+ [
+ V.h('span',
+ {
+ style: { width: (width * 100) + '%' }
+ }),
+ V.h('label', v)
+ ]
+ );
}
function showLoad(d) {
- if (!('loadavg' in d.statistics)) {
+ if (!('loadavg' in d)) {
return undefined;
}
- return function (el) {
- var value = d.statistics.loadavg.toFixed(2);
- var width = d.statistics.loadavg % 1;
- var warning = false;
- if (d.statistics.loadavg >= d.nodeinfo.hardware.nproc) {
- warning = true;
- }
- el.appendChild(showBar(value, width, warning));
- };
+ var value = d.loadavg.toFixed(2);
+ var width = d.loadavg % 1;
+ var warning = false;
+ if (d.loadavg >= d.nproc) {
+ warning = true;
+ }
+ return showBar(value, width, warning);
}
function showRAM(d) {
- if (!('memory_usage' in d.statistics)) {
+ if (!('memory_usage' in d)) {
return undefined;
}
- return function (el) {
- var value = Math.round(d.statistics.memory_usage * 100) + ' %';
- var width = d.statistics.memory_usage;
- var warning = false;
- if (d.statistics.memory_usage >= 0.8) {
- warning = true;
- }
- el.appendChild(showBar(value, width, warning));
- };
+ var value = Math.round(d.memory_usage * 100) + ' %';
+ var width = d.memory_usage;
+ var warning = false;
+ if (d.memory_usage >= 0.8) {
+ warning = true;
+ }
+ return showBar(value, width, warning);
}
function showAutoupdate(d) {
- var au = helper.dictGet(d.nodeinfo, ['software', 'autoupdater']);
+ var au = helper.dictGet(d, ['autoupdater']);
if (!au) {
return undefined;
}
@@ -169,16 +156,14 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
function showStatImg(o, d) {
var subst = {};
- subst['{NODE_ID}'] = d.nodeinfo.node_id;
- subst['{NODE_NAME}'] = d.nodeinfo.hostname.replace(/[^a-z0-9\-]/ig, '_');
+ subst['{NODE_ID}'] = d.node_id;
+ subst['{NODE_NAME}'] = d.hostname.replace(/[^a-z0-9\-]/ig, '_');
subst['{TIME}'] = d.lastseen.format('DDMMYYYYHmmss');
subst['{LOCALE}'] = _.locale();
- return helper.showStat(o, subst);
+ return helper.showStat(V, o, subst);
}
- return function (config, el, router, d, gateways) {
- var linkScale = d3Interpolate.interpolate('#F02311', '#04C714');
-
+ return function (config, el, router, d, linkScale, gateways) {
function renderNeighbourRow(n) {
var icons = [];
icons.push(V.h('span', { props: { className: n.incoming ? 'ion-arrow-left-c' : 'ion-arrow-right-c' } }));
@@ -189,107 +174,122 @@ define(['sorttable', 'snabbdom', 'd3-interpolate', 'moment', 'helper'],
var name = V.h('a', {
props: {
className: 'online',
- href: router.generateLink({ node: n.node.nodeinfo.node_id })
+ href: router.generateLink({ node: n.node.node_id })
}, on: {
click: function (e) {
- router.fullUrl({ node: n.node.nodeinfo.node_id }, e);
+ router.fullUrl({ node: n.node.node_id }, e);
}
}
- }, n.node.nodeinfo.hostname);
+ }, n.node.hostname);
var td1 = V.h('td', icons);
var td2 = V.h('td', name);
- var td3 = V.h('td', (n.node.statistics.clients ? n.node.statistics.clients.toString() : '0'));
- var td4 = V.h('td', { style: { color: linkScale(1 / n.link.tq) } }, helper.showTq(n.link));
+ var td3 = V.h('td', (n.node.clients ? n.node.clients.toString() : '0'));
+ var td4 = V.h('td', { style: { color: linkScale((n.link.source_tq + n.link.target_tq) / 2) } }, helper.showTq(n.link.source_tq) + ' - ' + helper.showTq(n.link.target_tq));
var td5 = V.h('td', helper.showDistance(n.link));
return V.h('tr', [td1, td2, td3, td4, td5]);
}
- var h2 = document.createElement('h2');
- h2.textContent = d.nodeinfo.hostname;
- el.appendChild(h2);
+ var self = this;
+ var header = document.createElement('h2');
+ var table = document.createElement('table');
+ var images = document.createElement('div');
+ var neighbours = document.createElement('h3');
+ var headings = [{
+ name: ''
+ }, {
+ name: 'node.nodes',
+ sort: function (a, b) {
+ return a.node.hostname.localeCompare(b.node.hostname);
+ },
+ reverse: false
+ }, {
+ name: 'node.clients',
+ class: 'ion-people',
+ sort: function (a, b) {
+ return ('clients' in a.node ? a.node.clients : -1) -
+ ('clients' in b.node ? b.node.clients : -1);
+ },
+ reverse: true
+ }, {
+ name: 'node.tq',
+ class: 'ion-connection-bars',
+ sort: function (a, b) {
+ return a.link.source_tq - b.link.source_tq;
+ },
+ reverse: true
+ }, {
+ name: 'node.distance',
+ class: 'ion-arrow-resize',
+ sort: function (a, b) {
+ return (a.link.distance === undefined ? -1 : a.link.distance) -
+ (b.link.distance === undefined ? -1 : b.link.distance);
+ },
+ reverse: true
+ }];
+ var tableNeighbour = new SortTable(headings, 1, renderNeighbourRow);
- var attributes = document.createElement('table');
- attributes.classList.add('attributes');
+ el.appendChild(header);
+ el.appendChild(table);
+ el.appendChild(neighbours);
+ el.appendChild(tableNeighbour.el);
+ el.appendChild(images);
- helper.attributeEntry(attributes, 'node.status', showStatus(d));
- helper.attributeEntry(attributes, 'node.gateway', d.flags.gateway ? 'ja' : null);
- helper.attributeEntry(attributes, 'node.coordinates', showGeoURI(d));
+ self.render = function render() {
+ V.patch(header, V.h('h2', d.hostname));
- if (config.nodeInfobox && config.nodeInfobox.contact) {
- helper.attributeEntry(attributes, 'node.contact', helper.dictGet(d.nodeinfo, ['owner', 'contact']));
- }
+ var children = [];
- helper.attributeEntry(attributes, 'node.hardware', helper.dictGet(d.nodeinfo, ['hardware', 'model']));
- helper.attributeEntry(attributes, 'node.primaryMac', helper.dictGet(d.nodeinfo, ['network', 'mac']));
- helper.attributeEntry(attributes, 'node.id', helper.dictGet(d.nodeinfo, ['node_id']));
- helper.attributeEntry(attributes, 'node.firmware', showFirmware(d));
- helper.attributeEntry(attributes, 'node.site', showSite(d, config));
- helper.attributeEntry(attributes, 'node.uptime', showUptime(d));
- helper.attributeEntry(attributes, 'node.firstSeen', showFirstseen(d));
- if (config.nodeInfobox && config.nodeInfobox.hardwareUsage) {
- helper.attributeEntry(attributes, 'node.systemLoad', showLoad(d));
- helper.attributeEntry(attributes, 'node.ram', showRAM(d));
- }
- helper.attributeEntry(attributes, 'node.ipAddresses', showIPs(d));
- helper.attributeEntry(attributes, 'node.selectedGateway', gateways[helper.dictGet(d.statistics, ['gateway'])]);
- helper.attributeEntry(attributes, 'node.update', showAutoupdate(d));
- helper.attributeEntry(attributes, 'node.clients', showClients(d));
+ children.push(helper.attributeEntry(V, 'node.status', showStatus(d)));
+ children.push(helper.attributeEntry(V, 'node.gateway', d.is_gateway ? 'ja' : null));
+ children.push(helper.attributeEntry(V, 'node.coordinates', showGeoURI(d)));
- el.appendChild(attributes);
+ if (config.nodeInfobox && config.nodeInfobox.contact) {
+ children.push(helper.attributeEntry(V, 'node.contact', helper.dictGet(d, ['owner', 'contact'])));
+ }
- if (d.neighbours.length > 0) {
- var h3 = document.createElement('h3');
- h3.textContent = _.t('node.link', d.neighbours.length) + ' (' + d.neighbours.length + ')';
- el.appendChild(h3);
+ children.push(helper.attributeEntry(V, 'node.hardware', helper.dictGet(d, ['model'])));
+ children.push(helper.attributeEntry(V, 'node.primaryMac', helper.dictGet(d, ['network', 'mac'])));
+ children.push(helper.attributeEntry(V, 'node.firmware', showFirmware(d)));
+ children.push(helper.attributeEntry(V, 'node.site', showSite(d, config)));
+ children.push(helper.attributeEntry(V, 'node.uptime', showUptime(d)));
+ children.push(helper.attributeEntry(V, 'node.firstSeen', showFirstseen(d)));
+ if (config.nodeInfobox && config.nodeInfobox.hardwareUsage) {
+ children.push(helper.attributeEntry(V, 'node.systemLoad', showLoad(d)));
+ children.push(helper.attributeEntry(V, 'node.ram', showRAM(d)));
+ }
+ children.push(helper.attributeEntry(V, 'node.ipAddresses', showIPs(d)));
+ children.push(helper.attributeEntry(V, 'node.selectedGateway', gateways[helper.dictGet(d, ['gateway'])]));
+ children.push(helper.attributeEntry(V, 'node.update', showAutoupdate(d)));
+ children.push(helper.attributeEntry(V, 'node.clients', showClients(d)));
- var headings = [{
- name: ''
- }, {
- name: 'node.nodes',
- sort: function (a, b) {
- return a.node.nodeinfo.hostname.localeCompare(b.node.nodeinfo.hostname);
- },
- reverse: false
- }, {
- name: 'node.clients',
- class: 'ion-people',
- sort: function (a, b) {
- return ('clients' in a.node.statistics ? a.node.statistics.clients : -1) -
- ('clients' in b.node.statistics ? b.node.statistics.clients : -1);
- },
- reverse: true
- }, {
- name: 'node.tq',
- class: 'ion-connection-bars',
- sort: function (a, b) {
- return a.link.tq - b.link.tq;
- },
- reverse: true
- }, {
- name: 'node.distance',
- class: 'ion-arrow-resize',
- sort: function (a, b) {
- return (a.link.distance === undefined ? -1 : a.link.distance) -
- (b.link.distance === undefined ? -1 : b.link.distance);
- },
- reverse: true
- }];
+ var elNew = V.h('table', children);
+ table = V.patch(table, elNew);
+ table.elm.classList.add('attributes');
- var table = new SortTable(headings, 1, renderNeighbourRow);
- table.setData(d.neighbours);
- table.el.elm.classList.add('node-links');
- el.appendChild(table.el.elm);
- }
+ V.patch(neighbours, V.h('h3', _.t('node.link', d.neighbours.length) + ' (' + d.neighbours.length + ')'));
+ if (d.neighbours.length > 0) {
+ tableNeighbour.setData(d.neighbours);
+ tableNeighbour.el.elm.classList.add('node-links');
+ }
- if (config.nodeInfos) {
- config.nodeInfos.forEach(function (nodeInfo) {
- var h4 = document.createElement('h4');
- h4.textContent = nodeInfo.name;
- el.appendChild(h4);
- el.appendChild(showStatImg(nodeInfo, d));
+ if (config.nodeInfos) {
+ var img = [];
+ config.nodeInfos.forEach(function (nodeInfo) {
+ img.push(V.h('h4', nodeInfo.name));
+ img.push(showStatImg(nodeInfo, d));
+ });
+ images = V.patch(images, V.h('div', img));
+ }
+ };
+
+ self.setData = function setData(data) {
+ d = data.nodes.all.find(function (a) {
+ return a.node_id === d.node_id;
});
- }
+ self.render();
+ };
+ return self;
};
});
diff --git a/lib/legend.js b/lib/legend.js
index fca8a4f..530accf 100644
--- a/lib/legend.js
+++ b/lib/legend.js
@@ -10,10 +10,10 @@ define(['helper'], function (helper) {
var totalNodes = helper.sum(d.nodes.all.map(helper.one));
var totalOnlineNodes = helper.sum(d.nodes.all.filter(helper.online).map(helper.one));
var totalClients = helper.sum(d.nodes.all.filter(helper.online).map(function (n) {
- return n.statistics.clients ? n.statistics.clients : 0;
+ return n.clients ? n.clients : 0;
}));
var totalGateways = helper.sum(d.nodes.all.filter(helper.online).filter(function (n) {
- return n.flags.gateway;
+ return n.is_gateway;
}).map(helper.one));
stats.textContent = _.t('sidebar.nodes', { total: totalNodes, online: totalOnlineNodes }) + ' ' +
diff --git a/lib/linklist.js b/lib/linklist.js
index bb8eb75..d96da21 100644
--- a/lib/linklist.js
+++ b/lib/linklist.js
@@ -2,7 +2,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
'use strict';
function linkName(d) {
- return (d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + ' – ' + d.target.node.nodeinfo.hostname;
+ return (d.source ? d.source.hostname : d.source.id) + ' – ' + d.target.hostname;
}
var headings = [{
@@ -15,7 +15,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
name: 'node.tq',
class: 'ion-connection-bars',
sort: function (a, b) {
- return a.tq - b.tq;
+ return (a.source_tq + a.target_tq) / 2 - (b.source_tq + b.target_tq) / 2;
},
reverse: true
}, {
@@ -44,7 +44,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
}, linkName(d))];
var td1 = V.h('td', td1Content);
- var td2 = V.h('td', { style: { color: linkScale(1 / d.tq) } }, helper.showTq(d));
+ var td2 = V.h('td', { style: { color: linkScale((d.source_tq + d.target_tq) / 2) } }, helper.showTq(d.source_tq) + ' - ' + helper.showTq(d.target_tq));
var td3 = V.h('td', helper.showDistance(d));
return V.h('tr', [td1, td2, td3]);
@@ -59,7 +59,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
};
this.setData = function setData(d) {
- table.setData(d.graph.links);
+ table.setData(d.links);
};
};
});
diff --git a/lib/main.js b/lib/main.js
index 887dfbc..5c8b569 100644
--- a/lib/main.js
+++ b/lib/main.js
@@ -4,44 +4,19 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
return function (config) {
function handleData(data) {
- var dataNodes = {};
- dataNodes.nodes = [];
- var dataGraph = {};
- dataGraph.batadv = {};
- dataGraph.batadv.nodes = [];
- dataGraph.batadv.links = [];
+ var timestamp;
+ var nodes = [];
+ var links = [];
var gateways = {};
- function rearrangeLinks(d) {
- d.source += dataGraph.batadv.nodes.length;
- d.target += dataGraph.batadv.nodes.length;
- }
-
for (var i = 0; i < data.length; ++i) {
- var vererr;
- if (i % 2) {
- if (data[i].version !== 1) {
- vererr = 'Unsupported graph version: ' + data[i].version;
- console.error(vererr); // silent fail
- } else {
- data[i].batadv.links.forEach(rearrangeLinks);
- dataGraph.batadv.nodes = dataGraph.batadv.nodes.concat(data[i].batadv.nodes);
- dataGraph.batadv.links = dataGraph.batadv.links.concat(data[i].batadv.links);
- dataGraph.timestamp = data[i].timestamp;
- }
- } else if (data[i].version !== 2) {
- vererr = 'Unsupported nodes version: ' + data[i].version;
- console.error(vererr); // silent fail
- } else {
- dataNodes.nodes = dataNodes.nodes.concat(data[i].nodes);
- dataNodes.timestamp = data[i].timestamp;
- }
+ nodes = nodes.concat(data[i].nodes);
+ timestamp = data[i].timestamp;
+ links = links.concat(data[i].links.filter(function (d) {
+ return d.source !== undefined;
+ }));
}
- var nodes = dataNodes.nodes.filter(function (d) {
- return 'firstseen' in d && 'lastseen' in d;
- });
-
nodes.forEach(function (node) {
node.firstseen = moment.utc(node.firstseen).local();
node.lastseen = moment.utc(node.lastseen).local();
@@ -53,44 +28,12 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
var newnodes = helper.limit('firstseen', age, helper.sortByKey('firstseen', nodes).filter(helper.online));
var lostnodes = helper.limit('lastseen', age, helper.sortByKey('lastseen', nodes).filter(helper.offline));
- var graphnodes = {};
-
- dataNodes.nodes.forEach(function (d) {
- graphnodes[d.nodeinfo.node_id] = d;
- });
-
- var graph = dataGraph.batadv;
-
- graph.nodes.forEach(function (d) {
- if (d.node_id in graphnodes) {
- d.node = graphnodes[d.node_id];
- if (d.unseen) {
- d.node.flags.online = true;
- d.node.flags.unseen = true;
- }
- }
- });
-
- graph.links.forEach(function (d) {
- d.source = graph.nodes[d.source];
-
- if (graph.nodes[d.target].node) {
- d.target = graph.nodes[d.target];
- } else {
- d.target = undefined;
- }
- });
-
- var links = graph.links.filter(function (d) {
- return d.target !== undefined;
- });
-
nodes.forEach(function (d) {
d.neighbours = [];
- if (d.flags.gateway && d.nodeinfo.network.mesh) {
- var mesh = d.nodeinfo.network.mesh;
+ if (d.is_gateway && d.network.mesh) {
+ var mesh = d.network.mesh;
mesh[Object.keys(mesh)[0]].interfaces.tunnel.forEach(function (mac) {
- gateways[mac] = d.nodeinfo.hostname;
+ gateways[mac] = d.hostname;
});
}
});
@@ -98,16 +41,24 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
links.forEach(function (d) {
var ids;
- ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id];
- 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.source = nodes.find(function (a) {
+ return a.node_id === d.source;
+ });
+
+ d.target = nodes.find(function (a) {
+ return a.node_id === d.target;
+ });
+
+ ids = [d.source.node_id, d.target.node_id];
+ d.source.neighbours.push({ node: d.target, link: d, incoming: false });
+ d.target.neighbours.push({ node: d.source, link: d, incoming: true });
d.id = ids.join('-');
try {
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.target.node.nodeinfo.location.latitude, d.target.node.nodeinfo.location.longitude));
+ d.latlngs.push(L.latLng(d.source.location.latitude, d.source.location.longitude));
+ d.latlngs.push(L.latLng(d.target.location.latitude, d.target.location.longitude));
d.distance = d.latlngs[0].distanceTo(d.latlngs[1]);
} catch (e) {
@@ -116,20 +67,21 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
});
links.sort(function (a, b) {
- return b.tq - a.tq;
+ return b.source_tq - a.source_tq;
});
return {
now: now,
- timestamp: moment.utc(dataNodes.timestamp).local(),
+ timestamp: moment.utc(timestamp).local(),
nodes: {
all: nodes,
new: newnodes,
lost: lostnodes
},
+ links: links,
graph: {
- links: links,
- nodes: graph.nodes
+ links: [],
+ nodes: []
},
gateways: gateways
};
@@ -146,8 +98,7 @@ define(['moment', 'utils/router', 'leaflet', 'gui', 'helper', 'utils/language'],
for (var i in config.dataPath) {
if (config.dataPath.hasOwnProperty(i)) {
- urls.push(config.dataPath[i] + 'nodes.json');
- urls.push(config.dataPath[i] + 'graph.json');
+ urls.push(config.dataPath[i] + 'meshviewer.json');
}
}
diff --git a/lib/map.js b/lib/map.js
index d82c4fd..9974c1f 100644
--- a/lib/map.js
+++ b/lib/map.js
@@ -142,8 +142,8 @@ define(['map/clientlayer', 'map/labellayer', 'map/button', 'leaflet'],
var m;
if (highlight !== undefined) {
- if (highlight.type === 'node' && nodeDict[highlight.o.nodeinfo.node_id]) {
- m = nodeDict[highlight.o.nodeinfo.node_id];
+ if (highlight.type === 'node' && nodeDict[highlight.o.node_id]) {
+ m = nodeDict[highlight.o.node_id];
m.setStyle({ color: 'orange', weight: 20, fillOpacity: 1, opacity: 0.7, className: 'stroke-first' });
} else if (highlight.type === 'link' && linkDict[highlight.o.id]) {
m = linkDict[highlight.o.id];
diff --git a/lib/map/clientlayer.js b/lib/map/clientlayer.js
index ac09e33..aa25553 100644
--- a/lib/map/clientlayer.js
+++ b/lib/map/clientlayer.js
@@ -5,8 +5,8 @@ define(['leaflet', 'rbush', 'helper'],
return L.GridLayer.extend({
mapRTree: function mapRTree(d) {
return {
- minX: d.nodeinfo.location.latitude, minY: d.nodeinfo.location.longitude,
- maxX: d.nodeinfo.location.latitude, maxY: d.nodeinfo.location.longitude,
+ minX: d.location.latitude, minY: d.location.longitude,
+ maxX: d.location.latitude, maxY: d.location.longitude,
node: d
};
},
@@ -17,7 +17,7 @@ define(['leaflet', 'rbush', 'helper'],
// pre-calculate start angles
this.data.all().forEach(function (n) {
- n.startAngle = (parseInt(n.node.nodeinfo.node_id.substr(10, 2), 16) / 255) * 2 * Math.PI;
+ n.startAngle = (parseInt(n.node.node_id.substr(10, 2), 16) / 255) * 2 * Math.PI;
});
this.redraw();
},
@@ -49,12 +49,12 @@ define(['leaflet', 'rbush', 'helper'],
ctx.beginPath();
nodes.forEach(function (d) {
- var p = map.project([d.node.nodeinfo.location.latitude, d.node.nodeinfo.location.longitude]);
+ var p = map.project([d.node.location.latitude, d.node.location.longitude]);
p.x -= s.x;
p.y -= s.y;
- helper.positionClients(ctx, p, d.startAngle, d.node.statistics.clients, startDistance);
+ helper.positionClients(ctx, p, d.startAngle, d.node.clients, startDistance);
});
ctx.fillStyle = 'rgba(220, 0, 103, 0.7)';
diff --git a/lib/map/labellayer.js b/lib/map/labellayer.js
index 92b6550..78a4774 100644
--- a/lib/map/labellayer.js
+++ b/lib/map/labellayer.js
@@ -35,14 +35,14 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
return function (d) {
var font = fontSize + 'px ' + bodyStyle.fontFamily;
return {
- position: L.latLng(d.nodeinfo.location.latitude, d.nodeinfo.location.longitude),
- label: d.nodeinfo.hostname,
+ position: L.latLng(d.location.latitude, d.location.longitude),
+ label: d.hostname,
offset: offset,
fillStyle: fillStyle,
height: fontSize * 1.2,
font: font,
stroke: stroke,
- width: measureText(font, d.nodeinfo.hostname).width
+ width: measureText(font, d.hostname).width
};
};
}
@@ -78,18 +78,18 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
function mkMarker(dict, iconFunc, router) {
return function (d) {
- var m = L.circleMarker([d.nodeinfo.location.latitude, d.nodeinfo.location.longitude], iconFunc(d));
+ var m = L.circleMarker([d.location.latitude, d.location.longitude], iconFunc(d));
m.resetStyle = function resetStyle() {
m.setStyle(iconFunc(d));
};
m.on('click', function () {
- router.fullUrl({ node: d.nodeinfo.node_id });
+ router.fullUrl({ node: d.node_id });
});
- m.bindTooltip(d.nodeinfo.hostname);
+ m.bindTooltip(d.hostname);
- dict[d.nodeinfo.node_id] = m;
+ dict[d.node_id] = m;
return m;
};
@@ -102,7 +102,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
return graph.map(function (d) {
var opts = {
- color: linkScale(1 / d.tq),
+ color: linkScale((d.source_tq + d.target_tq) / 2),
weight: 4,
opacity: 0.5,
dashArray: 'none'
@@ -114,7 +114,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
line.setStyle(opts);
};
- line.bindTooltip(d.source.node.nodeinfo.hostname + ' – ' + d.target.node.nodeinfo.hostname + '
' + helper.showDistance(d) + ' / ' + helper.showTq(d) + '');
+ line.bindTooltip(d.source.hostname + ' – ' + d.target.hostname + '
' + helper.showDistance(d) + ' / ' + helper.showTq(d.source_tq) + ' - ' + helper.showTq(d.target_tq) + '');
line.on('click', function () {
router.fullUrl({ link: d.id });
});
@@ -151,7 +151,7 @@ define(['leaflet', 'rbush', 'helper', 'moment'],
groupLines.clearLayers();
}
- var lines = addLinksToMap(linkDict, linkScale, data.graph.links, router);
+ var lines = addLinksToMap(linkDict, linkScale, data.links, router);
groupLines = L.featureGroup(lines).addTo(map);
var nodesOnline = helper.subtract(data.nodes.all.filter(helper.online), data.nodes.new);
diff --git a/lib/nodelist.js b/lib/nodelist.js
index b16c9c3..392324a 100644
--- a/lib/nodelist.js
+++ b/lib/nodelist.js
@@ -3,9 +3,9 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
V = V.default;
function getUptime(now, d) {
- if (d.flags.online && 'uptime' in d.statistics) {
- return Math.round(d.statistics.uptime);
- } else if (!d.flags.online && 'lastseen' in d) {
+ if (d.is_online && 'uptime' in d) {
+ return Math.round(d.uptime);
+ } else if (!d.is_online && 'lastseen' in d) {
return Math.round(-(now.unix() - d.lastseen.unix()));
}
return 0;
@@ -31,7 +31,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
}, {
name: 'node.nodes',
sort: function (a, b) {
- return a.nodeinfo.hostname.localeCompare(b.nodeinfo.hostname);
+ return a.hostname.localeCompare(b.hostname);
},
reverse: false
}, {
@@ -52,8 +52,8 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
name: 'node.clients',
class: 'ion-people',
sort: function (a, b) {
- return ('clients' in a.statistics ? a.statistics.clients : -1) -
- ('clients' in b.statistics ? b.statistics.clients : -1);
+ return ('clients' in a ? a.clients : -1) -
+ ('clients' in b ? b.clients : -1);
},
reverse: true
}];
@@ -62,18 +62,18 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
function renderRow(d) {
var td0Content = [];
var td1Content = [];
- var aClass = ['hostname', d.flags.online ? 'online' : 'offline'];
+ var aClass = ['hostname', d.is_online ? 'online' : 'offline'];
td1Content.push(V.h('a', {
props: {
className: aClass.join(' '),
- href: router.generateLink({ node: d.nodeinfo.node_id })
+ href: router.generateLink({ node: d.node_id })
}, on: {
click: function (e) {
- router.fullUrl({ node: d.nodeinfo.node_id }, e);
+ router.fullUrl({ node: d.node_id }, e);
}
}
- }, d.nodeinfo.hostname));
+ }, d.hostname));
if (helper.hasLocation(d)) {
td0Content.push(V.h('span', { props: { className: 'icon ion-location' } }));
@@ -83,7 +83,7 @@ define(['sorttable', 'snabbdom', 'helper'], function (SortTable, V, helper) {
var td1 = V.h('td', td1Content);
var td2 = V.h('td', showUptime(d.uptime));
var td3 = V.h('td', d.neighbours.length);
- var td4 = V.h('td', Number('clients' in d.statistics ? d.statistics.clients : 0).toFixed(0));
+ var td4 = V.h('td', Number('clients' in d ? d.clients : 0).toFixed(0));
return V.h('tr', [td0, td1, td2, td3, td4]);
}
diff --git a/lib/proportions.js b/lib/proportions.js
index 0c4eb15..611543b 100644
--- a/lib/proportions.js
+++ b/lib/proportions.js
@@ -15,11 +15,6 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'],
var gatewayTable;
var siteTable;
-
- function showStatGlobal(o) {
- return helper.showStat(o);
- }
-
function count(nodes, key, f) {
var dict = {};
@@ -86,19 +81,19 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'],
var nodeDict = {};
data.nodes.all.forEach(function (d) {
- nodeDict[d.nodeinfo.node_id] = d;
+ nodeDict[d.node_id] = d;
});
- var statusDict = count(nodes, ['flags', 'online'], function (d) {
+ var statusDict = count(nodes, ['is_online'], function (d) {
return d ? 'online' : 'offline';
});
- var fwDict = count(nodes, ['nodeinfo', 'software', 'firmware', 'release']);
- var hwDict = count(nodes, ['nodeinfo', 'hardware', 'model']);
- var geoDict = count(nodes, ['nodeinfo', 'location'], function (d) {
+ var fwDict = count(nodes, ['firmware', 'release']);
+ var hwDict = count(nodes, ['model']);
+ var geoDict = count(nodes, ['location'], function (d) {
return d && d.longitude && d.latitude ? _.t('yes') : _.t('no');
});
- var autoDict = count(nodes, ['nodeinfo', 'software', 'autoupdater'], function (d) {
+ var autoDict = count(nodes, ['autoupdater'], function (d) {
if (d === null) {
return null;
} else if (d.enabled) {
@@ -107,7 +102,7 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'],
return _.t('node.deactivated');
});
- var gatewayDict = count(nodes, ['statistics', 'gateway'], function (d) {
+ var gatewayDict = count(nodes, ['is_gateway'], function (d) {
for (var mac in data.gateways) {
if (data.gateways.hasOwnProperty(mac) && mac === d) {
d = data.gateways[mac];
@@ -117,7 +112,7 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'],
return null;
});
- var siteDict = count(nodes, ['nodeinfo', 'system', 'site_code'], function (d) {
+ var siteDict = count(nodes, ['nodeinfo', 'site_code'], function (d) {
if (config.siteNames) {
config.siteNames.forEach(function (t) {
if (d === t.site) {
@@ -158,7 +153,6 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'],
};
self.render = function render(el) {
- var h2;
self.renderSingle(el, 'node.status', statusTable);
self.renderSingle(el, 'node.firmware', fwTable);
self.renderSingle(el, 'node.hardware', hwTable);
@@ -168,12 +162,14 @@ define(['d3-interpolate', 'snabbdom', 'filters/genericnode', 'helper'],
self.renderSingle(el, 'node.site', siteTable);
if (config.globalInfos) {
+ var images = document.createElement('div');
+ el.appendChild(images);
+ var img = [];
config.globalInfos.forEach(function (globalInfo) {
- h2 = document.createElement('h2');
- h2.textContent = globalInfo.name;
- el.appendChild(h2);
- el.appendChild(showStatGlobal(globalInfo));
+ img.push(V.h('h2', globalInfo.name));
+ img.push(helper.showStat(V, globalInfo));
});
+ V.patch(images, V.h('div', img));
}
};
diff --git a/lib/simplenodelist.js b/lib/simplenodelist.js
index ea2c6cf..89b4bda 100644
--- a/lib/simplenodelist.js
+++ b/lib/simplenodelist.js
@@ -38,18 +38,18 @@ define(['moment', 'snabbdom', 'helper'], function (moment, V, helper) {
var td0Content = [];
var td1Content = [];
- var aClass = ['hostname', d.flags.online ? 'online' : 'offline'];
+ var aClass = ['hostname', d.is_online ? 'online' : 'offline'];
td1Content.push(V.h('a', {
props: {
className: aClass.join(' '),
- href: router.generateLink({ node: d.nodeinfo.node_id })
+ href: router.generateLink({ node: d.node_id })
}, on: {
click: function (e) {
- router.fullUrl({ node: d.nodeinfo.node_id }, e);
+ router.fullUrl({ node: d.node_id }, e);
}
}
- }, d.nodeinfo.hostname));
+ }, d.hostname));
if (helper.hasLocation(d)) {
td0Content.push(V.h('span', { props: { className: 'icon ion-location' } }));
diff --git a/lib/title.js b/lib/title.js
index 1602c08..b3855a3 100644
--- a/lib/title.js
+++ b/lib/title.js
@@ -17,11 +17,11 @@ define(function () {
};
this.gotoNode = function gotoNode(d) {
- setTitle(d.nodeinfo.hostname);
+ setTitle(d.hostname);
};
this.gotoLink = function gotoLink(d) {
- setTitle((d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + ' \u21D4 ' + d.target.node.nodeinfo.hostname);
+ setTitle((d.source ? d.source.hostname : d.source.id) + ' \u21D4 ' + d.target.hostname);
};
this.gotoLocation = function gotoLocation() {
diff --git a/lib/utils/helper.js b/lib/utils/helper.js
index 3587542..6264990 100644
--- a/lib/utils/helper.js
+++ b/lib/utils/helper.js
@@ -73,30 +73,29 @@ define({
},
/* Helpers working with nodes */
-
offline: function offline(d) {
- return !d.flags.online;
+ return !d.is_online;
},
online: function online(d) {
- return d.flags.online;
+ return d.is_online;
},
hasLocation: function hasLocation(d) {
- return 'location' in d.nodeinfo &&
- Math.abs(d.nodeinfo.location.latitude) < 90 &&
- Math.abs(d.nodeinfo.location.longitude) < 180;
+ return 'location' in d &&
+ Math.abs(d.location.latitude) < 90 &&
+ Math.abs(d.location.longitude) < 180;
},
subtract: function subtract(a, b) {
var ids = {};
b.forEach(function (d) {
- ids[d.nodeinfo.node_id] = true;
+ ids[d.node_id] = true;
});
return a.filter(function (d) {
- return !(d.nodeinfo.node_id in ids);
+ return !(d.node_id in ids);
});
},
@@ -111,59 +110,41 @@ define({
},
showTq: function showTq(d) {
- return (1 / d.tq * 100).toFixed(0) + '%';
+ return (d * 100).toFixed(0) + '%';
},
- attributeEntry: function attributeEntry(el, label, value) {
+ attributeEntry: function attributeEntry(V, label, value) {
if (value === null || value === undefined) {
return '';
}
- var tr = document.createElement('tr');
- var th = document.createElement('th');
- th.textContent = _.t(label);
- tr.appendChild(th);
-
- var td = document.createElement('td');
-
- if (typeof value === 'function') {
- value(td);
- } else {
- td.appendChild(document.createTextNode(value));
+ if (typeof value !== 'object') {
+ value = V.h('td', value);
}
- tr.appendChild(td);
-
- el.appendChild(tr);
-
- return td;
+ return V.h('tr', [
+ V.h('th', _.t(label)),
+ value
+ ]);
},
- showStat: function showStat(o, subst) {
+ showStat: function showStat(V, o, subst) {
var content;
subst = typeof subst !== 'undefined' ? subst : {};
- content = document.createElement('img');
- content.src = require('helper').listReplace(o.image, subst);
-
- var p = document.createElement('p');
+ content = V.h('img', { attrs: { src: require('helper').listReplace(o.image, subst) } });
if (o.href) {
- var link = document.createElement('a');
- link.target = '_blank';
- link.href = require('helper').listReplace(o.href, subst);
- link.appendChild(content);
-
- if (o.title) {
- link.title = require('helper').listReplace(o.title, subst);
- }
-
- p.appendChild(link);
- } else {
- p.appendChild(content);
+ return V.h('p', V.h('a', {
+ attrs:
+ {
+ href: require('helper').listReplace(o.href, subst),
+ target: '_blank',
+ title: require('helper').listReplace(o.title, subst)
+ }
+ }, content));
}
-
- return p;
+ return V.h('p', content);
},
getTileBBox: function getTileBBox(s, map, tileSize, margin) {
diff --git a/lib/utils/router.js b/lib/utils/router.js
index 55ba478..1e52204 100644
--- a/lib/utils/router.js
+++ b/lib/utils/router.js
@@ -144,10 +144,10 @@ define(['Navigo'], function (Navigo) {
objects.gateways = data.gateways;
data.nodes.all.forEach(function (d) {
- objects.nodes[d.nodeinfo.node_id] = d;
+ objects.nodes[d.node_id] = d;
});
- data.graph.links.forEach(function (d) {
+ data.links.forEach(function (d) {
objects.links[d.id] = d;
});
};
diff --git a/locale/en.json b/locale/en.json
index 9452ff3..6745724 100644
--- a/locale/en.json
+++ b/locale/en.json
@@ -6,6 +6,7 @@
"links": "Links",
"clients": "Clients",
"distance": "Distance",
+ "connectionType": "Connection type",
"tq": "Transmit quality",
"lastOnline": "online, last message %{time} (%{date})",
"lastOffline": "offline, last message %{time} (%{date})",
diff --git a/scss/modules/_sidebar.scss b/scss/modules/_sidebar.scss
index 9ab49fb..bc021f3 100644
--- a/scss/modules/_sidebar.scss
+++ b/scss/modules/_sidebar.scss
@@ -58,7 +58,7 @@
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
- width: 66%;
+ width: 60%;
}
}
}