forked from emeeks's block: Networks - Graphs 2
xxxxxxxxxx
<html>
<head>
<title>Delete nodes and edges</title>
<meta charset="utf-8" />
<script src="https://d3js.org/d3.v3.min.js" type="text/JavaScript"></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(); //grab all data from DOM
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(); //important
force.nodes(filteredNodes); //reapply filtered nodes to force
force.links(filteredEdges);
d3.selectAll("g.node").data(filteredNodes, function (d) {return d.id})
.exit()
.transition()
.duration(500)
.style("opacity", 0)
.remove(); // remove no longer represented nodes
d3.selectAll("g.edge").data(filteredEdges, function (d) {return d.id})
.exit()
.transition()
.duration(500)
.style("opacity", 0)
.remove();
force.start(); // remove edges no longer represented
}
// delete edges that were connected to nodes
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(); // restart force
}
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>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js