From 9cb9407e1cc81b3be083a1f484a56ee56d90449f Mon Sep 17 00:00:00 2001 From: Raghu Rajagopalan Date: Thu, 31 Mar 2016 10:40:35 +0530 Subject: [PATCH] working but ugly --- dist/www/javascripts/lib/mermaid.js | 210 ++++++++++++----- src/diagrams/gitGraph/gitGraphAst.js | 2 +- src/diagrams/gitGraph/gitGraphRenderer.js | 269 +++++++++++++++------- testgitgraph.mm | 7 + 4 files changed, 343 insertions(+), 145 deletions(-) diff --git a/dist/www/javascripts/lib/mermaid.js b/dist/www/javascripts/lib/mermaid.js index 564d7b234..50334be3a 100644 --- a/dist/www/javascripts/lib/mermaid.js +++ b/dist/www/javascripts/lib/mermaid.js @@ -53543,7 +53543,7 @@ exports.clear = function () { }; exports.getBranchesAsObjArray = function () { return _.map(branches, function (v, k) { - return { "name": k, "commitid": v }; + return { "name": k, "commit": commits[v] }; }); }; exports.getBranches = function () { @@ -53575,13 +53575,100 @@ exports.getHead = function () { 'use strict'; var db = require('./gitGraphAst'); +var _ = require('lodash'); var gitGraphParser = require('./parser/gitGraph'); var d3 = require('../../d3'); var Logger = require('../../logger'); var log = new Logger.Log(); +var allCommitsDict = {}; exports.setConf = function (config) {}; +function svgCreateDefs(svg) { + svg.append("defs").append("circle").attr("id", "def-commit").attr("r", 15).attr("cx", 0).attr("cy", 0); + svg.select("defs").append("line").attr("id", "def-arrow-rl").attr("x1", 25).attr("y1", 0).attr("x2", -25).attr("y2", 0).attr("marker-end", "url(#triangle)"); +} +function svgAddArrowMarker(svg) { + svg.append("marker").attr({ + "id": "triangle", + "refX": "5", + "refY": "5", + "markerUnits": "strokeWidth", + "fill": "#666", + "markerWidth": "4", + "markerHeight": "3", + "orient": "auto", + "viewBox": "0,0,10,10" + }).append("svg:path").attr("d", "M 0 0 L 10 5 L 0 10 z"); +} + +function svgDrawLine(svg, points) { + + var lineGen = d3.svg.line().x(function (d) { + return d.x; + }).y(function (d) { + return d.y; + }).interpolate("linear"); + + svg.append("svg:path").attr("d", lineGen(points)).style("stroke", "grey").style("stroke-width", "2").style("fill", "none"); +} + +function svgDrawLineForCommits(svg, fromId, toId) { + log.debug("svgDrawLineForCommits: ", fromId, toId); + var fromBbox = svg.select("#node-" + fromId).node().getBBox(); + var toBbox = svg.select("#node-" + toId).node().getBBox(); + log.debug("svgDrawLineForCommits: ", fromBbox, toBbox); + svgDrawLine(svg, [{ "x": fromBbox.x, "y": fromBbox.y + fromBbox.height / 2 }, { "x": toBbox.x + toBbox.width, "y": toBbox.y + toBbox.height / 2 }]); +} +function renderCommitHistory(svg, commitid, branches, direction, branchNum) { + var commit; + branchNum = branchNum || 1; + if (_.isString(commitid)) { + do { + commit = allCommitsDict[commitid]; + log.debug("in renderCommitHistory", commit.id, commit.seq); + if (svg.select("#node-" + commitid).size() > 0) return; + svg.append("g").attr("class", "commit").attr("id", function () { + return "node-" + commit.id; + }).append("use").attr("transform", function () { + return "translate(" + (commit.seq * 100 + 50) + ", " + branchNum * 50 + ")"; + }).attr("xlink:href", "#def-commit").attr("fill", "yellow").attr("stroke", "grey").attr("stroke-width", "2"); + + if (commit.parent && commit.seq > 0) { + log.debug("drawing line: ", commit.id, commit.seq); + var parent = allCommitsDict[commit.parent] || allCommitsDict[commit.parent[0]]; + log.debug("parentid: ", parent.id); + var parentNode = svg.select("#node-" + parent.id); + log.debug("parent:", parentNode.size()); + //var parentNode = document.getElementById("node-"+parent.id); + //if (parentNode) { + //log.debug("parent ", parentNode); + //log.debug("parent BBox", parentNode.); + //} + var pathInfo = [{ x: commit.seq * 100 + 35, y: branchNum * 50 }, { x: parent.seq * 100 + 65, y: branchNum * 50 }]; + if (parentNode.node()) { + //var rect = parentNode.node().getBoundingClientRect() + //log.debug("parent BCR", rect); + var rect = parentNode.node().getBBox(); + log.debug("parent BBox", rect); + pathInfo[1].x = rect.x + rect.width; + pathInfo[1].y = rect.y + rect.height / 2; + } + svgDrawLine(svg, pathInfo); + } + commitid = commit.parent; + } while (commitid && allCommitsDict[commitid]); + } + + if (_.isArray(commitid)) { + log.debug("found merge commmit", commitid); + renderCommitHistory(svg, commitid[0], branches, direction, branchNum); + renderCommitHistory(svg, commitid[1], branches, direction, ++branchNum); + //confusing... commit should still refer to original commit. + // commitid has been modified as commitid = commit.parent; + svgDrawLineForCommits(svg, commit.id, commitid[1]); + } +} exports.draw = function (txt, id, ver) { try { var parser; @@ -53593,76 +53680,85 @@ exports.draw = function (txt, id, ver) { parser.parse(txt + "\n"); var direction = db.getDirection(); var commits = db.getCommitsArray(); - log.debug("# of commits: " + commits.length); - //log.debug("id: " + commits[0].id); - //log.debug(db.getCommits()); - //log.debug("length:", commits.length); - //log.debug("length:", Object.keys(db.getCommits()).length); - // Fetch the default direction, use TD if none was found + allCommitsDict = db.getCommits(); + var branches = db.getBranchesAsObjArray(); + var commit = _.maxBy(commits, 'seq'); var svg = d3.select('#' + id); - // - // - // - svg.append("marker").attr({ - "id": "triangle", - "refX": "5", - "refY": "5", - "markerUnits": "strokeWidth", - "fill": "#666", - "markerWidth": "4", - "markerHeight": "3", - "orient": "auto", - "viewBox": "0,0,10,10" - }).append("svg:path").attr("d", "M 0 0 L 10 5 L 0 10 z"); + svgAddArrowMarker(svg); + svgCreateDefs(svg); var count = commits.length; - var nodes = svg.selectAll("g.commit").data(commits).enter().append("g").attr("class", "commit").attr("id", function (d) { - return d.id; - }).attr("transform", function (d, i) { - if (direction == "TB" || direction == "BT") return "translate(50," + (50 + i * 100) + ")"; - if (direction == "LR") return "translate(" + (50 + (count - i) * 100) + ", 50)"; - }); - var lines = svg.selectAll("g.arrows").data(commits).enter().append("g").append("line").attr("transform", function (d, i) { - if (direction == "TB" || direction == "BT") return "translate(50," + (70 + i * 100) + ")"; - if (direction == "LR") return "translate(" + (70 + i * 100) + ", 50)"; - }).attr({ - "x1": direction == "LR" ? 60 : 0, - "y1": direction == "LR" ? 0 : 0, - "x2": direction == "LR" ? 0 : 0, - "y2": direction == "LR" ? 0 : 60 - }).attr("marker-end", "url(#triangle)").attr("stroke", "black").attr("stroke-width", "3"); - //g.append('text') // text label for the x axis - //.attr('x', 100) - //.attr('y', 40) - //.attr('class','version') - //.attr('font-size','32px') - //.style('text-anchor', 'middle') - //.text('mermaid raghu'+ ver); - - var circles = svg.selectAll("g.commit").append("circle").attr("r", 15).attr("fill", "yellow").attr("stroke", "grey"); - var textContainer = svg.selectAll("g.commit").append("g").attr("transform", function () { - if (direction == "LR") return "translate(-30, 35)"; - if (direction == "BT" || direction == "TB") return "translate(200, 0)"; - }).attr("class", "commit-label"); - textContainer.append("text").text(function (c) { - return c.id + "," + c.seq; - }); + renderCommitHistory(svg, commit.id, branches, direction); + /* + *var nodes = svg + * .selectAll("g.commit") + * .data(commits) + * .enter() + * .append("g") + * .attr("class", "commit") + * .attr("id", function (d) { + * return d.id; + * }) + * .attr("transform", function (d, i) { + * if (direction == "TB" || direction == "BT") + * return "translate(50," + (50 + i * 100) + ")"; + * if (direction == "LR") + * return "translate(" + (50 + (count -i) * 100) + ", 50)"; + * }); + */ /* - var box = exports.bounds.getBounds(); - var height = box.stopy-box.starty+2*conf.diagramMarginY; - var width = box.stopx-box.startx+2*conf.diagramMarginX;*/ + *var lines = svg.selectAll("g.arrows") + * .data(commits) + * .enter() + * .append("g") + * .append("line") + * .attr("transform", function(d, i) { + * if (direction == "TB" || direction == "BT") + * return "translate(50," + (70 + (i * 100)) + ")"; + * if (direction == "LR") + * return "translate(" + (70 + (i * 100)) + ", 50)"; + * }) + * .attr({ + * "x1": direction == "LR" ? 60:0, + * "y1": direction == "LR" ? 0:0, + * "x2": direction == "LR" ? 0:0, + * "y2": direction == "LR" ? 0:60 + * }) + * .attr("marker-end", "url(#triangle)") + * .attr("stroke", "black") + * .attr("stroke-width", "3") + */ + + /* + *var circles = svg.selectAll("g.commit") + * .append("circle") + * .attr("r", 15) + * .attr("fill", "yellow") + * .attr("stroke", "grey"); + *var textContainer = svg.selectAll("g.commit") + * .append("g") + * .attr("transform", function () { + * if (direction == "LR") return "translate(-30, 35)"; + * if (direction == "BT" || direction == "TB") return "translate(200, 0)"; + * }) + * .attr("class", "commit-label"); + *textContainer + * .append("text") + * .text(function (c) { + * return c.id + "," + c.seq; + * }); + */ svg.attr('height', 900); svg.attr('width', 1200); - //svg.attr('viewBox', '0 0 300 150'); } catch (e) { log.error("Error while rendering gitgraph"); log.error(e.message); } }; -},{"../../d3":109,"../../logger":131,"./gitGraphAst":124,"./parser/gitGraph":126}],126:[function(require,module,exports){ +},{"../../d3":109,"../../logger":131,"./gitGraphAst":124,"./parser/gitGraph":126,"lodash":106}],126:[function(require,module,exports){ (function (process){ /* parser generated by jison 0.4.17 */ /* diff --git a/src/diagrams/gitGraph/gitGraphAst.js b/src/diagrams/gitGraph/gitGraphAst.js index bf50de9bc..66f3a39df 100644 --- a/src/diagrams/gitGraph/gitGraphAst.js +++ b/src/diagrams/gitGraph/gitGraphAst.js @@ -163,7 +163,7 @@ exports.clear = function () { } exports.getBranchesAsObjArray = function() { return _.map(branches, function(v,k) { - return {"name": k, "commitid": v}; + return {"name": k, "commit": commits[v]}; }); } exports.getBranches = function() { return branches; } diff --git a/src/diagrams/gitGraph/gitGraphRenderer.js b/src/diagrams/gitGraph/gitGraphRenderer.js index e59fed746..d845df544 100644 --- a/src/diagrams/gitGraph/gitGraphRenderer.js +++ b/src/diagrams/gitGraph/gitGraphRenderer.js @@ -1,13 +1,132 @@ var db = require('./gitGraphAst'); +var _ = require('lodash'); var gitGraphParser = require('./parser/gitGraph'); var d3 = require('../../d3'); var Logger = require('../../logger'); var log = new Logger.Log(); +var allCommitsDict = {}; exports.setConf = function (config) { } +function svgCreateDefs(svg) { + svg.append("defs") + .append("circle") + .attr("id", "def-commit") + .attr("r", 15) + .attr("cx", 0) + .attr("cy", 0); + svg.select("defs") + .append("line") + .attr("id", "def-arrow-rl") + .attr("x1", 25) + .attr("y1", 0) + .attr("x2", -25) + .attr("y2", 0) + .attr("marker-end", "url(#triangle)"); +} +function svgAddArrowMarker(svg) { + svg.append("marker") + .attr({ + "id": "triangle", + "refX": "5", + "refY": "5", + "markerUnits": "strokeWidth", + "fill": "#666", + "markerWidth": "4", + "markerHeight": "3", + "orient": "auto", + "viewBox": "0,0,10,10" + }) + .append("svg:path") + .attr("d", "M 0 0 L 10 5 L 0 10 z"); +} + +function svgDrawLine(svg, points) { + + var lineGen = d3.svg.line() + .x(function(d) { return d.x }) + .y(function(d) {return d.y}) + .interpolate("linear"); + + svg + .append("svg:path") + .attr("d", lineGen(points)) + .style("stroke", "grey") + .style("stroke-width", "2") + .style("fill", "none"); +} + +function svgDrawLineForCommits(svg, fromId, toId) { + log.debug("svgDrawLineForCommits: ", fromId, toId); + var fromBbox = svg.select("#node-" + fromId).node().getBBox(); + var toBbox = svg.select("#node-" + toId).node().getBBox(); + log.debug("svgDrawLineForCommits: ", fromBbox, toBbox); + svgDrawLine(svg, [ + {"x": fromBbox.x, "y": fromBbox.y + fromBbox.height/2 }, + {"x": toBbox.x + toBbox.width, "y": toBbox.y + toBbox.height/2 } + ]); +} +function renderCommitHistory(svg, commitid, branches, direction, branchNum) { + var commit; + branchNum = branchNum || 1; + if (_.isString(commitid)) { + do { + commit = allCommitsDict[commitid]; + log.debug("in renderCommitHistory", commit.id, commit.seq); + if (svg.select("#node-" + commitid).size() > 0) return; + svg + .append("g") + .attr("class", "commit") + .attr("id", function() { return "node-" + commit.id; }) + .append("use") + .attr("transform", function() { + return "translate(" + (commit.seq * 100 + 50 )+ ", " + (branchNum * 50)+")"; + }) + .attr("xlink:href", "#def-commit") + .attr("fill", "yellow") + .attr("stroke", "grey") + .attr("stroke-width", "2"); + + if (commit.parent && commit.seq > 0) { + log.debug("drawing line: ", commit.id, commit.seq); + var parent = allCommitsDict[commit.parent] || allCommitsDict[commit.parent[0]]; + log.debug("parentid: ", parent.id); + var parentNode = svg.select("#node-" + parent.id); + log.debug("parent:", parentNode.size()); + //var parentNode = document.getElementById("node-"+parent.id); + //if (parentNode) { + //log.debug("parent ", parentNode); + //log.debug("parent BBox", parentNode.); + //} + var pathInfo = [ + {x: commit.seq *100 + 35, y: branchNum* 50}, + {x: parent.seq *100 + 65, y: branchNum* 50} + ]; + if (parentNode.node()) { + //var rect = parentNode.node().getBoundingClientRect() + //log.debug("parent BCR", rect); + var rect = parentNode.node().getBBox(); + log.debug("parent BBox", rect); + pathInfo[1].x = rect.x + rect.width; + pathInfo[1].y = rect.y + rect.height/2; + } + svgDrawLine(svg, pathInfo); + } + commitid = commit.parent + } while (commitid && allCommitsDict[commitid]); + } + + if (_.isArray(commitid)) { + log.debug("found merge commmit", commitid); + renderCommitHistory(svg, commitid[0], branches, direction, branchNum); + renderCommitHistory(svg, commitid[1], branches, direction, ++branchNum); + //confusing... commit should still refer to original commit. + // commitid has been modified as commitid = commit.parent; + svgDrawLineForCommits(svg, commit.id, commitid[1]); + } +} exports.draw = function (txt, id, ver) { try { var parser; @@ -19,102 +138,78 @@ exports.draw = function (txt, id, ver) { parser.parse(txt + "\n"); var direction = db.getDirection(); var commits = db.getCommitsArray(); - log.debug("# of commits: " + commits.length); - //log.debug("id: " + commits[0].id); - //log.debug(db.getCommits()); - //log.debug("length:", commits.length); - //log.debug("length:", Object.keys(db.getCommits()).length); - // Fetch the default direction, use TD if none was found + allCommitsDict = db.getCommits(); + var branches = db.getBranchesAsObjArray(); + var commit = _.maxBy(commits, 'seq'); var svg = d3.select('#' + id); - // - // - // - svg.append("marker") - .attr({ - "id": "triangle", - "refX": "5", - "refY": "5", - "markerUnits": "strokeWidth", - "fill": "#666", - "markerWidth": "4", - "markerHeight": "3", - "orient": "auto", - "viewBox": "0,0,10,10" - }) - .append("svg:path") - .attr("d", "M 0 0 L 10 5 L 0 10 z"); + svgAddArrowMarker(svg); + svgCreateDefs(svg); var count = commits.length; - var nodes = svg - .selectAll("g.commit") - .data(commits) - .enter() - .append("g") - .attr("class", "commit") - .attr("id", function (d) { - return d.id; - }) - .attr("transform", function (d, i) { - if (direction == "TB" || direction == "BT") - return "translate(50," + (50 + i * 100) + ")"; - if (direction == "LR") - return "translate(" + (50 + (count -i) * 100) + ", 50)"; - }); - var lines = svg.selectAll("g.arrows") - .data(commits) - .enter() - .append("g") - .append("line") - .attr("transform", function(d, i) { - if (direction == "TB" || direction == "BT") - return "translate(50," + (70 + (i * 100)) + ")"; - if (direction == "LR") - return "translate(" + (70 + (i * 100)) + ", 50)"; - }) - .attr({ - "x1": direction == "LR" ? 60:0, - "y1": direction == "LR" ? 0:0, - "x2": direction == "LR" ? 0:0, - "y2": direction == "LR" ? 0:60 - }) - .attr("marker-end", "url(#triangle)") - .attr("stroke", "black") - .attr("stroke-width", "3") - //g.append('text') // text label for the x axis - //.attr('x', 100) - //.attr('y', 40) - //.attr('class','version') - //.attr('font-size','32px') - //.style('text-anchor', 'middle') - //.text('mermaid raghu'+ ver); - - var circles = svg.selectAll("g.commit") - .append("circle") - .attr("r", 15) - .attr("fill", "yellow") - .attr("stroke", "grey"); - var textContainer = svg.selectAll("g.commit") - .append("g") - .attr("transform", function () { - if (direction == "LR") return "translate(-30, 35)"; - if (direction == "BT" || direction == "TB") return "translate(200, 0)"; - }) - .attr("class", "commit-label"); - textContainer - .append("text") - .text(function (c) { - return c.id + "," + c.seq; - }); + renderCommitHistory(svg, commit.id, branches, direction); + /* + *var nodes = svg + * .selectAll("g.commit") + * .data(commits) + * .enter() + * .append("g") + * .attr("class", "commit") + * .attr("id", function (d) { + * return d.id; + * }) + * .attr("transform", function (d, i) { + * if (direction == "TB" || direction == "BT") + * return "translate(50," + (50 + i * 100) + ")"; + * if (direction == "LR") + * return "translate(" + (50 + (count -i) * 100) + ", 50)"; + * }); + */ /* - var box = exports.bounds.getBounds(); + *var lines = svg.selectAll("g.arrows") + * .data(commits) + * .enter() + * .append("g") + * .append("line") + * .attr("transform", function(d, i) { + * if (direction == "TB" || direction == "BT") + * return "translate(50," + (70 + (i * 100)) + ")"; + * if (direction == "LR") + * return "translate(" + (70 + (i * 100)) + ", 50)"; + * }) + * .attr({ + * "x1": direction == "LR" ? 60:0, + * "y1": direction == "LR" ? 0:0, + * "x2": direction == "LR" ? 0:0, + * "y2": direction == "LR" ? 0:60 + * }) + * .attr("marker-end", "url(#triangle)") + * .attr("stroke", "black") + * .attr("stroke-width", "3") + */ - var height = box.stopy-box.starty+2*conf.diagramMarginY; - var width = box.stopx-box.startx+2*conf.diagramMarginX;*/ + /* + *var circles = svg.selectAll("g.commit") + * .append("circle") + * .attr("r", 15) + * .attr("fill", "yellow") + * .attr("stroke", "grey"); + *var textContainer = svg.selectAll("g.commit") + * .append("g") + * .attr("transform", function () { + * if (direction == "LR") return "translate(-30, 35)"; + * if (direction == "BT" || direction == "TB") return "translate(200, 0)"; + * }) + * .attr("class", "commit-label"); + *textContainer + * .append("text") + * .text(function (c) { + * return c.id + "," + c.seq; + * }); + */ svg.attr('height', 900); svg.attr('width', 1200); - //svg.attr('viewBox', '0 0 300 150'); } catch (e) { log.error("Error while rendering gitgraph"); log.error(e.message); diff --git a/testgitgraph.mm b/testgitgraph.mm index 611837d2e..0ea76dd50 100644 --- a/testgitgraph.mm +++ b/testgitgraph.mm @@ -1,12 +1,19 @@ gitGraph : + commit commit branch newbranch checkout newbranch commit commit + branch other + checkout other + commit + commit + commit checkout master commit merge newbranch commit checkout newbranch merge master + merge other