Mercurial > hg > soundsoftware-site
diff public/javascripts/revision_graph.js @ 1115:433d4f72a19b redmine-2.2
Update to Redmine SVN revision 11137 on 2.2-stable branch
author | Chris Cannam |
---|---|
date | Mon, 07 Jan 2013 12:01:42 +0000 |
parents | cbb26bc654de |
children | 622f24f53b42 |
line wrap: on
line diff
--- a/public/javascripts/revision_graph.js Wed Jun 27 14:54:18 2012 +0100 +++ b/public/javascripts/revision_graph.js Mon Jan 07 12:01:42 2013 +0000 @@ -1,173 +1,94 @@ -var commits = chunk.commits, - comms = {}, - pixelsX = [], - pixelsY = [], - mmax = Math.max, - max_rdmid = 0, - max_space = 0, - parents = {}; -for (var i = 0, ii = commits.length; i < ii; i++) { - for (var j = 0, jj = commits[i].parents.length; j < jj; j++) { - parents[commits[i].parents[j][0]] = true; +var revisionGraph = null; + +function drawRevisionGraph(holder, commits_hash, graph_space) { + var XSTEP = 20, + CIRCLE_INROW_OFFSET = 10; + var commits_by_scmid = commits_hash, + commits = $.map(commits_by_scmid, function(val,i){return val;}); + var max_rdmid = commits.length - 1; + var commit_table_rows = $('table.changesets tr.changeset'); + + // create graph + if(revisionGraph != null) + revisionGraph.clear(); + else + revisionGraph = Raphael(holder); + + var top = revisionGraph.set(); + // init dimensions + var graph_x_offset = commit_table_rows.first().find('td').first().position().left - $(holder).position().left, + graph_y_offset = $(holder).position().top, + graph_right_side = graph_x_offset + (graph_space + 1) * XSTEP, + graph_bottom = commit_table_rows.last().position().top + commit_table_rows.last().height() - graph_y_offset; + + revisionGraph.setSize(graph_right_side, graph_bottom); + + // init colors + var colors = []; + Raphael.getColor.reset(); + for (var k = 0; k <= graph_space; k++) { + colors.push(Raphael.getColor()); } - max_rdmid = Math.max(max_rdmid, commits[i].rdmid); - max_space = Math.max(max_space, commits[i].space); -} -for (i = 0; i < ii; i++) { - if (commits[i].scmid in parents) { - commits[i].isParent = true; - } - comms[commits[i].scmid] = commits[i]; -} -var colors = ["#000"]; -for (var k = 0; k < max_space; k++) { - colors.push(Raphael.getColor()); -} + var parent_commit; + var x, y, parent_x, parent_y; + var path, title; + var revision_dot_overlay; + $.each(commits, function(index, commit) { + if (!commit.hasOwnProperty("space")) + commit.space = 0; -function branchGraph(holder) { - var xstep = 20; - var ystep = $$('tr.changeset')[0].getHeight(); - var ch, cw; - cw = max_space * xstep + xstep; - ch = max_rdmid * ystep + ystep; - var r = Raphael("holder", cw, ch), - top = r.set(); - var cuday = 0, cumonth = ""; + y = commit_table_rows.eq(max_rdmid - commit.rdmid).position().top - graph_y_offset + CIRCLE_INROW_OFFSET; + x = graph_x_offset + XSTEP / 2 + XSTEP * commit.space; + revisionGraph.circle(x, y, 3) + .attr({ + fill: colors[commit.space], + stroke: 'none', + }).toFront(); + // paths to parents + $.each(commit.parent_scmids, function(index, parent_scmid) { + parent_commit = commits_by_scmid[parent_scmid]; + if (parent_commit) { + if (!parent_commit.hasOwnProperty("space")) + parent_commit.space = 0; - for (i = 0; i < ii; i++) { - var x, y; - y = 10 + ystep *(max_rdmid - commits[i].rdmid); - x = 3 + xstep * commits[i].space; - var stroke = "none"; - r.circle(x, y, 3).attr({fill: colors[commits[i].space], stroke: stroke}); - if (commits[i].refs != null && commits[i].refs != "") { - var longrefs = commits[i].refs - var shortrefs = commits[i].refs; - if (shortrefs.length > 15) { - shortrefs = shortrefs.substr(0,13) + "..."; - } - var t = r.text(x+5,y+5,shortrefs).attr({font: "12px Fontin-Sans, Arial", fill: "#666", - title: longrefs, cursor: "pointer", rotation: "0"}); - - var textbox = t.getBBox(); - t.translate(textbox.width / 2, textbox.height / -3); - } - for (var j = 0, jj = commits[i].parents.length; j < jj; j++) { - var c = comms[commits[i].parents[j][0]]; - var p,arrow; - if (c) { - var cy, cx; - cy = 10 + ystep * (max_rdmid - c.rdmid), - cx = 3 + xstep * c.space; - - if (c.space == commits[i].space) { - p = r.path("M" + x + "," + y + "L" + cx + "," + cy); + parent_y = commit_table_rows.eq(max_rdmid - parent_commit.rdmid).position().top - graph_y_offset + CIRCLE_INROW_OFFSET; + parent_x = graph_x_offset + XSTEP / 2 + XSTEP * parent_commit.space; + if (parent_commit.space == commit.space) { + // vertical path + path = revisionGraph.path([ + 'M', x, y, + 'V', parent_y]); } else { - p = r.path(["M", x, y, "C",x,y,x, y+(cy-y)/2,x+(cx-x)/2, y+(cy-y)/2, - "C", x+(cx-x)/2,y+(cy-y)/2, cx, cy-(cy-y)/2, cx, cy]); + // path to a commit in a different branch (Bezier curve) + path = revisionGraph.path([ + 'M', x, y, + 'C', x, y, x, y + (parent_y - y) / 2, x + (parent_x - x) / 2, y + (parent_y - y) / 2, + 'C', x + (parent_x - x) / 2, y + (parent_y - y) / 2, parent_x, parent_y-(parent_y-y)/2, parent_x, parent_y]); } } else { - p = r.path("M" + x + "," + y + "L" + x + "," + ch); - } - p.attr({stroke: colors[commits[i].space], "stroke-width": 1.5}); - } - (function (c, x, y) { - top.push(r.circle(x, y, 10).attr({fill: "#000", opacity: 0, - cursor: "pointer", href: commits[i].href}) - .hover(function () {}, function () {}) - ); - }(commits[i], x, y)); - } + // vertical path ending at the bottom of the revisionGraph + path = revisionGraph.path([ + 'M', x, y, + 'V', graph_bottom]); + } + path.attr({stroke: colors[commit.space], "stroke-width": 1.5}).toBack(); + }); + revision_dot_overlay = revisionGraph.circle(x, y, 10); + revision_dot_overlay + .attr({ + fill: '#000', + opacity: 0, + cursor: 'pointer', + href: commit.href + }); + + if(commit.refs != null && commit.refs.length > 0) { + title = document.createElementNS(revisionGraph.canvas.namespaceURI, 'title'); + title.appendChild(document.createTextNode(commit.refs)); + revision_dot_overlay.node.appendChild(title); + } + top.push(revision_dot_overlay); + }); top.toFront(); - var hw = holder.offsetWidth, - hh = holder.offsetHeight, - drag, - dragger = function (e) { - if (drag) { - e = e || window.event; - holder.scrollLeft = drag.sl - (e.clientX - drag.x); - holder.scrollTop = drag.st - (e.clientY - drag.y); - } - }; - holder.onmousedown = function (e) { - e = e || window.event; - drag = {x: e.clientX, y: e.clientY, st: holder.scrollTop, sl: holder.scrollLeft}; - document.onmousemove = dragger; - }; - document.onmouseup = function () { - drag = false; - document.onmousemove = null; - }; - holder.scrollLeft = cw; }; - -Raphael.fn.popupit = function (x, y, set, dir, size) { - dir = dir == null ? 2 : dir; - size = size || 5; - x = Math.round(x); - y = Math.round(y); - var bb = set.getBBox(), - w = Math.round(bb.width / 2), - h = Math.round(bb.height / 2), - dx = [0, w + size * 2, 0, -w - size * 2], - dy = [-h * 2 - size * 3, -h - size, 0, -h - size], - p = ["M", x - dx[dir], y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0), - 0, "a", size, size, 0, 0, 1, -size, -size, - "l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, - -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size, - "l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), - 0, "a", size, size, 0, 0, 1, size, size, - "l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, - mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size, - "l", -mmax(w - size, 0), 0, "z"].join(","), - xy = [{x: x, y: y + size * 2 + h}, - {x: x - size * 2 - w, y: y}, - {x: x, y: y - size * 2 - h}, - {x: x + size * 2 + w, y: y}] - [dir]; - set.translate(xy.x - w - bb.x, xy.y - h - bb.y); - return this.set(this.path(p).attr({fill: "#234", stroke: "none"}) - .insertBefore(set.node ? set : set[0]), set); -}; - -Raphael.fn.popup = function (x, y, text, dir, size) { - dir = dir == null ? 2 : dir > 3 ? 3 : dir; - size = size || 5; - text = text || "$9.99"; - var res = this.set(), - d = 3; - res.push(this.path().attr({fill: "#000", stroke: "#000"})); - res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff", "font-family": "Helvetica, Arial"})); - res.update = function (X, Y, withAnimation) { - X = X || x; - Y = Y || y; - var bb = this[1].getBBox(), - w = bb.width / 2, - h = bb.height / 2, - dx = [0, w + size * 2, 0, -w - size * 2], - dy = [-h * 2 - size * 3, -h - size, 0, -h - size], - p = ["M", X - dx[dir], Y - dy[dir], "l", -size, (dir == 2) * -size, - -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size, - "l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, - 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size, - "l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), - 0, "a", size, size, 0, 0, 1, size, size, - "l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, - mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size, - "l", -mmax(w - size, 0), 0, "z"].join(","), - xy = [{x: X, y: Y + size * 2 + h}, - {x: X - size * 2 - w, y: Y}, - {x: X, y: Y - size * 2 - h}, - {x: X + size * 2 + w, y: Y}] - [dir]; - xy.path = p; - if (withAnimation) { - this.animate(xy, 500, ">"); - } else { - this.attr(xy); - } - return this; - }; - return res.update(x, y); -};