2015-04-02 20:07:00 +00:00
|
|
|
define(["chroma-js", "virtual-dom", "numeral-intl"],
|
|
|
|
function (Chroma, V, numeral) {
|
|
|
|
|
2015-06-07 16:47:14 +00:00
|
|
|
return function (config) {
|
2015-03-30 00:58:47 +00:00
|
|
|
var self = this
|
|
|
|
var scale = Chroma.scale("YlGnBu").mode("lab")
|
|
|
|
|
2015-07-07 22:30:29 +00:00
|
|
|
var statusTable = document.createElement("table")
|
|
|
|
statusTable.classList.add("proportion")
|
|
|
|
|
2015-07-07 15:42:41 +00:00
|
|
|
var fwTable = document.createElement("table")
|
|
|
|
fwTable.classList.add("proportion")
|
|
|
|
|
|
|
|
var hwTable = document.createElement("table")
|
|
|
|
hwTable.classList.add("proportion")
|
|
|
|
|
|
|
|
var geoTable = document.createElement("table")
|
|
|
|
geoTable.classList.add("proportion")
|
|
|
|
|
|
|
|
var autoTable = document.createElement("table")
|
|
|
|
autoTable.classList.add("proportion")
|
|
|
|
|
|
|
|
var gwTable = document.createElement("table")
|
|
|
|
gwTable.classList.add("proportion")
|
|
|
|
|
2015-06-07 16:47:14 +00:00
|
|
|
function showStatGlobal(o) {
|
|
|
|
var content, caption
|
|
|
|
|
|
|
|
if (o.thumbnail) {
|
|
|
|
content = document.createElement("img")
|
|
|
|
content.src = o.thumbnail
|
|
|
|
}
|
|
|
|
|
|
|
|
if (o.caption) {
|
|
|
|
caption = o.caption
|
|
|
|
|
|
|
|
if (!content)
|
|
|
|
content = document.createTextNode(caption)
|
|
|
|
}
|
|
|
|
|
|
|
|
var p = document.createElement("p")
|
|
|
|
|
|
|
|
if (o.href) {
|
|
|
|
var link = document.createElement("a")
|
|
|
|
link.target = "_blank"
|
|
|
|
link.href = o.href
|
|
|
|
link.appendChild(content)
|
|
|
|
|
|
|
|
if (caption && o.thumbnail)
|
|
|
|
link.title = caption
|
|
|
|
|
|
|
|
p.appendChild(link)
|
|
|
|
} else
|
|
|
|
p.appendChild(content)
|
|
|
|
|
|
|
|
return p
|
|
|
|
}
|
|
|
|
|
2015-04-21 23:35:31 +00:00
|
|
|
function count(nodes, key, f) {
|
2015-03-30 00:58:47 +00:00
|
|
|
var dict = {}
|
|
|
|
|
|
|
|
nodes.forEach( function (d) {
|
|
|
|
var v = dictGet(d, key.slice(0))
|
|
|
|
|
|
|
|
if (f !== undefined)
|
|
|
|
v = f(v)
|
|
|
|
|
|
|
|
if (v === null)
|
2015-04-21 23:35:31 +00:00
|
|
|
return
|
2015-03-30 00:58:47 +00:00
|
|
|
|
|
|
|
dict[v] = 1 + (v in dict ? dict[v] : 0)
|
|
|
|
})
|
|
|
|
|
|
|
|
return Object.keys(dict).map(function (d) { return [d, dict[d]] })
|
|
|
|
}
|
|
|
|
|
|
|
|
function fillTable(table, data) {
|
2015-04-02 20:07:00 +00:00
|
|
|
if (!table.last)
|
|
|
|
table.last = V.h("table")
|
|
|
|
|
2015-03-30 00:58:47 +00:00
|
|
|
var max = 0
|
|
|
|
data.forEach(function (d) {
|
|
|
|
if (d[1] > max)
|
|
|
|
max = d[1]
|
|
|
|
})
|
|
|
|
|
2015-04-02 20:07:00 +00:00
|
|
|
var items = data.map(function (d) {
|
2015-03-30 00:58:47 +00:00
|
|
|
var v = d[1] / max
|
|
|
|
var c1 = Chroma.contrast(scale(v), "white")
|
|
|
|
var c2 = Chroma.contrast(scale(v), "black")
|
2015-04-02 20:07:00 +00:00
|
|
|
|
|
|
|
var th = V.h("th", d[0])
|
|
|
|
var td = V.h("td", V.h("span", {style: {
|
|
|
|
width: Math.round(v * 100) + "%",
|
|
|
|
backgroundColor: scale(v).hex(),
|
|
|
|
color: c1 > c2 ? "white" : "black"
|
|
|
|
}}, numeral(d[1]).format("0,0")))
|
|
|
|
|
|
|
|
return V.h("tr", [th, td])
|
2015-03-30 00:58:47 +00:00
|
|
|
})
|
2015-04-02 20:07:00 +00:00
|
|
|
|
|
|
|
var tableNew = V.h("table", items)
|
|
|
|
table = V.patch(table, V.diff(table.last, tableNew))
|
|
|
|
table.last = tableNew
|
2015-03-30 00:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.setData = function (data) {
|
2015-03-30 01:12:30 +00:00
|
|
|
var onlineNodes = data.nodes.all.filter(online)
|
|
|
|
var nodes = onlineNodes.concat(data.nodes.lost)
|
|
|
|
var nodeDict = {}
|
|
|
|
|
|
|
|
data.nodes.all.forEach(function (d) {
|
|
|
|
nodeDict[d.nodeinfo.node_id] = d
|
|
|
|
})
|
2015-03-30 00:58:47 +00:00
|
|
|
|
2015-07-07 22:30:29 +00:00
|
|
|
var statusDict = count(nodes, ["flags", "online"], function (d) {
|
|
|
|
return d ? "online" : "offline"
|
|
|
|
})
|
2015-04-21 23:35:31 +00:00
|
|
|
var fwDict = count(nodes, ["nodeinfo", "software", "firmware", "release"])
|
|
|
|
var hwDict = count(nodes, ["nodeinfo", "hardware", "model"])
|
2015-06-19 18:24:41 +00:00
|
|
|
var geoDict = count(nodes, ["nodeinfo", "location"], function (d) {
|
2015-07-08 13:43:58 +00:00
|
|
|
return d ? "ja" : "nein"
|
2015-06-19 18:24:41 +00:00
|
|
|
})
|
2015-04-21 23:35:31 +00:00
|
|
|
var autoDict = count(nodes, ["nodeinfo", "software", "autoupdater"], function (d) {
|
|
|
|
if (d === null)
|
2015-03-30 00:58:47 +00:00
|
|
|
return null
|
2015-04-21 23:35:31 +00:00
|
|
|
else if (d.enabled)
|
2015-03-30 00:58:47 +00:00
|
|
|
return d.branch
|
2015-04-21 23:35:31 +00:00
|
|
|
else
|
|
|
|
return "(deaktiviert)"
|
2015-03-30 00:58:47 +00:00
|
|
|
})
|
|
|
|
|
2015-04-21 23:35:31 +00:00
|
|
|
var gwDict = count(onlineNodes, ["statistics", "gateway"], function (d) {
|
2015-03-30 01:12:30 +00:00
|
|
|
if (d === null)
|
|
|
|
return null
|
|
|
|
|
|
|
|
if (d in nodeDict)
|
|
|
|
return nodeDict[d].nodeinfo.hostname
|
|
|
|
|
|
|
|
return d
|
|
|
|
})
|
|
|
|
|
2015-07-07 22:30:29 +00:00
|
|
|
fillTable(statusTable, statusDict.sort(function (a, b) { return b[1] - a[1] }))
|
2015-03-30 00:58:47 +00:00
|
|
|
fillTable(fwTable, fwDict.sort(function (a, b) { return b[1] - a[1] }))
|
|
|
|
fillTable(hwTable, hwDict.sort(function (a, b) { return b[1] - a[1] }))
|
2015-06-19 18:24:41 +00:00
|
|
|
fillTable(geoTable, geoDict.sort(function (a, b) { return b[1] - a[1] }))
|
2015-03-30 00:58:47 +00:00
|
|
|
fillTable(autoTable, autoDict.sort(function (a, b) { return b[1] - a[1] }))
|
2015-03-30 01:12:30 +00:00
|
|
|
fillTable(gwTable, gwDict.sort(function (a, b) { return b[1] - a[1] }))
|
2015-03-30 00:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.render = function (el) {
|
|
|
|
var h2
|
2015-07-07 22:30:29 +00:00
|
|
|
h2 = document.createElement("h2")
|
|
|
|
h2.textContent = "Status"
|
|
|
|
el.appendChild(h2)
|
|
|
|
el.appendChild(statusTable)
|
|
|
|
|
2015-03-30 00:58:47 +00:00
|
|
|
h2 = document.createElement("h2")
|
|
|
|
h2.textContent = "Firmwareversionen"
|
|
|
|
el.appendChild(h2)
|
|
|
|
el.appendChild(fwTable)
|
|
|
|
|
|
|
|
h2 = document.createElement("h2")
|
|
|
|
h2.textContent = "Hardwaremodelle"
|
|
|
|
el.appendChild(h2)
|
|
|
|
el.appendChild(hwTable)
|
|
|
|
|
2015-06-19 18:24:41 +00:00
|
|
|
h2 = document.createElement("h2")
|
|
|
|
h2.textContent = "Auf der Karte sichtbar"
|
|
|
|
el.appendChild(h2)
|
|
|
|
el.appendChild(geoTable)
|
|
|
|
|
2015-03-30 00:58:47 +00:00
|
|
|
h2 = document.createElement("h2")
|
|
|
|
h2.textContent = "Autoupdater"
|
|
|
|
el.appendChild(h2)
|
|
|
|
el.appendChild(autoTable)
|
2015-03-30 01:12:30 +00:00
|
|
|
|
|
|
|
h2 = document.createElement("h2")
|
|
|
|
h2.textContent = "Gewählter Gateway"
|
|
|
|
el.appendChild(h2)
|
|
|
|
el.appendChild(gwTable)
|
2015-06-07 16:47:14 +00:00
|
|
|
|
|
|
|
if (config.globalInfos)
|
|
|
|
config.globalInfos.forEach( function (globalInfo) {
|
|
|
|
h2 = document.createElement("h2")
|
|
|
|
h2.textContent = globalInfo.name
|
|
|
|
el.appendChild(h2)
|
|
|
|
|
|
|
|
el.appendChild(showStatGlobal(globalInfo))
|
|
|
|
})
|
2015-03-30 00:58:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return self
|
|
|
|
}
|
|
|
|
})
|