Commit 59b6de93 authored by Sato Hiroyuki's avatar Sato Hiroyuki

Improve overlap of lines in network graph

parent 7ba4f2dc
...@@ -5,12 +5,13 @@ module Gitlab ...@@ -5,12 +5,13 @@ module Gitlab
class Commit class Commit
include ActionView::Helpers::TagHelper include ActionView::Helpers::TagHelper
attr_accessor :time, :space, :refs attr_accessor :time, :space, :refs, :parent_spaces
def initialize(commit) def initialize(commit)
@_commit = commit @_commit = commit
@time = -1 @time = -1
@space = 0 @space = 0
@parent_spaces = []
end end
def method_missing(m, *args, &block) def method_missing(m, *args, &block)
...@@ -28,6 +29,7 @@ module Gitlab ...@@ -28,6 +29,7 @@ module Gitlab
} }
h[:time] = time h[:time] = time
h[:space] = space h[:space] = space
h[:parent_spaces] = parent_spaces
h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil? h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil?
h[:id] = sha h[:id] = sha
h[:date] = date h[:date] = date
......
...@@ -16,7 +16,6 @@ module Gitlab ...@@ -16,7 +16,6 @@ module Gitlab
@commits = collect_commits @commits = collect_commits
@days = index_commits @days = index_commits
@space = 0
end end
def to_json(*args) def to_json(*args)
...@@ -53,7 +52,7 @@ module Gitlab ...@@ -53,7 +52,7 @@ module Gitlab
# #
# @return [Array<TimeDate>] list of commit dates corelated with time on commits # @return [Array<TimeDate>] list of commit dates corelated with time on commits
def index_commits def index_commits
days, heads = [], [] days, heads, times = [], [], []
map = {} map = {}
commits.reverse.each_with_index do |c,i| commits.reverse.each_with_index do |c,i|
...@@ -61,6 +60,7 @@ module Gitlab ...@@ -61,6 +60,7 @@ module Gitlab
days[i] = c.committed_date days[i] = c.committed_date
map[c.id] = c map[c.id] = c
heads += c.refs unless c.refs.nil? heads += c.refs unless c.refs.nil?
times[i] = c
end end
heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote} heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote}
...@@ -86,9 +86,62 @@ module Gitlab ...@@ -86,9 +86,62 @@ module Gitlab
end end
end end
# find parent spaces for not overlap lines
times.each do |c|
c.parent_spaces.concat(find_free_parent_spaces(c, map, times))
end
days days
end end
def find_free_parent_spaces(commit, map, times)
spaces = []
commit.parents.each do |p|
if map.include?(p.id) then
parent = map[p.id]
range = if commit.time < parent.time then
commit.time..parent.time
else
parent.time..commit.time
end
space = if commit.space >= parent.space then
find_free_parent_space(range, map, parent.space, 1, commit.space, times)
else
find_free_parent_space(range, map, parent.space, -1, parent.space, times)
end
mark_reserved(range, space)
spaces << space
end
end
spaces
end
def find_free_parent_space(range, map, space_base, space_step, space_default, times)
if is_overlap?(range, times, space_default) then
find_free_space(range, map, space_base, space_step)
else
space_default
end
end
def is_overlap?(range, times, overlap_space)
range.each do |i|
if i != range.first &&
i != range.last &&
times[i].space == overlap_space then
return true;
end
end
false
end
# Add space mark on commit and its parents # Add space mark on commit and its parents
# #
# @param [Graph::Commit] the commit object. # @param [Graph::Commit] the commit object.
...@@ -98,8 +151,9 @@ module Gitlab ...@@ -98,8 +151,9 @@ module Gitlab
if leaves.empty? if leaves.empty?
return return
end end
@space = find_free_space(leaves, map) time_range = leaves.last.time..leaves.first.time
leaves.each{|l| l.space = @space} space = find_free_space(time_range, map, 1, 2)
leaves.each{|l| l.space = space}
# and mark it as reserved # and mark it as reserved
min_time = leaves.last.time min_time = leaves.last.time
parents = leaves.last.parents.collect parents = leaves.last.parents.collect
...@@ -116,7 +170,7 @@ module Gitlab ...@@ -116,7 +170,7 @@ module Gitlab
else else
max_time = parent_time - 1 max_time = parent_time - 1
end end
mark_reserved(min_time..max_time, @space) mark_reserved(min_time..max_time, space)
# Visit branching chains # Visit branching chains
leaves.each do |l| leaves.each do |l|
...@@ -133,28 +187,22 @@ module Gitlab ...@@ -133,28 +187,22 @@ module Gitlab
end end
end end
def find_free_space(leaves, map) def find_free_space(time_range, map, space_base, space_step)
time_range = leaves.last.time..leaves.first.time
reserved = [] reserved = []
for day in time_range for day in time_range
reserved += @_reserved[day] reserved += @_reserved[day]
end end
space = base_space(leaves, map)
while (reserved.include? space) || (space == @space) do
space += 1
end
space
end
def base_space(leaves, map) space = space_base
parents = [] while reserved.include?(space) do
leaves.each do |l| space += space_step
parents.concat l.parents.collect.select{|p| map.include? p.id and map[p.id].space.nonzero?} if space <= 0 then
space_step *= -1
space = space_base + space_step
end
end end
space = parents.map{|p| map[p.id].space}.max || 0 space
space += 1
end end
# Takes most left subtree branch of commits # Takes most left subtree branch of commits
......
...@@ -103,8 +103,9 @@ ...@@ -103,8 +103,9 @@
for (i = 0; i < this.commitCount; i++) { for (i = 0; i < this.commitCount; i++) {
var x = offsetX + 20 * this.commits[i].time var x = offsetX + 20 * this.commits[i].time
, y = offsetY + 20 * this.commits[i].space , y = offsetY + 10 * this.commits[i].space
, c; , c
, ps;
// Draw dot // Draw dot
r.circle(x, y, 3).attr({ r.circle(x, y, 3).attr({
...@@ -115,9 +116,11 @@ ...@@ -115,9 +116,11 @@
// Draw lines // Draw lines
for (var j = 0, jj = this.commits[i].parents.length; j < jj; j++) { for (var j = 0, jj = this.commits[i].parents.length; j < jj; j++) {
c = this.preparedCommits[this.commits[i].parents[j][0]]; c = this.preparedCommits[this.commits[i].parents[j][0]];
ps = this.commits[i].parent_spaces[j];
if (c) { if (c) {
var cx = offsetX + 20 * c.time var cx = offsetX + 20 * c.time
, cy = offsetY + 20 * c.space; , cy = offsetY + 10 * c.space
, psy = offsetY + 10 * ps;
if (c.space == this.commits[i].space) { if (c.space == this.commits[i].space) {
r.path([ r.path([
"M", x, y, "M", x, y,
...@@ -128,13 +131,25 @@ ...@@ -128,13 +131,25 @@
}); });
} else if (c.space < this.commits[i].space) { } else if (c.space < this.commits[i].space) {
r.path(["M", x - 5, y + .0001, "l-5-2,0,4,5,-2C", x - 5, y, x - 17, y + 2, x - 20, y - 5, "L", cx, y - 5, cx, cy]) r.path([
"M", x - 5, y,
"l-5-2,0,4,5,-2",
"L", x - 10, y,
"L", x - 15, psy,
"L", cx + 5, psy,
"L", cx, cy])
.attr({ .attr({
stroke: this.colors[this.commits[i].space], stroke: this.colors[this.commits[i].space],
"stroke-width": 2 "stroke-width": 2
}); });
} else { } else {
r.path(["M", x - 3, y + 6, "l-4,3,4,2,0,-5L", x - 10, y + 20, "L", x - 10, cy, cx, cy]) r.path([
"M", x - 3, y + 6,
"l-4,3,4,2,0,-5",
"L", x - 5, y + 10,
"L", x - 10, psy,
"L", cx + 5, psy,
"L", cx, cy])
.attr({ .attr({
stroke: this.colors[c.space], stroke: this.colors[c.space],
"stroke-width": 2 "stroke-width": 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment