Browse Source

work on forcegraph reload

Nils Schneider 9 years ago
parent
commit
d6e0587c55
4 changed files with 105 additions and 61 deletions
  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) {
 define(["d3"], function (d3) {
    return function (config, linkScale, sidebar, router) {
    return function (config, linkScale, sidebar, router) {
     var self = this
     var self = this
-    var nodes, links
     var svg, vis, link, node
     var svg, vis, link, node
     var nodesDict, linksDict
     var nodesDict, linksDict
     var zoomBehavior
     var zoomBehavior
     var force
     var force
     var el
     var el
     var doAnimation = false
     var doAnimation = false
+    var intNodes = []
 
 
     var LINK_DISTANCE = 70
     var LINK_DISTANCE = 70
 
 
@@ -19,18 +19,18 @@ define(["d3"], function (d3) {
       if (!localStorageTest())
       if (!localStorageTest())
         return
         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))
       localStorage.setItem("graph/nodeposition", JSON.stringify(save))
     }
     }
 
 
     function nodeName(d) {
     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
       else
-        return d.id
+        return d.o.id
     }
     }
 
 
     function dragstart(d) {
     function dragstart(d) {
@@ -132,7 +132,7 @@ define(["d3"], function (d3) {
               .gravity(0.05)
               .gravity(0.05)
               .linkDistance(LINK_DISTANCE)
               .linkDistance(LINK_DISTANCE)
               .linkStrength(function (d) {
               .linkStrength(function (d) {
-                return 1 / d.tq
+                return 1 / d.o.tq
               })
               })
               .on("tick", tickEvent)
               .on("tick", tickEvent)
               .on("end", savePositions)
               .on("end", savePositions)
@@ -145,25 +145,45 @@ define(["d3"], function (d3) {
                           .on("dragend", dragend)
                           .on("dragend", dragend)
 
 
     self.setData = function (data) {
     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
         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")
       link = vis.select("g.links")
                 .selectAll("g.link")
                 .selectAll("g.link")
                 .data(links, function (d) { return d.id })
                 .data(links, function (d) { return d.id })
 
 
+      link.exit().remove()
+
       var linkEnter = link.enter().append("g")
       var linkEnter = link.enter().append("g")
                           .attr("class", "link")
                           .attr("class", "link")
                           .on("click", function (d) {
                           .on("click", function (d) {
@@ -175,34 +195,34 @@ define(["d3"], function (d3) {
                .append("title")
                .append("title")
 
 
       link.selectAll("line")
       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 = {}
       linksDict = {}
 
 
       link.each( function (d) {
       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")
       node = vis.select("g.nodes")
                 .selectAll(".node")
                 .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")
       var nodeEnter = node.enter().append("circle")
                           .attr("r", 8)
                           .attr("r", 8)
                           .on("click", function (d) {
                           .on("click", function (d) {
                             if (!d3.event.defaultPrevented)
                             if (!d3.event.defaultPrevented)
-                              router.node(d.node)()
+                              router.node(d.o.node)()
                           })
                           })
                           .call(draggableNode)
                           .call(draggableNode)
 
 
       node.attr("class", function (d) {
       node.attr("class", function (d) {
         var s = ["node"]
         var s = ["node"]
-        if (!d.node)
+        if (!d.o.node)
           s.push("unknown")
           s.push("unknown")
 
 
         return s.join(" ")
         return s.join(" ")
@@ -211,26 +231,40 @@ define(["d3"], function (d3) {
       nodesDict = {}
       nodesDict = {}
 
 
       node.each( function (d) {
       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.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)
       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])
            .size([diameter, diameter])
-           .start()
+
+      if (node.enter().size() + link.enter().size() > 0)
+        force.start()
     }
     }
 
 
     self.resetView = function () {
     self.resetView = function () {
@@ -245,7 +279,7 @@ define(["d3"], function (d3) {
     self.gotoNode = function (d) {
     self.gotoNode = function (d) {
       link.classed("highlight", false)
       link.classed("highlight", false)
       node.classed("highlight", function (e) {
       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]
       var n = nodesDict[d.nodeinfo.node_id]
@@ -259,7 +293,7 @@ define(["d3"], function (d3) {
     self.gotoLink = function (d) {
     self.gotoLink = function (d) {
       node.classed("highlight", false)
       node.classed("highlight", false)
       link.classed("highlight", function (e) {
       link.classed("highlight", function (e) {
-        return e === d && d !== undefined
+        return e.o === d && d !== undefined
       })
       })
 
 
       var l = linksDict[d.id]
       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) {
   return function(linkScale, router) {
     var self = this
     var self = this
-    var el, tbody, sort
+    var el, tbody
 
 
     self.render = function (d)  {
     self.render = function (d)  {
       el = document.createElement("div")
       el = document.createElement("div")
@@ -34,7 +34,6 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
 
 
         var th3 = document.createElement("th")
         var th3 = document.createElement("th")
         th3.textContent = "Entfernung"
         th3.textContent = "Entfernung"
-        th3.classList.add("sort-default")
         tr.appendChild(th3)
         tr.appendChild(th3)
 
 
         thead.appendChild(tr)
         thead.appendChild(tr)
@@ -43,11 +42,16 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
         tbody = document.createElement("tbody")
         tbody = document.createElement("tbody")
         tbody.last = V.h("tbody")
         tbody.last = V.h("tbody")
         table.appendChild(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 name = d.source.node.nodeinfo.hostname + " – " + d.target.node.nodeinfo.hostname
         var td1Content = [V.h("a", {href: "#", onclick: router.link(d)}, name)]
         var td1Content = [V.h("a", {href: "#", onclick: router.link(d)}, name)]
 
 
@@ -55,10 +59,8 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
           td1Content.push(" (VPN)")
           td1Content.push(" (VPN)")
 
 
         var td1 = V.h("td", td1Content)
         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])
         return V.h("tr", [td1, td2, td3])
       })
       })
@@ -66,7 +68,6 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
       var tbodyNew = V.h("tbody", items)
       var tbodyNew = V.h("tbody", items)
       tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew))
       tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew))
       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",
     var urls = [ config.dataPath + "nodes.json",
                  config.dataPath + "graph.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) {
       .then(function (d) {
         var gui = new GUI(config, router)
         var gui = new GUI(config, router)
         gui.setData(d)
         gui.setData(d)
         router.setData(d)
         router.setData(d)
         router.start()
         router.start()
+
+        window.setInterval(function () {
+          update().then(function (d) {
+            gui.setData(d)
+            router.setData(d)
+          })
+        }, 60000)
       })
       })
       .catch(function (e) {
       .catch(function (e) {
         console.log(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) {
   return function(router) {
     function showUptime(now, d) {
     function showUptime(now, d) {
       var uptime
       var uptime
@@ -20,7 +20,7 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
     }
     }
 
 
     var self = this
     var self = this
-    var el, tbody, sort
+    var el, tbody
 
 
     self.render = function (d) {
     self.render = function (d) {
       el = document.createElement("div")
       el = document.createElement("div")
@@ -44,7 +44,6 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
         var tr = document.createElement("tr")
         var tr = document.createElement("tr")
         var th1 = document.createElement("th")
         var th1 = document.createElement("th")
         th1.textContent = "Knoten"
         th1.textContent = "Knoten"
-        th1.classList.add("sort-default")
         tr.appendChild(th1)
         tr.appendChild(th1)
 
 
         var th2 = document.createElement("th")
         var th2 = document.createElement("th")
@@ -61,12 +60,13 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
         tbody = document.createElement("tbody")
         tbody = document.createElement("tbody")
         tbody.last = V.h("tbody")
         tbody.last = V.h("tbody")
         table.appendChild(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 td1Content = []
         var aClass = ["hostname", d.flags.online ? "online" : "offline"]
         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 uptime = showUptime(data.now, d)
 
 
         var td1 = V.h("td", td1Content)
         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 : "")
         var td3 = V.h("td", "clients" in d.statistics ? d.statistics.clients : "")
 
 
         return V.h("tr", [td1, td2, td3])
         return V.h("tr", [td1, td2, td3])
@@ -90,7 +90,6 @@ define(["tablesort", "virtual-dom", "tablesort.numeric"],
       var tbodyNew = V.h("tbody", items)
       var tbodyNew = V.h("tbody", items)
       tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew))
       tbody = V.patch(tbody, V.diff(tbody.last, tbodyNew))
       tbody.last = tbodyNew
       tbody.last = tbodyNew
-      sort.refresh()
    }
    }
   }
   }
 })
 })