Skip to content

Instantly share code, notes, and snippets.

@anthonyjclark
Last active October 11, 2017 22:08
Show Gist options
  • Save anthonyjclark/5b8135cbcc0a9ae886fc16b91d1bb63d to your computer and use it in GitHub Desktop.
Save anthonyjclark/5b8135cbcc0a9ae886fc16b91d1bb63d to your computer and use it in GitHub Desktop.
Generating random directed graphs
<!doctype html>
<head>
<title>Generating Directed Graphs</title>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<!-- <script src="https://d3js.org/d3.v4.min.js"></script> -->
<body>
<script type="text/javascript">
// Width and height of the SVG element
var width = 1000;
var height = 800;
// Graph element parameters
var radius = 15;
var linkDistance = 100;
// Graph data
var dataset = {
nodes: [
{name: "A"}, {name: "B"}, {name: "C"}, {name: "D"}, {name: "E"},
{name: "F"}, {name: "G"}, {name: "H"}, {name: "I"}, {name: "J"}
],
edges: [
{source: 0, target: 1}, {source: 0, target: 2}, {source: 0, target: 3}, {source: 0, target: 4},
{source: 1, target: 5},
{source: 2, target: 5}, {source: 2, target: 5},
{source: 3, target: 4},
{source: 5, target: 8}, {source: 5, target: 9},
{source: 6, target: 7},
{source: 7, target: 8},
{source: 8, target: 9}
]
};
// Create the SVG element
var svg = d3.select("body")
.append("svg")
.attr({"width": width, "height": height});
// Create the force layout and add the nodes and edges
var force = d3.layout.force()
.nodes(dataset.nodes)
.links(dataset.edges)
.size([width, height])
.linkDistance([linkDistance])
.charge([-500])
.theta(0.1)
.gravity(0.05)
.start();
// Style the edges (and add arrowheads)
var edges = svg.selectAll("line")
.data(dataset.edges)
.enter()
.append("line")
.attr("id", function(d, i) { return 'edge' + i; })
.attr("marker-end", "url(#arrowhead)")
.style("stroke", "#ccc")
.style("pointer-events", "none");
// Style the nodes
var colors = d3.scale.category10();
var nodes = svg.selectAll("circle")
.data(dataset.nodes)
.enter()
.append("circle")
.attr({"r": radius})
.style("fill", function(d, i) { return colors(i); })
.call(force.drag)
// Add text to each node
var nodelabels = svg.selectAll(".nodelabel")
.data(dataset.nodes)
.enter()
.append("text")
.attr({
"x": function(d) { return d.x; },
"y": function(d) { return d.y; },
"font-family": "monospace",
"class": "nodelabel",
"stroke": "black"})
.text(function(d) { return d.name; });
//
var edgepaths = svg.selectAll(".edgepath")
.data(dataset.edges)
.enter()
.append("path")
.attr({
"d": function(d) {
return 'M ' + d.source.x + ' ' + d.source.y + ' L ' + d.target.x + ' ' + d.target.y;
},
"class": "edgepath",
"fill-opacity": 0,
"stroke-opacity": 0,
"fill": "blue",
"stroke": "red",
"id": function(d, i) { return "edgepath" + i; }})
.style("pointer-events", "none");
// Add label class to each edge
var edgelabels = svg.selectAll(".edgelabel")
.data(dataset.edges)
.enter()
.append("text")
.style("pointer-events", "none")
.attr({
"class": "edgelabel",
"id": function(d, i) { return "edgelabel" + i; },
"dx": 80,
"dy": 0,
"font-size": 10,
"fill": "#aaa"});
// Add label to each edge
// edgelabels.append('textPath')
// .attr("xlink:href", function(d, i) { return "#edgepath" + i; })
// .style("pointer-events", "none")
// .text(function(d, i) { return "label " + i; });
//
svg.append("defs").append("marker")
.attr({
"id": "arrowhead",
"viewBox": "-0 -5 10 10",
"refX": 25,
"refY": 0,
//'markerUnits':'strokeWidth',
"orient": "auto",
"markerWidth": 10,
"markerHeight": 10,
"xoverflow": "visible"})
.append("svg:path")
.attr("d", "M 0,-5 L 10 ,0 L 0,5")
.attr("fill", "#ccc")
.attr("stroke","#ccc");
//
force.on("tick", function() {
edges.attr({
"x1": function(d) { return d.source.x; },
"y1": function(d) { return d.source.y; },
"x2": function(d) { return d.target.x; },
"y2": function(d) { return d.target.y; }
});
nodes.attr({
"cx": function(d) { return d.x; },
"cy": function(d) { return d.y; }
});
nodelabels
.attr("x", function(d) { return d.x - 4; })
.attr("y", function(d) { return d.y + 4; });
edgepaths.attr("d", function(d) {
return "M " + d.source.x + " " + d.source.y + " L " + d.target.x + " " + d.target.y;
});
// edgelabels.attr("transform", function(d, i) {
// if (d.target.x < d.source.x) {
// bbox = this.getBBox();
// rx = bbox.x + bbox.width/2;
// ry = bbox.y + bbox.height/2;
// return "rotate(180 " + rx + " " + ry + ")";
// } else {
// return "rotate(0)";
// }
// });
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment