Skip to content

Instantly share code, notes, and snippets.

@emeeks
Last active March 17, 2016 02:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save emeeks/936c4ba41fd8cd565d06 to your computer and use it in GitHub Desktop.
Save emeeks/936c4ba41fd8cd565d06 to your computer and use it in GitHub Desktop.
Networks - Graphs 2

Graph Example 2 for How to Create Effective Network Data Visualization

Changing the network topology interactively. Nodes or edges can be removed by double-clicking on them. This filters the corresponding entries in the node and edge arrays, re-applies them to the force layout, and exits the necessary elements.

This requires setting key values for the selection when the data-binding is done.

It also introduces SVG:g elements for edges, so that a much thicker, fully-transparent under-edge can be created not only to increase the interaction surface for the edge but also to provide visual feedback (the blue highlighting) when a user mouses over the edge.

For exploratory and explanatory network data visualization, interactivity like this can be very effective to demonstrate the importance or unimportance of certain nodes or edges. Allowing for changes to network topology by the user also promote network literacy, which is critical for organizations that intend to use network data visualization effectively.

source target weight
1 3 5
1 8 3
1 9 3
1 12 3
1 15 2
1 23 3
1 26 2
1 37 2
1 46 2
2 1 1
2 4 2
2 5 1
2 6 3
2 7 5
2 8 4
2 10 1
2 11 5
2 12 1
2 13 4
2 14 4
2 16 2
2 18 3
2 19 2
2 20 5
2 21 1
2 22 3
2 25 3
2 26 1
2 27 4
2 28 4
2 29 5
2 31 2
2 33 2
2 34 3
2 35 5
2 37 1
2 38 4
2 41 3
3 1 4
3 4 1
3 8 1
3 9 4
3 12 4
3 22 1
3 31 1
3 32 4
3 33 2
3 37 1
3 46 4
4 8 3
4 11 2
4 20 2
4 32 3
4 33 3
4 40 5
5 2 1
5 6 5
5 7 1
5 13 1
5 14 2
5 17 1
5 18 1
5 19 5
5 20 3
5 21 2
5 23 3
5 25 3
5 26 5
5 27 2
5 28 1
5 29 3
5 34 1
5 36 3
5 38 1
5 39 4
5 44 3
5 45 5
6 2 1
6 5 3
6 7 1
6 11 1
6 13 1
6 14 1
6 17 3
6 19 4
6 20 2
6 21 3
6 23 3
6 25 5
6 26 5
6 27 1
6 28 5
6 29 1
6 35 1
6 36 5
6 38 1
6 39 5
6 44 5
6 45 4
7 2 5
7 8 3
7 11 3
7 13 3
7 14 5
7 19 2
7 20 4
7 23 2
7 26 2
7 27 2
7 28 2
7 29 4
7 34 4
7 35 5
7 38 2
7 45 2
8 1 4
8 2 3
8 3 2
8 4 4
8 7 3
8 9 3
8 10 3
8 11 1
8 12 4
8 15 2
8 16 2
8 18 1
8 19 1
8 20 2
8 22 4
8 29 1
8 31 5
8 32 4
8 33 5
8 34 3
8 37 2
8 38 2
8 40 2
8 41 3
8 42 1
8 43 1
8 45 1
8 46 1
9 1 3
9 3 2
9 4 1
9 8 1
9 12 1
9 15 1
9 17 5
9 18 1
9 26 1
9 31 1
9 32 2
9 33 1
9 37 1
9 40 1
9 46 1
10 1 3
10 2 1
10 4 1
10 8 4
10 9 5
10 11 1
10 12 1
10 14 1
10 17 5
10 18 1
10 19 1
10 20 2
10 23 2
10 28 2
10 31 2
10 33 1
10 34 1
10 37 2
10 38 3
10 40 2
10 41 2
10 42 1
10 43 2
10 44 1
10 45 1
11 2 5
11 20 4
11 38 3
11 45 4
12 1 3
12 2 1
12 3 2
12 4 1
12 5 1
12 6 1
12 7 1
12 8 3
12 9 2
12 10 1
12 11 1
12 13 1
12 14 1
12 15 1
12 16 1
12 17 1
12 18 1
12 19 1
12 20 1
12 21 1
12 22 5
12 23 1
12 24 1
12 25 1
12 26 1
12 27 1
12 28 1
12 29 1
12 30 1
12 31 2
12 32 2
12 33 5
12 34 1
12 35 1
12 36 1
12 37 2
12 38 1
12 39 1
12 40 1
12 41 2
12 42 1
12 43 1
12 44 1
12 45 1
12 46 5
13 2 3
13 5 1
13 6 1
13 7 2
13 11 1
13 17 1
13 18 2
13 19 2
13 20 2
13 21 1
13 23 1
13 25 1
13 26 1
13 27 2
13 28 1
13 29 3
13 34 1
13 35 1
13 38 1
13 44 1
13 45 1
14 2 4
14 5 1
14 6 1
14 7 2
14 8 1
14 11 1
14 19 1
14 20 3
14 22 1
14 23 1
14 27 1
14 28 1
14 31 1
14 33 1
14 35 1
14 38 2
14 41 1
14 45 1
16 1 1
16 2 1
16 3 1
16 4 1
16 5 1
16 6 1
16 7 1
16 8 1
16 9 1
16 10 1
16 11 1
16 12 1
16 13 1
16 14 1
16 15 1
16 17 1
16 18 1
16 19 1
16 20 1
16 21 1
16 22 1
16 23 1
16 24 1
16 25 1
16 26 1
16 27 1
16 28 1
16 29 1
16 30 1
16 31 1
16 32 1
16 33 1
16 34 1
16 35 1
16 36 1
16 37 1
16 38 1
16 39 1
16 40 1
16 41 1
16 42 1
16 43 1
16 44 1
16 45 1
16 46 1
17 5 1
17 6 2
17 10 5
17 13 1
17 19 3
17 20 1
17 21 1
17 23 4
17 25 2
17 26 3
17 28 3
17 29 3
17 36 2
17 38 1
17 39 2
17 44 3
17 45 3
18 1 1
18 2 4
18 5 2
18 7 2
18 8 2
18 9 1
18 10 1
18 11 2
18 13 5
18 15 1
18 16 1
18 20 4
18 22 2
18 25 4
18 26 2
18 27 3
18 28 2
18 29 2
18 31 3
18 33 3
18 34 3
18 35 1
18 37 2
18 38 2
18 40 2
19 2 3
19 5 5
19 6 5
19 7 3
19 11 2
19 13 3
19 14 2
19 17 3
19 20 2
19 21 2
19 25 3
19 26 5
19 27 2
19 28 3
19 29 2
19 36 5
19 38 3
19 39 5
19 44 5
19 45 5
20 1 2
20 2 3
20 4 2
20 5 2
20 6 2
20 7 3
20 8 4
20 9 1
20 10 2
20 11 4
20 12 2
20 13 5
20 14 4
20 17 1
20 18 4
20 19 3
20 21 1
20 22 2
20 23 3
20 25 3
20 26 2
20 27 4
20 28 4
20 29 4
20 31 3
20 34 3
20 35 2
20 36 2
20 38 4
20 41 2
20 43 2
20 44 3
20 45 5
21 2 2
21 6 3
21 17 4
21 19 2
21 20 3
21 23 2
21 25 2
21 26 3
21 27 2
21 28 3
21 29 4
21 36 2
21 39 2
21 44 4
21 45 4
22 1 1
22 2 2
22 3 1
22 4 2
22 5 1
22 6 1
22 7 1
22 8 3
22 9 1
22 10 1
22 11 2
22 12 5
22 13 1
22 14 1
22 15 5
22 16 2
22 17 1
22 18 2
22 19 1
22 20 1
22 21 1
22 23 1
22 24 1
22 25 1
22 26 1
22 27 1
22 28 1
22 29 1
22 30 1
22 31 2
22 32 2
22 33 5
22 34 2
22 35 1
22 36 1
22 37 1
22 38 4
22 39 1
22 40 5
22 41 1
22 42 1
22 43 1
22 44 1
22 45 2
22 46 2
23 1 2
23 2 1
23 5 3
23 6 3
23 7 1
23 10 3
23 11 2
23 13 1
23 14 1
23 17 4
23 19 3
23 20 3
23 21 1
23 25 2
23 26 4
23 27 1
23 28 3
23 29 4
23 31 1
23 34 1
23 35 1
23 36 5
23 38 2
23 39 4
23 44 4
23 45 2
25 2 2
25 5 2
25 6 5
25 7 1
25 11 1
25 13 1
25 17 1
25 18 2
25 19 4
25 20 3
25 23 3
25 26 4
25 27 2
25 28 3
25 29 1
25 35 1
25 36 3
25 39 3
25 44 2
25 45 3
26 1 1
26 2 1
26 5 5
26 6 5
26 7 1
26 9 1
26 11 2
26 13 1
26 17 4
26 18 1
26 19 5
26 20 2
26 21 2
26 23 5
26 25 5
26 27 2
26 28 4
26 29 2
26 31 1
26 34 1
26 35 1
26 36 5
26 38 2
26 39 5
26 44 5
26 45 5
27 2 4
27 5 2
27 6 2
27 7 2
27 11 1
27 13 5
27 14 3
27 17 1
27 18 3
27 19 2
27 20 4
27 21 1
27 23 1
27 25 3
27 26 2
27 28 2
27 29 4
27 34 1
27 35 5
27 36 1
27 38 1
27 39 1
27 44 1
27 45 3
28 2 3
28 5 2
28 6 5
28 7 2
28 10 2
28 11 2
28 13 2
28 17 4
28 18 3
28 19 3
28 20 3
28 21 2
28 23 4
28 25 2
28 26 3
28 27 2
28 29 3
28 36 3
28 38 2
28 39 2
28 44 4
28 45 3
29 2 4
29 4 1
29 5 3
29 6 1
29 7 4
29 8 1
29 11 1
29 13 3
29 14 1
29 17 1
29 18 1
29 19 1
29 20 4
29 21 2
29 23 4
29 25 1
29 26 1
29 27 3
29 28 3
29 34 1
29 35 1
29 36 1
29 38 1
29 44 2
29 45 1
30 24 1
31 1 2
31 2 2
31 3 1
31 4 3
31 8 5
31 9 1
31 10 2
31 12 2
31 16 2
31 18 3
31 20 3
31 22 2
31 23 2
31 32 2
31 34 2
31 37 1
31 38 3
31 40 3
31 41 2
31 43 1
31 45 2
32 1 2
32 3 2
32 4 5
32 8 2
32 9 2
32 12 1
32 31 1
32 33 3
32 34 2
32 37 1
32 40 5
32 41 1
32 46 1
33 1 2
33 2 2
33 4 5
33 8 5
33 9 2
33 10 2
33 11 1
33 12 5
33 14 1
33 15 3
33 16 3
33 18 3
33 20 1
33 22 5
33 31 3
33 32 3
33 34 3
33 37 3
33 38 2
33 40 5
33 43 2
34 1 1
34 2 2
34 5 1
34 6 1
34 7 1
34 8 2
34 13 1
34 16 1
34 18 1
34 19 1
34 20 1
34 22 1
34 23 1
34 25 1
34 26 1
34 27 1
34 28 1
34 29 1
34 31 3
34 32 1
34 33 4
34 35 1
34 37 2
34 38 2
34 40 1
34 42 5
34 43 1
35 2 3
35 13 2
35 18 2
35 27 4
35 29 2
35 39 2
36 2 1
36 5 3
36 6 5
36 17 3
36 18 1
36 19 4
36 20 1
36 21 1
36 23 5
36 25 4
36 26 5
36 28 4
36 29 2
36 39 4
36 44 5
36 45 5
37 1 2
37 2 1
37 8 2
37 9 1
37 10 2
37 12 2
37 18 1
37 31 2
37 32 1
37 33 1
37 34 2
37 40 1
37 43 1
38 2 5
38 4 2
38 6 2
38 7 4
38 8 2
38 11 3
38 13 2
38 14 4
38 18 1
38 19 2
38 20 3
38 22 5
38 23 3
38 26 2
38 28 1
38 29 3
38 31 3
38 33 3
38 34 2
38 35 5
38 41 4
38 44 1
38 45 2
39 5 3
39 6 5
39 13 1
39 17 1
39 19 5
39 23 4
39 25 2
39 26 4
39 28 2
39 36 3
39 44 4
39 45 5
40 1 1
40 2 1
40 4 5
40 8 3
40 9 1
40 12 1
40 15 3
40 16 2
40 18 1
40 20 1
40 22 3
40 31 2
40 32 5
40 33 5
40 34 2
40 37 2
40 43 1
41 1 2
41 2 2
41 8 3
41 10 5
41 12 2
41 14 2
41 20 2
41 38 3
41 43 2
42 8 1
42 10 1
42 28 1
42 31 1
42 33 1
42 34 4
42 37 1
42 41 1
42 43 1
42 45 1
43 8 2
43 12 2
43 31 1
43 33 2
43 34 1
44 1 1
44 2 1
44 5 3
44 6 5
44 7 1
44 8 1
44 11 1
44 13 1
44 17 3
44 19 5
44 20 2
44 21 2
44 23 3
44 25 2
44 26 4
44 28 2
44 33 1
44 34 1
44 35 1
44 36 4
44 38 1
44 39 4
44 42 1
44 43 1
44 45 3
45 1 1
45 2 2
45 4 1
45 5 5
45 6 5
45 7 2
45 8 1
45 9 1
45 10 1
45 11 3
45 12 2
45 13 1
45 14 2
45 17 4
45 18 2
45 19 4
45 20 4
45 21 3
45 22 1
45 23 3
45 25 4
45 26 5
45 27 2
45 28 3
45 29 3
45 31 3
45 33 1
45 34 1
45 35 1
45 36 5
45 38 2
45 42 1
45 44 4
46 1 3
46 3 4
46 8 1
46 9 3
46 12 5
46 22 1
46 32 2
46 33 2
46 34 2
46 37 1
46 43 1
<html>
<head>
<title>Delete nodes and edges</title>
<meta charset="utf-8" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
</head>
<style>
svg {
height: 500px;
width: 500px;
border: 1px solid gray;
}
</style>
<body>
<div id="viz">
<svg>
</svg>
</div>
</body>
<footer>
<script>
d3.csv("firm.csv",function(error,data) {createNetwork(data)});
function createNetwork(edgelist) {
var nodeHash = {};
var nodes = [];
var edges = [];
edgelist.forEach(function (edge) {
if (!nodeHash[edge.source]) {
nodeHash[edge.source] = {id: edge.source, label: edge.source};
nodes.push(nodeHash[edge.source]);
}
if (!nodeHash[edge.target]) {
nodeHash[edge.target] = {id: edge.target, label: edge.target};
nodes.push(nodeHash[edge.target]);
}
if (edge.weight >= 5) {
edges.push({id: nodeHash[edge.source].id + "-" + nodeHash[edge.target].id, source: nodeHash[edge.source], target: nodeHash[edge.target], weight: edge.weight});
}
});
createForceNetwork(nodes, edges);
}
function createForceNetwork(nodes, edges) {
//create a network from an edgelist
//Highlight edges, delete nodes and edges
var force = d3.layout.force().nodes(nodes).links(edges)
.size([500,500])
.charge(function (d) {return Math.min(-100, d.weight * -50)})
.on("tick", updateNetwork);
var edgeEnter = d3.select("svg").selectAll("g.edge")
.data(edges, function (d) {return d.id})
.enter()
.append("g")
.attr("class", "edge");
edgeEnter
.append("line")
.attr("class", "highlight")
.style("stroke-width", "8px")
.style("stroke", "#66CCCC")
.style("opacity", 0)
.on("dblclick", deleteEdge)
.on("mouseover", edgeOver)
.on("mouseout", edgeOut);
edgeEnter
.append("line")
.style("stroke-width", "1px")
.style("stroke", "black")
.style("pointer-events", "none");
var nodeEnter = d3.select("svg").selectAll("g.node")
.data(nodes, function (d) {return d.id})
.enter()
.append("g")
.attr("class", "node")
.on("dblclick", deleteNode)
.on("mouseover", nodeOver)
.on("mouseout", nodeOut)
.call(force.drag());
nodeEnter.append("circle")
.attr("r", 5)
.style("fill", "#CC9999")
.style("stroke", "black")
.style("stroke-width", "1px")
nodeEnter.append("text")
.style("text-anchor", "middle")
.attr("y", 2)
.style("stroke-width", "1px")
.style("stroke-opacity", 0.75)
.style("stroke", "white")
.style("font-size", "8px")
.text(function (d) {return d.id})
.style("pointer-events", "none")
nodeEnter.append("text")
.style("text-anchor", "middle")
.attr("y", 2)
.style("font-size", "8px")
.text(function (d) {return d.id})
.style("pointer-events", "none")
force.start();
function nodeOver() {
d3.select(this).select("circle")
.style("fill", "#66CCCC")
.style("stroke", "#66CCCC")
.style("stroke-width", "3px");
}
function nodeOut() {
d3.selectAll("circle")
.style("fill", "#CC9999")
.style("stroke", "black")
.style("stroke-width", "1px");
}
function deleteNode(d) {
var currentNodes = d3.selectAll("g.node").data();
var currentEdges = d3.selectAll("g.edge").data();
var filteredNodes = currentNodes.filter(function (p) {return p !== d});
var filteredEdges = currentEdges.filter(function (p) {return p.source !== d && p.target !== d});
force.stop();
force.nodes(filteredNodes);
force.links(filteredEdges);
d3.selectAll("g.node").data(filteredNodes, function (d) {return d.id})
.exit()
.transition()
.duration(500)
.style("opacity", 0)
.remove();
d3.selectAll("g.edge").data(filteredEdges, function (d) {return d.id})
.exit()
.transition()
.duration(500)
.style("opacity", 0)
.remove();
force.start();
}
function deleteEdge(d) {
var currentEdges = d3.selectAll("g.edge").data();
var filteredEdges = currentEdges.filter(function (p) {return p !== d});
force.stop();
force.links(filteredEdges);
d3.selectAll("g.edge").data(filteredEdges, function (d) {return d.id})
.exit()
.transition()
.duration(500)
.style("opacity", 0)
.remove();
force.start();
}
function edgeOver(d) {
d3.select(this).style("opacity", 0.75);
}
function edgeOut() {
d3.selectAll("line.highlight").style("opacity", 0);
}
function updateNetwork() {
d3.select("svg").selectAll("line")
.attr("x1", function (d) {return d.source.x})
.attr("y1", function (d) {return d.source.y})
.attr("x2", function (d) {return d.target.x})
.attr("y2", function (d) {return d.target.y});
d3.select("svg").selectAll("g.node")
.attr("transform", function (d) {return "translate(" + d.x + "," + d.y + ")"});
d3.select("svg").selectAll("g.node > circle")
.attr("r", function (d) {return Math.max(3, d.weight)});
}
}
</script>
</footer>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment