work on forcegraph reload

This commit is contained in:
Nils Schneider 2015-04-03 02:32:32 +02:00
parent 0490455ccf
commit d6e0587c55
4 changed files with 105 additions and 61 deletions

View file

@ -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) { var save = intNodes.map( function (d) {
return { id: d.id, x: d.x, y: d.y } 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) if (d.o.node && d.o.node.nodeinfo)
return d.node.nodeinfo.hostname 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()) { intNodes.forEach( function (d) {
var save = JSON.parse(localStorage.getItem("graph/nodeposition")) oldNodes[d.o.id] = d
if (save)
save.forEach( function (d) {
nodePositions[d.id] = d
}) })
}
links = data.graph.links.filter( function (d) { intNodes = data.graph.nodes.map( function (d) {
var e
if (d.id in oldNodes)
e = oldNodes[d.id]
else
e = {}
e.o = 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) if (d.o.source.node && d.o.target.node)
linksDict[d.id] = d 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) if (d.o.node)
nodesDict[d.node.nodeinfo.node_id] = d nodesDict[d.o.node.nodeinfo.node_id] = d
}) })
nodeEnter.append("title") nodeEnter.append("title")
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) { nodeEnter.each( function (d) {
if (nodePositions[d.id]) { if (nodePositions[d.o.id]) {
d.x = nodePositions[d.id].x d.x = nodePositions[d.o.id].x
d.y = nodePositions[d.id].y 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) force.nodes(intNodes)
.links(links) .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]

View file

@ -1,8 +1,8 @@
define(["tablesort", "virtual-dom", "tablesort.numeric"], define(["virtual-dom"],
function (Tablesort, V) { 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 td2 = V.h("td", {style: {color: linkScale(d.tq).hex()}}, showTq(d))
var td3 = V.h("td", {attributes: { var td3 = V.h("td", showDistance(d))
"data-sort": d.distance !== undefined ? -d.distance : 1
}}, 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()
} }
} }
}) })

View file

@ -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() {
Promise.all(urls.map(getJSON)) return Promise.all(urls.map(getJSON))
.then(handleData) .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)

View file

@ -1,5 +1,5 @@
define(["tablesort", "virtual-dom", "tablesort.numeric"], define(["virtual-dom"],
function (Tablesort, V) { 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()
} }
} }
}) })