proportions.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. define(["chroma-js", "virtual-dom", "numeral-intl"],
  2. function (Chroma, V, numeral) {
  3. return function (config) {
  4. var self = this
  5. var scale = Chroma.scale("YlGnBu").mode("lab")
  6. var statusTable = document.createElement("table")
  7. statusTable.classList.add("proportion")
  8. var fwTable = document.createElement("table")
  9. fwTable.classList.add("proportion")
  10. var hwTable = document.createElement("table")
  11. hwTable.classList.add("proportion")
  12. var geoTable = document.createElement("table")
  13. geoTable.classList.add("proportion")
  14. var autoTable = document.createElement("table")
  15. autoTable.classList.add("proportion")
  16. function showStatGlobal(o) {
  17. var content, caption
  18. if (o.thumbnail) {
  19. content = document.createElement("img")
  20. content.src = o.thumbnail
  21. }
  22. if (o.caption) {
  23. caption = o.caption
  24. if (!content)
  25. content = document.createTextNode(caption)
  26. }
  27. var p = document.createElement("p")
  28. if (o.href) {
  29. var link = document.createElement("a")
  30. link.target = "_blank"
  31. link.href = o.href
  32. link.appendChild(content)
  33. if (caption && o.thumbnail)
  34. link.title = caption
  35. p.appendChild(link)
  36. } else
  37. p.appendChild(content)
  38. return p
  39. }
  40. function count(nodes, key, f) {
  41. var dict = {}
  42. nodes.forEach( function (d) {
  43. var v = dictGet(d, key.slice(0))
  44. if (f !== undefined)
  45. v = f(v)
  46. if (v === null)
  47. return
  48. dict[v] = 1 + (v in dict ? dict[v] : 0)
  49. })
  50. return Object.keys(dict).map(function (d) { return [d, dict[d]] })
  51. }
  52. function fillTable(table, data) {
  53. if (!table.last)
  54. table.last = V.h("table")
  55. var max = 0
  56. data.forEach(function (d) {
  57. if (d[1] > max)
  58. max = d[1]
  59. })
  60. var items = data.map(function (d) {
  61. var v = d[1] / max
  62. var c1 = Chroma.contrast(scale(v), "white")
  63. var c2 = Chroma.contrast(scale(v), "black")
  64. var th = V.h("th", d[0])
  65. var td = V.h("td", V.h("span", {style: {
  66. width: Math.round(v * 100) + "%",
  67. backgroundColor: scale(v).hex(),
  68. color: c1 > c2 ? "white" : "black"
  69. }}, numeral(d[1]).format("0,0")))
  70. return V.h("tr", [th, td])
  71. })
  72. var tableNew = V.h("table", items)
  73. table = V.patch(table, V.diff(table.last, tableNew))
  74. table.last = tableNew
  75. }
  76. self.setData = function (data) {
  77. var onlineNodes = data.nodes.all.filter(online)
  78. var nodes = onlineNodes.concat(data.nodes.lost)
  79. var nodeDict = {}
  80. data.nodes.all.forEach(function (d) {
  81. nodeDict[d.nodeinfo.node_id] = d
  82. })
  83. var statusDict = count(nodes, ["flags", "online"], function (d) {
  84. return d ? "online" : "offline"
  85. })
  86. var fwDict = count(nodes, ["nodeinfo", "software", "firmware", "release"])
  87. var hwDict = count(nodes, ["nodeinfo", "hardware", "model"])
  88. var geoDict = count(nodes, ["nodeinfo", "location"], function (d) {
  89. return d ? "ja" : "nein"
  90. })
  91. var autoDict = count(nodes, ["nodeinfo", "software", "autoupdater"], function (d) {
  92. if (d === null)
  93. return null
  94. else if (d.enabled)
  95. return d.branch
  96. else
  97. return "(deaktiviert)"
  98. })
  99. fillTable(statusTable, statusDict.sort(function (a, b) { return b[1] - a[1] }))
  100. fillTable(fwTable, fwDict.sort(function (a, b) { return b[1] - a[1] }))
  101. fillTable(hwTable, hwDict.sort(function (a, b) { return b[1] - a[1] }))
  102. fillTable(geoTable, geoDict.sort(function (a, b) { return b[1] - a[1] }))
  103. fillTable(autoTable, autoDict.sort(function (a, b) { return b[1] - a[1] }))
  104. }
  105. self.render = function (el) {
  106. var h2
  107. h2 = document.createElement("h2")
  108. h2.textContent = "Status"
  109. el.appendChild(h2)
  110. el.appendChild(statusTable)
  111. h2 = document.createElement("h2")
  112. h2.textContent = "Firmwareversionen"
  113. el.appendChild(h2)
  114. el.appendChild(fwTable)
  115. h2 = document.createElement("h2")
  116. h2.textContent = "Hardwaremodelle"
  117. el.appendChild(h2)
  118. el.appendChild(hwTable)
  119. h2 = document.createElement("h2")
  120. h2.textContent = "Auf der Karte sichtbar"
  121. el.appendChild(h2)
  122. el.appendChild(geoTable)
  123. h2 = document.createElement("h2")
  124. h2.textContent = "Autoupdater"
  125. el.appendChild(h2)
  126. el.appendChild(autoTable)
  127. if (config.globalInfos)
  128. config.globalInfos.forEach( function (globalInfo) {
  129. h2 = document.createElement("h2")
  130. h2.textContent = globalInfo.name
  131. el.appendChild(h2)
  132. el.appendChild(showStatGlobal(globalInfo))
  133. })
  134. }
  135. return self
  136. }
  137. })