mirror of
https://github.com/redmine/redmine.git
synced 2026-01-14 19:42:57 +01:00
The original curve design made it difficult to identify which commits were connected, when several commits existed between the connected ones on the branches. Now, connections between commits on different branches are more easily recognizable in typical scenarios. The new curves connect from the left or right side to commit that already have vertical connections, and from the top or bottom to the last or first commit on a branch, respectively. <pre> | | | | | * /-* * * *-\ | | | | | | | *-/ * *-/ * * | | | | | </pre> Patch by Leonid Murin (user:murin). git-svn-id: https://svn.redmine.org/redmine/trunk@24258 e93f8b46-1217-0410-a6f0-8f06a7374b81
139 lines
5.2 KiB
JavaScript
139 lines
5.2 KiB
JavaScript
/**
|
|
* Redmine - project management software
|
|
* Copyright (C) 2006- Jean-Philippe Lang
|
|
* This code is released under the GNU General Public License.
|
|
*/
|
|
|
|
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;
|
|
|
|
|
|
var yForRow = function (index, commit) {
|
|
var row = commit_table_rows.eq(index);
|
|
|
|
switch (row.find("td:first").css("vertical-align")) {
|
|
case "middle":
|
|
return row.position().top + (row.height() / 2) - graph_y_offset;
|
|
default:
|
|
return row.position().top + - graph_y_offset + CIRCLE_INROW_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());
|
|
}
|
|
|
|
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;
|
|
|
|
y = yForRow(max_rdmid - commit.rdmid);
|
|
x = graph_x_offset + XSTEP / 2 + XSTEP * commit.space;
|
|
revisionGraph.circle(x, y, 3)
|
|
.attr({
|
|
fill: colors[commit.space],
|
|
stroke: 'none'
|
|
}).toFront();
|
|
|
|
// check for parents in the same column
|
|
let noVerticalParents = true;
|
|
$.each(commit.parent_scmids, function (index, parentScmid) {
|
|
parent_commit = commits_by_scmid[parentScmid];
|
|
if (parent_commit) {
|
|
if (!parent_commit.hasOwnProperty("space"))
|
|
parent_commit.space = 0;
|
|
|
|
// has parent in the same column on this page
|
|
if (parent_commit.space === commit.space)
|
|
noVerticalParents = false;
|
|
} else {
|
|
// has parent in the same column on the other page
|
|
noVerticalParents = false;
|
|
}
|
|
});
|
|
|
|
// paths to parents
|
|
$.each(commit.parent_scmids, function(index, parent_scmid) {
|
|
parent_commit = commits_by_scmid[parent_scmid];
|
|
if (parent_commit) {
|
|
parent_y = yForRow(max_rdmid - parent_commit.rdmid);
|
|
parent_x = graph_x_offset + XSTEP / 2 + XSTEP * parent_commit.space;
|
|
const controlPointDelta = (parent_y - y) / 8;
|
|
|
|
if (parent_commit.space === commit.space) {
|
|
// vertical path
|
|
path = revisionGraph.path([
|
|
'M', x, y,
|
|
'V', parent_y]);
|
|
} else if (noVerticalParents) {
|
|
// branch start (Bezier curve)
|
|
path = revisionGraph.path([
|
|
'M', x, y,
|
|
'C', x, y + controlPointDelta, x, parent_y - controlPointDelta, parent_x, parent_y]);
|
|
} else if (!parent_commit.hasOwnProperty('vertical_children')) {
|
|
// branch end (Bezier curve)
|
|
path = revisionGraph.path([
|
|
'M', x, y,
|
|
'C', parent_x, y + controlPointDelta, parent_x, parent_y, parent_x, parent_y]);
|
|
} else {
|
|
// path to a commit in a different branch (Bezier curve)
|
|
path = revisionGraph.path([
|
|
'M', x, y,
|
|
'C', parent_x, y, x, parent_y, parent_x, parent_y]);
|
|
}
|
|
} else {
|
|
// 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();
|
|
};
|