label below nodes, simplify node highlighting

This commit is contained in:
Nils Schneider 2012-09-12 07:40:19 +02:00
parent 76e9ad1595
commit 90940c8f21
4 changed files with 92 additions and 52 deletions

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
} }

View file

@ -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