label below nodes, simplify node highlighting
This commit is contained in:
parent
76e9ad1595
commit
90940c8f21
|
@ -6,15 +6,13 @@
|
||||||
stroke-width: 2.5px;
|
stroke-width: 2.5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node text {
|
.node text, .label text {
|
||||||
font-size: 11px;
|
font-size: 10px;
|
||||||
fill: #000;
|
fill: #000;
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.link line {
|
.link line {
|
||||||
stroke: #ddd;
|
stroke: #ddd;
|
||||||
stroke-opacity: 1;
|
|
||||||
stroke-width: 5px;
|
stroke-width: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,3 +59,7 @@
|
||||||
fill: #ddd;
|
fill: #ddd;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label rect {
|
||||||
|
fill: rgba(255, 255, 255, 1.0);
|
||||||
|
}
|
||||||
|
|
|
@ -7,14 +7,13 @@
|
||||||
stroke-width: 2.5px;
|
stroke-width: 2.5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.node text {
|
.node text, .label text {
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
fill: #333;
|
fill: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.link line {
|
.link line {
|
||||||
stroke: #777;
|
stroke: #777;
|
||||||
stroke-opacity: 1;
|
|
||||||
stroke-width: 2.5px;
|
stroke-width: 2.5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,3 +67,11 @@
|
||||||
fill: #777;
|
fill: #777;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label rect {
|
||||||
|
fill: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
.label.highlight rect {
|
||||||
|
fill: rgba(255, 255, 100, 0.9);
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
stroke-width: 5px;
|
stroke-width: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.faded {
|
||||||
|
stroke-opacity: 0.2;
|
||||||
|
fill-opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
.node.highlight ellipse {
|
.node.highlight ellipse {
|
||||||
fill: #FFF0B3;
|
fill: #FFF0B3;
|
||||||
}
|
}
|
||||||
|
|
118
html/force.js
118
html/force.js
|
@ -41,7 +41,7 @@ function resize() {
|
||||||
|
|
||||||
d3.select("#chart")
|
d3.select("#chart")
|
||||||
.attr("width", w).attr("height", h)
|
.attr("width", w).attr("height", h)
|
||||||
|
|
||||||
if (vis)
|
if (vis)
|
||||||
vis.attr("width", w).attr("height", h)
|
vis.attr("width", w).attr("height", h)
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ function next_style() {
|
||||||
var s;
|
var s;
|
||||||
if (style !== undefined)
|
if (style !== undefined)
|
||||||
s = d3.select("head link[title=" + style + "] + link")
|
s = d3.select("head link[title=" + style + "] + link")
|
||||||
|
|
||||||
if (s == null || s[0][0] == null)
|
if (s == null || s[0][0] == null)
|
||||||
s = d3.select("head link[title]")
|
s = d3.select("head link[title]")
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ function show_node(mac) {
|
||||||
|
|
||||||
d3.selectAll("#chart .node")
|
d3.selectAll("#chart .node")
|
||||||
.each( function(d) {
|
.each( function(d) {
|
||||||
if (d.id == mac)
|
if (d.id == mac)
|
||||||
d3.select(this)
|
d3.select(this)
|
||||||
.classed("marked", true)
|
.classed("marked", true)
|
||||||
})
|
})
|
||||||
|
@ -156,32 +156,32 @@ function isConnected(a, b) {
|
||||||
a.index == b.index
|
a.index == b.index
|
||||||
}
|
}
|
||||||
|
|
||||||
function fade(opacity) {
|
function highlight(b) {
|
||||||
return function(d) {
|
return function(d) {
|
||||||
if (dragging) return
|
if (dragging) return
|
||||||
|
|
||||||
vis.selectAll("g.node")
|
vis.selectAll("g.node")
|
||||||
.style("stroke-opacity", function(o) {
|
.classed("faded", function(o) {
|
||||||
var connected = isConnected(d, o)
|
return !(isConnected(d, o)) && b
|
||||||
|
})
|
||||||
|
.classed("highlight", function(o) {
|
||||||
|
return isConnected(d, o) && b
|
||||||
|
})
|
||||||
|
|
||||||
if (connected && opacity != 1)
|
vis.selectAll("g.label")
|
||||||
d3.select(this)
|
.classed("faded", function(o) {
|
||||||
.classed("highlight", true)
|
return !isConnected(d, o) && b
|
||||||
else
|
})
|
||||||
d3.select(this)
|
.classed("highlight", function(o) {
|
||||||
.classed("highlight", false)
|
return o == d && b
|
||||||
|
})
|
||||||
|
|
||||||
thisOpacity = connected?1:opacity
|
vis.selectAll(".link")
|
||||||
this.setAttribute('fill-opacity', thisOpacity)
|
.classed("faded", function(o) {
|
||||||
return thisOpacity
|
return !(o.source === d || o.target === d) && b
|
||||||
})
|
|
||||||
|
|
||||||
vis.selectAll(".link *")
|
|
||||||
.style("stroke-opacity", function(o) {
|
|
||||||
return o.source === d || o.target === d ? 1 : opacity
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function show_node_info(d) {
|
function show_node_info(d) {
|
||||||
d3.selectAll("#nodeinfo").remove()
|
d3.selectAll("#nodeinfo").remove()
|
||||||
|
@ -238,6 +238,8 @@ vis.append("g").attr("class", "links")
|
||||||
|
|
||||||
vis.append("g").attr("class", "nodes")
|
vis.append("g").attr("class", "nodes")
|
||||||
|
|
||||||
|
vis.append("g").attr("class", "labels")
|
||||||
|
|
||||||
var linkedByIndex
|
var linkedByIndex
|
||||||
|
|
||||||
var force = d3.layout.force()
|
var force = d3.layout.force()
|
||||||
|
@ -261,11 +263,11 @@ var force = d3.layout.force()
|
||||||
switch (d.type) {
|
switch (d.type) {
|
||||||
case "vpn": return 0.01
|
case "vpn": return 0.01
|
||||||
case "client": return 1
|
case "client": return 1
|
||||||
default: return 0.5
|
default: return 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
force.on("tick", function() {
|
force.on("tick", function(e) {
|
||||||
var size = force.size()
|
var size = force.size()
|
||||||
var nodes = force.nodes()
|
var nodes = force.nodes()
|
||||||
var nl = nodes.length
|
var nl = nodes.length
|
||||||
|
@ -287,7 +289,11 @@ force.on("tick", function() {
|
||||||
.attr("x2", function(d) { return d.target.x })
|
.attr("x2", function(d) { return d.target.x })
|
||||||
.attr("y2", function(d) { return d.target.y })
|
.attr("y2", function(d) { return d.target.y })
|
||||||
|
|
||||||
vis.selectAll(".node").attr("transform", function(d) {
|
vis.selectAll(".node").attr("transform", function(d) {
|
||||||
|
return "translate(" + d.x + "," + d.y + ")";
|
||||||
|
})
|
||||||
|
|
||||||
|
vis.selectAll(".label").attr("transform", function(d) {
|
||||||
return "translate(" + d.x + "," + d.y + ")";
|
return "translate(" + d.x + "," + d.y + ")";
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -405,11 +411,11 @@ function update() {
|
||||||
return false
|
return false
|
||||||
|
|
||||||
if (!visible.clients && (d.source.flags.client || d.target.flags.client))
|
if (!visible.clients && (d.source.flags.client || d.target.flags.client))
|
||||||
return false
|
return false
|
||||||
|
|
||||||
// hides links to clients
|
// hides links to clients
|
||||||
if (!visible.vpn && (d.source.flags.vpn || d.target.flags.vpn))
|
if (!visible.vpn && (d.source.flags.vpn || d.target.flags.vpn))
|
||||||
return false
|
return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
@ -478,7 +484,10 @@ function update() {
|
||||||
return false
|
return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
|
.sort(function(a, b) {
|
||||||
|
return (a.flags.client?1:0) < (b.flags.client?1:0)
|
||||||
|
})
|
||||||
|
|
||||||
var node = vis.select("g.nodes")
|
var node = vis.select("g.nodes")
|
||||||
.selectAll("g.node")
|
.selectAll("g.node")
|
||||||
|
@ -493,8 +502,8 @@ function update() {
|
||||||
return d.id
|
return d.id
|
||||||
})
|
})
|
||||||
.attr("class", "node")
|
.attr("class", "node")
|
||||||
.on("mouseover", fade(.2))
|
.on("mouseover", highlight(true))
|
||||||
.on("mouseout", fade(1))
|
.on("mouseout", highlight(false))
|
||||||
.on("click", show_node_info)
|
.on("click", show_node_info)
|
||||||
.call(node_drag)
|
.call(node_drag)
|
||||||
|
|
||||||
|
@ -512,8 +521,7 @@ function update() {
|
||||||
.attr("rx", function(d) {
|
.attr("rx", function(d) {
|
||||||
var r
|
var r
|
||||||
if (d.flags.client) r = 4
|
if (d.flags.client) r = 4
|
||||||
else if (visible.labels) r = Math.max(10, d.name.length * 5)
|
else r = 8
|
||||||
else r = 10
|
|
||||||
|
|
||||||
d.rx = r
|
d.rx = r
|
||||||
|
|
||||||
|
@ -522,37 +530,55 @@ function update() {
|
||||||
.attr("ry", function(d) {
|
.attr("ry", function(d) {
|
||||||
var r
|
var r
|
||||||
if (d.flags.client) r = 4
|
if (d.flags.client) r = 4
|
||||||
else if (visible.labels) r = 10
|
else r = 8
|
||||||
else r = 10
|
|
||||||
|
|
||||||
d.ry = r
|
d.ry = r
|
||||||
|
|
||||||
return r
|
return r
|
||||||
})
|
})
|
||||||
|
|
||||||
nodeEnter.filter(function(d) {
|
var label = vis.select("g.labels")
|
||||||
return !d.flags.client
|
.selectAll("g.label")
|
||||||
})
|
.data(nodes.filter(function(d) {
|
||||||
.append("text")
|
return !d.flags.client && visible.labels
|
||||||
.attr("class", "name")
|
}), function(d) {
|
||||||
.attr("text-anchor", "middle")
|
return d.id
|
||||||
.attr("y", "4px")
|
}
|
||||||
|
)
|
||||||
|
|
||||||
node.selectAll("text.name")
|
var labelEnter = label.enter()
|
||||||
|
.append("g")
|
||||||
|
.attr("id", function (d) {
|
||||||
|
return d.id
|
||||||
|
})
|
||||||
|
.attr("class", "label")
|
||||||
|
|
||||||
|
labelEnter.append("rect")
|
||||||
|
.attr("y", "10px")
|
||||||
|
.attr("x", function(d) { return - d.name.length * 7/2 })
|
||||||
|
.attr("width", function(d) { return d.name.length * 7 })
|
||||||
|
.attr("height", "15px")
|
||||||
|
|
||||||
|
labelEnter.append("text")
|
||||||
|
.attr("class", "name")
|
||||||
|
.attr("text-anchor", "middle")
|
||||||
|
.attr("y", "21px")
|
||||||
|
.attr("x", "0px")
|
||||||
|
|
||||||
|
label.selectAll("text.name")
|
||||||
.text(function(d) {
|
.text(function(d) {
|
||||||
if (visible.labels)
|
return d.name
|
||||||
return d.name
|
|
||||||
|
|
||||||
return ""
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
label.exit().remove()
|
||||||
|
|
||||||
nodeEnter.append("title")
|
nodeEnter.append("title")
|
||||||
|
|
||||||
node.selectAll("title")
|
node.selectAll("title")
|
||||||
.text(function(d) { return d.name?d.name:" " })
|
.text(function(d) { return d.name?d.name:" " })
|
||||||
|
|
||||||
node.selectAll(".uplinks").remove()
|
node.selectAll(".uplinks").remove()
|
||||||
|
|
||||||
if (!visible.vpn) {
|
if (!visible.vpn) {
|
||||||
var uplink_info = node.filter(function (d) {
|
var uplink_info = node.filter(function (d) {
|
||||||
return d.vpns > 0
|
return d.vpns > 0
|
||||||
|
|
Loading…
Reference in a new issue