Переглянути джерело

work on forcegraph reload

Nils Schneider 9 роки тому
батько
коміт
d6e0587c55
4 змінених файлів з 105 додано та 61 видалено
  1. 72 38
      lib/forcegraph.js
  2. 13 12
      lib/linklist.js
  3. 12 2
      lib/main.js
  4. 8 9
      lib/nodelist.js

+ 72 - 38
lib/forcegraph.js

@@ -1,13 +1,13 @@
 define(["d3"], function (d3) {
    return function (config, linkScale, sidebar, router) {
     var self = this
-    var nodes, links
     var svg, vis, link, node
     var nodesDict, linksDict
     var zoomBehavior
     var force
     var el
     var doAnimation = false
+    var intNodes = []
 
     var LINK_DISTANCE = 70
 
@@ -19,18 +19,18 @@ define(["d3"], function (d3) {
       if (!localStorageTest())
         return
 
-      var save = nodes.map( function (d) {
-        return { id: d.id, x: d.x, y: d.y }
+      var save = intNodes.map( function (d) {
+        return { id: d.o.id, x: d.x, y: d.y }
       })
 
       localStorage.setItem("graph/nodeposition", JSON.stringify(save))
     }
 
     function nodeName(d) {
-      if (d.node && d.node.nodeinfo)
-        return d.node.nodeinfo.hostname
+      if (d.o.node && d.o.node.nodeinfo)
+        return d.o.node.nodeinfo.hostname
       else
-        return d.id
+        return d.o.id
     }
 
     function dragstart(d) {
@@ -132,7 +132,7 @@ define(["d3"], function (d3) {
               .gravity(0.05)
               .linkDistance(LINK_DISTANCE)
               .linkStrength(function (d) {
-                return 1 / d.tq
+                return 1 / d.o.tq
               })
               .on("tick", tickEvent)
               .on("end", savePositions)
@@ -145,25 +145,45 @@ define(["d3"], function (d3) {
                           .on("dragend", dragend)
 
     self.setData = function (data) {
-      var nodePositions = {}
+      var oldNodes = {}
 
-      if (localStorageTest()) {
-        var save = JSON.parse(localStorage.getItem("graph/nodeposition"))
+      intNodes.forEach( function (d) {
+        oldNodes[d.o.id] = d
+      })
 
-        if (save)
-          save.forEach( function (d) {
-            nodePositions[d.id] = d
-          })
-      }
+      intNodes = data.graph.nodes.map( function (d) {
+        var e
+        if (d.id in oldNodes)
+          e = oldNodes[d.id]
+        else
+          e = {}
+
+        e.o = d
 
-      links = data.graph.links.filter( function (d) {
+        return e
+      })
+
+      var newNodesDict = {}
+
+      intNodes.forEach( function (d) {
+        newNodesDict[d.o.id] = d
+      })
+
+      var intLinks = data.graph.links.filter( function (d) {
         return !d.vpn
+      }).map( function (d) {
+        var source = newNodesDict[d.source.id]
+        var target = newNodesDict[d.target.id]
+
+        return {o: d, source: source, target: target}
       })
 
       link = vis.select("g.links")
                 .selectAll("g.link")
                 .data(links, function (d) { return d.id })
 
+      link.exit().remove()
+
       var linkEnter = link.enter().append("g")
                           .attr("class", "link")
                           .on("click", function (d) {
@@ -175,34 +195,34 @@ define(["d3"], function (d3) {
                .append("title")
 
       link.selectAll("line")
-          .style("stroke", function (d) { return linkScale(d.tq) })
+          .style("stroke", function (d) { return linkScale(d.o.tq).hex() })
 
-      link.selectAll("title").text(showTq)
+      link.selectAll("title").text(function (d) { return showTq(d.o) })
 
       linksDict = {}
 
       link.each( function (d) {
-        if (d.source.node && d.target.node)
-          linksDict[d.id] = d
+        if (d.o.source.node && d.o.target.node)
+          linksDict[d.o.id] = d
       })
 
-      nodes = data.graph.nodes
-
       node = vis.select("g.nodes")
                 .selectAll(".node")
-                .data(nodes, function(d) { return d.id })
+                .data(intNodes, function(d) { return d.o.id })
+
+      node.exit().remove()
 
       var nodeEnter = node.enter().append("circle")
                           .attr("r", 8)
                           .on("click", function (d) {
                             if (!d3.event.defaultPrevented)
-                              router.node(d.node)()
+                              router.node(d.o.node)()
                           })
                           .call(draggableNode)
 
       node.attr("class", function (d) {
         var s = ["node"]
-        if (!d.node)
+        if (!d.o.node)
           s.push("unknown")
 
         return s.join(" ")
@@ -211,26 +231,40 @@ define(["d3"], function (d3) {
       nodesDict = {}
 
       node.each( function (d) {
-        if (d.node)
-          nodesDict[d.node.nodeinfo.node_id] = d
+        if (d.o.node)
+          nodesDict[d.o.node.nodeinfo.node_id] = d
       })
 
       nodeEnter.append("title")
-      nodeEnter.each( function (d) {
-        if (nodePositions[d.id]) {
-          d.x = nodePositions[d.id].x
-          d.y = nodePositions[d.id].y
+
+      if (localStorageTest()) {
+        var save = JSON.parse(localStorage.getItem("graph/nodeposition"))
+
+        if (save) {
+          var nodePositions = {}
+          save.forEach( function (d) {
+            nodePositions[d.id] = d
+          })
+
+          nodeEnter.each( function (d) {
+            if (nodePositions[d.o.id]) {
+              d.x = nodePositions[d.o.id].x
+              d.y = nodePositions[d.o.id].y
+            }
+          })
         }
-      })
+      }
 
       node.selectAll("title").text(nodeName)
 
-      var diameter = graphDiameter(nodes)
+      var diameter = graphDiameter(intNodes)
 
-      force.nodes(nodes)
-           .links(links)
+      force.nodes(intNodes)
+           .links(intLinks)
            .size([diameter, diameter])
-           .start()
+
+      if (node.enter().size() + link.enter().size() > 0)
+        force.start()
     }
 
     self.resetView = function () {
@@ -245,7 +279,7 @@ define(["d3"], function (d3) {
     self.gotoNode = function (d) {
       link.classed("highlight", false)
       node.classed("highlight", function (e) {
-        return e.node === d && d !== undefined
+        return e.o.node === d && d !== undefined
       })
 
       var n = nodesDict[d.nodeinfo.node_id]
@@ -259,7 +293,7 @@ define(["d3"], function (d3) {
     self.gotoLink = function (d) {
       node.classed("highlight", false)
       link.classed("highlight", function (e) {
-        return e === d && d !== undefined
+        return e.o === d && d !== undefined
       })
 
       var l = linksDict[d.id]

+ 13 - 12
lib/linklist.js

@@ -1,8 +1,8 @@
-define(["tablesort", "virtual-dom", "tablesort.numeric"],
-  function (Tablesort, V) {
+define(["virtual-dom"],
+  function (V) {
   return function(linkScale, router) {
     var self = this
-    var el, tbody, sort
+    var el, tbody
 
     self.render = function (d)  {
       el = document.createElement("div")
@@ -34,7 +34,6 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
 
         var th3 = document.createElement("th")
         th3.textContent = "Entfernung"
-        th3.classList.add("sort-default")
         tr.appendChild(th3)
 
         thead.appendChild(tr)
@@ -43,11 +42,16 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
         tbody = document.createElement("tbody")
         tbody.last = V.h("tbody")
         table.appendChild(tbody)
-
-        sort = new Tablesort(table)
       }
 
-      var items = data.graph.links.map( function (d) {
+      var links = data.graph.links.slice(0).sort( function (a, b) {
+        a = a.distance === undefined ? -1 : a.distance
+        b = b.distance === undefined ? -1 : b.distance
+
+        return b - a
+      })
+
+      var items = links.map( function (d) {
         var name = d.source.node.nodeinfo.hostname + " – " + d.target.node.nodeinfo.hostname
         var td1Content = [V.h("a", {href: "#", onclick: router.link(d)}, name)]
 
@@ -55,10 +59,8 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
           td1Content.push(" (VPN)")
 
         var td1 = V.h("td", td1Content)
-        var td2 = V.h("td", {style: {color: linkScale(d.tq)}}, showTq(d))
-        var td3 = V.h("td", {attributes: {
-                              "data-sort": d.distance !== undefined ? -d.distance : 1
-                            }}, showDistance(d))
+        var td2 = V.h("td", {style: {color: linkScale(d.tq).hex()}}, showTq(d))
+        var td3 = V.h("td", showDistance(d))
 
         return V.h("tr", [td1, td2, td3])
       })
@@ -66,7 +68,6 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
       var tbodyNew = V.h("tbody", items)
       tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew))
       tbody.last = tbodyNew
-      sort.refresh()
     }
   }
 })

+ 12 - 2
lib/main.js

@@ -88,14 +88,24 @@ function (config, moment, Router, L, GUI, numeral) {
     var urls = [ config.dataPath + "nodes.json",
                  config.dataPath + "graph.json"
                ]
+    function update() {
+      return Promise.all(urls.map(getJSON))
+                    .then(handleData)
+    }
 
-    Promise.all(urls.map(getJSON))
-      .then(handleData)
+    update()
       .then(function (d) {
         var gui = new GUI(config, router)
         gui.setData(d)
         router.setData(d)
         router.start()
+
+        window.setInterval(function () {
+          update().then(function (d) {
+            gui.setData(d)
+            router.setData(d)
+          })
+        }, 60000)
       })
       .catch(function (e) {
         console.log(e)

+ 8 - 9
lib/nodelist.js

@@ -1,5 +1,5 @@
-define(["tablesort", "virtual-dom", "tablesort.numeric"],
-  function (Tablesort, V) {
+define(["virtual-dom"],
+  function (V) {
   return function(router) {
     function showUptime(now, d) {
       var uptime
@@ -20,7 +20,7 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
     }
 
     var self = this
-    var el, tbody, sort
+    var el, tbody
 
     self.render = function (d) {
       el = document.createElement("div")
@@ -44,7 +44,6 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
         var tr = document.createElement("tr")
         var th1 = document.createElement("th")
         th1.textContent = "Knoten"
-        th1.classList.add("sort-default")
         tr.appendChild(th1)
 
         var th2 = document.createElement("th")
@@ -61,12 +60,13 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
         tbody = document.createElement("tbody")
         tbody.last = V.h("tbody")
         table.appendChild(tbody)
-
-        sort = new Tablesort(table)
       }
 
+      var nodes = data.nodes.all.slice(0).sort( function (a, b) {
+        return a.nodeinfo.hostname.localeCompare(b.nodeinfo.hostname)
+      })
 
-      var items = data.nodes.all.map( function (d) {
+      var items = nodes.map( function (d) {
         var td1Content = []
         var aClass = ["hostname", d.flags.online ? "online" : "offline"]
 
@@ -81,7 +81,7 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
         var uptime = showUptime(data.now, d)
 
         var td1 = V.h("td", td1Content)
-        var td2 = V.h("td", {attributes: { "data-sort": uptime.sort }}, uptime.v)
+        var td2 = V.h("td", uptime.v)
         var td3 = V.h("td", "clients" in d.statistics ? d.statistics.clients : "")
 
         return V.h("tr", [td1, td2, td3])
@@ -90,7 +90,6 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
       var tbodyNew = V.h("tbody", items)
       tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew))
       tbody.last = tbodyNew
-      sort.refresh()
    }
   }
 })