aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--html/git-deps.css12
-rw-r--r--html/git-deps.html21
-rw-r--r--html/js/git-deps-graph.js100
3 files changed, 133 insertions, 0 deletions
diff --git a/html/git-deps.css b/html/git-deps.css
new file mode 100644
index 0000000..307c70c
--- /dev/null
+++ b/html/git-deps.css
@@ -0,0 +1,12 @@
+.node {
+ stroke: #fff;
+ stroke-width: 1.5px;
+}
+
+.link {
+ fill: none;
+ stroke: #000;
+ stroke-width: 1.5px;
+ opacity: 0.4;
+ marker-end: url(#end-arrow);
+}
diff --git a/html/git-deps.html b/html/git-deps.html
new file mode 100644
index 0000000..1051e06
--- /dev/null
+++ b/html/git-deps.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+
+<html lang="en">
+<head>
+ <meta charset="utf-8" />
+ <title>git commit dependency graph</title>
+
+ <script language="javascript" type="text/javascript" src="js/jquery-2.1.3.min.js"></script>
+ <script language="javascript" type="text/javascript" src="js/d3.min.js"></script>
+ <script language="javascript" type="text/javascript" src="js/cola.v3.min.js"></script>
+ <script language="javascript" type="text/javascript" src="js/git-deps-graph.js"></script>
+
+ <link rel="stylesheet" type="text/css" href="git-deps.css" />
+</head>
+
+<body>
+ <h1>git commit dependency graph</h1>
+
+ <p>Some text probably goes here.</p>
+</body>
+</html>
diff --git a/html/js/git-deps-graph.js b/html/js/git-deps-graph.js
new file mode 100644
index 0000000..5deee7d
--- /dev/null
+++ b/html/js/git-deps-graph.js
@@ -0,0 +1,100 @@
+var width = 960,
+ height = 500;
+
+var color = d3.scale.category20();
+
+var d3cola = cola.d3adaptor()
+ .avoidOverlaps(true)
+ .size([width, height]);
+
+jQuery(function () {
+ draw_graph();
+});
+
+function draw_graph () {
+ var svg = d3.select("body").append("svg")
+ .attr("width", width)
+ .attr("height", height);
+
+ d3.json("test.json", function (error, graph) {
+ var nodeRadius = 5;
+
+ graph.nodes.forEach(function (v) { v.height = v.width = 2 * nodeRadius; });
+
+ d3cola
+ .nodes(graph.nodes)
+ .links(graph.links)
+ .flowLayout("y", 30)
+ .symmetricDiffLinkLengths(6)
+ .start(10,20,20);
+
+ // define arrow markers for graph links
+ svg.append('svg:defs').append('svg:marker')
+ .attr('id', 'end-arrow')
+ .attr('viewBox', '0 -5 10 10')
+ .attr('refX', 6)
+ .attr('markerWidth', 3)
+ .attr('markerHeight', 3)
+ .attr('orient', 'auto')
+ .append('svg:path')
+ .attr('d', 'M0,-5L10,0L0,5')
+ .attr('fill', '#000');
+
+ var path = svg.selectAll(".link")
+ .data(graph.links)
+ .enter().append('svg:path')
+ .attr('class', 'link');
+
+ var node = svg.selectAll(".node")
+ .data(graph.nodes)
+ .enter().append("circle")
+ .attr("class", "node")
+ .attr("r", nodeRadius)
+ .style("fill", function (d) { return color(d.group); })
+ .call(d3cola.drag);
+
+ node.append("title")
+ .text(function (d) { return d.name; });
+
+ d3cola.on("tick", function () {
+ path.each(function (d) {
+ if (isIE()) this.parentNode.insertBefore(this, this);
+ });
+ // draw directed edges with proper padding from node centers
+ path.attr('d', function (d) {
+ var deltaX = d.target.x - d.source.x,
+ deltaY = d.target.y - d.source.y,
+ dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY),
+ normX = deltaX / dist,
+ normY = deltaY / dist,
+ sourcePadding = nodeRadius,
+ targetPadding = nodeRadius + 2,
+ sourceX = d.source.x + (sourcePadding * normX),
+ sourceY = d.source.y + (sourcePadding * normY),
+ targetX = d.target.x - (targetPadding * normX),
+ targetY = d.target.y - (targetPadding * normY);
+ return 'M' + sourceX + ',' + sourceY + 'L' + targetX + ',' + targetY;
+ });
+
+ node.attr("cx", function (d) { return d.x; })
+ .attr("cy", function (d) { return d.y; });
+ });
+ // turn on overlap avoidance after first convergence
+ //cola.on("end", function () {
+ // if (!cola.avoidOverlaps()) {
+ // graph.nodes.forEach(function (v) {
+ // v.width = v.height = 10;
+ // });
+ // cola.avoidOverlaps(true);
+ // cola.start();
+ // }
+ //});
+ });
+}
+
+function isIE() {
+ return (navigator.appName == 'Microsoft Internet Explorer') ||
+ ((navigator.appName == 'Netscape') &&
+ (new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent)
+ != null));
+}