Commit 59b6de93cebe4aaa8cca121e6147fd7c83786f17

Authored by Sato Hiroyuki
1 parent 7ba4f2dc

Improve overlap of lines in network graph

lib/gitlab/graph/commit.rb
@@ -5,12 +5,13 @@ module Gitlab @@ -5,12 +5,13 @@ module Gitlab
5 class Commit 5 class Commit
6 include ActionView::Helpers::TagHelper 6 include ActionView::Helpers::TagHelper
7 7
8 - attr_accessor :time, :space, :refs 8 + attr_accessor :time, :space, :refs, :parent_spaces
9 9
10 def initialize(commit) 10 def initialize(commit)
11 @_commit = commit 11 @_commit = commit
12 @time = -1 12 @time = -1
13 @space = 0 13 @space = 0
  14 + @parent_spaces = []
14 end 15 end
15 16
16 def method_missing(m, *args, &block) 17 def method_missing(m, *args, &block)
@@ -28,6 +29,7 @@ module Gitlab @@ -28,6 +29,7 @@ module Gitlab
28 } 29 }
29 h[:time] = time 30 h[:time] = time
30 h[:space] = space 31 h[:space] = space
  32 + h[:parent_spaces] = parent_spaces
31 h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil? 33 h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil?
32 h[:id] = sha 34 h[:id] = sha
33 h[:date] = date 35 h[:date] = date
lib/gitlab/graph/json_builder.rb
@@ -16,7 +16,6 @@ module Gitlab @@ -16,7 +16,6 @@ module Gitlab
16 16
17 @commits = collect_commits 17 @commits = collect_commits
18 @days = index_commits 18 @days = index_commits
19 - @space = 0  
20 end 19 end
21 20
22 def to_json(*args) 21 def to_json(*args)
@@ -53,7 +52,7 @@ module Gitlab @@ -53,7 +52,7 @@ module Gitlab
53 # 52 #
54 # @return [Array<TimeDate>] list of commit dates corelated with time on commits 53 # @return [Array<TimeDate>] list of commit dates corelated with time on commits
55 def index_commits 54 def index_commits
56 - days, heads = [], [] 55 + days, heads, times = [], [], []
57 map = {} 56 map = {}
58 57
59 commits.reverse.each_with_index do |c,i| 58 commits.reverse.each_with_index do |c,i|
@@ -61,6 +60,7 @@ module Gitlab @@ -61,6 +60,7 @@ module Gitlab
61 days[i] = c.committed_date 60 days[i] = c.committed_date
62 map[c.id] = c 61 map[c.id] = c
63 heads += c.refs unless c.refs.nil? 62 heads += c.refs unless c.refs.nil?
  63 + times[i] = c
64 end 64 end
65 65
66 heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote} 66 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
86 end 86 end
87 end 87 end
88 88
  89 + # find parent spaces for not overlap lines
  90 + times.each do |c|
  91 + c.parent_spaces.concat(find_free_parent_spaces(c, map, times))
  92 + end
  93 +
89 days 94 days
90 end 95 end
91 96
  97 + def find_free_parent_spaces(commit, map, times)
  98 + spaces = []
  99 +
  100 + commit.parents.each do |p|
  101 + if map.include?(p.id) then
  102 + parent = map[p.id]
  103 +
  104 + range = if commit.time < parent.time then
  105 + commit.time..parent.time
  106 + else
  107 + parent.time..commit.time
  108 + end
  109 +
  110 + space = if commit.space >= parent.space then
  111 + find_free_parent_space(range, map, parent.space, 1, commit.space, times)
  112 + else
  113 + find_free_parent_space(range, map, parent.space, -1, parent.space, times)
  114 + end
  115 +
  116 + mark_reserved(range, space)
  117 + spaces << space
  118 + end
  119 + end
  120 +
  121 + spaces
  122 + end
  123 +
  124 + def find_free_parent_space(range, map, space_base, space_step, space_default, times)
  125 + if is_overlap?(range, times, space_default) then
  126 + find_free_space(range, map, space_base, space_step)
  127 + else
  128 + space_default
  129 + end
  130 + end
  131 +
  132 + def is_overlap?(range, times, overlap_space)
  133 + range.each do |i|
  134 + if i != range.first &&
  135 + i != range.last &&
  136 + times[i].space == overlap_space then
  137 +
  138 + return true;
  139 + end
  140 + end
  141 +
  142 + false
  143 + end
  144 +
92 # Add space mark on commit and its parents 145 # Add space mark on commit and its parents
93 # 146 #
94 # @param [Graph::Commit] the commit object. 147 # @param [Graph::Commit] the commit object.
@@ -98,8 +151,9 @@ module Gitlab @@ -98,8 +151,9 @@ module Gitlab
98 if leaves.empty? 151 if leaves.empty?
99 return 152 return
100 end 153 end
101 - @space = find_free_space(leaves, map)  
102 - leaves.each{|l| l.space = @space} 154 + time_range = leaves.last.time..leaves.first.time
  155 + space = find_free_space(time_range, map, 1, 2)
  156 + leaves.each{|l| l.space = space}
103 # and mark it as reserved 157 # and mark it as reserved
104 min_time = leaves.last.time 158 min_time = leaves.last.time
105 parents = leaves.last.parents.collect 159 parents = leaves.last.parents.collect
@@ -116,7 +170,7 @@ module Gitlab @@ -116,7 +170,7 @@ module Gitlab
116 else 170 else
117 max_time = parent_time - 1 171 max_time = parent_time - 1
118 end 172 end
119 - mark_reserved(min_time..max_time, @space) 173 + mark_reserved(min_time..max_time, space)
120 174
121 # Visit branching chains 175 # Visit branching chains
122 leaves.each do |l| 176 leaves.each do |l|
@@ -133,28 +187,22 @@ module Gitlab @@ -133,28 +187,22 @@ module Gitlab
133 end 187 end
134 end 188 end
135 189
136 - def find_free_space(leaves, map)  
137 - time_range = leaves.last.time..leaves.first.time 190 + def find_free_space(time_range, map, space_base, space_step)
138 reserved = [] 191 reserved = []
139 for day in time_range 192 for day in time_range
140 reserved += @_reserved[day] 193 reserved += @_reserved[day]
141 end 194 end
142 - space = base_space(leaves, map)  
143 - while (reserved.include? space) || (space == @space) do  
144 - space += 1  
145 - end  
146 -  
147 - space  
148 - end  
149 195
150 - def base_space(leaves, map)  
151 - parents = []  
152 - leaves.each do |l|  
153 - parents.concat l.parents.collect.select{|p| map.include? p.id and map[p.id].space.nonzero?} 196 + space = space_base
  197 + while reserved.include?(space) do
  198 + space += space_step
  199 + if space <= 0 then
  200 + space_step *= -1
  201 + space = space_base + space_step
  202 + end
154 end 203 end
155 204
156 - space = parents.map{|p| map[p.id].space}.max || 0  
157 - space += 1 205 + space
158 end 206 end
159 207
160 # Takes most left subtree branch of commits 208 # Takes most left subtree branch of commits
vendor/assets/javascripts/branch-graph.js
@@ -103,8 +103,9 @@ @@ -103,8 +103,9 @@
103 103
104 for (i = 0; i < this.commitCount; i++) { 104 for (i = 0; i < this.commitCount; i++) {
105 var x = offsetX + 20 * this.commits[i].time 105 var x = offsetX + 20 * this.commits[i].time
106 - , y = offsetY + 20 * this.commits[i].space  
107 - , c; 106 + , y = offsetY + 10 * this.commits[i].space
  107 + , c
  108 + , ps;
108 109
109 // Draw dot 110 // Draw dot
110 r.circle(x, y, 3).attr({ 111 r.circle(x, y, 3).attr({
@@ -115,9 +116,11 @@ @@ -115,9 +116,11 @@
115 // Draw lines 116 // Draw lines
116 for (var j = 0, jj = this.commits[i].parents.length; j < jj; j++) { 117 for (var j = 0, jj = this.commits[i].parents.length; j < jj; j++) {
117 c = this.preparedCommits[this.commits[i].parents[j][0]]; 118 c = this.preparedCommits[this.commits[i].parents[j][0]];
  119 + ps = this.commits[i].parent_spaces[j];
118 if (c) { 120 if (c) {
119 var cx = offsetX + 20 * c.time 121 var cx = offsetX + 20 * c.time
120 - , cy = offsetY + 20 * c.space; 122 + , cy = offsetY + 10 * c.space
  123 + , psy = offsetY + 10 * ps;
121 if (c.space == this.commits[i].space) { 124 if (c.space == this.commits[i].space) {
122 r.path([ 125 r.path([
123 "M", x, y, 126 "M", x, y,
@@ -128,13 +131,25 @@ @@ -128,13 +131,25 @@
128 }); 131 });
129 132
130 } else if (c.space < this.commits[i].space) { 133 } else if (c.space < this.commits[i].space) {
131 - 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]) 134 + r.path([
  135 + "M", x - 5, y,
  136 + "l-5-2,0,4,5,-2",
  137 + "L", x - 10, y,
  138 + "L", x - 15, psy,
  139 + "L", cx + 5, psy,
  140 + "L", cx, cy])
132 .attr({ 141 .attr({
133 stroke: this.colors[this.commits[i].space], 142 stroke: this.colors[this.commits[i].space],
134 "stroke-width": 2 143 "stroke-width": 2
135 }); 144 });
136 } else { 145 } else {
137 - r.path(["M", x - 3, y + 6, "l-4,3,4,2,0,-5L", x - 10, y + 20, "L", x - 10, cy, cx, cy]) 146 + r.path([
  147 + "M", x - 3, y + 6,
  148 + "l-4,3,4,2,0,-5",
  149 + "L", x - 5, y + 10,
  150 + "L", x - 10, psy,
  151 + "L", cx + 5, psy,
  152 + "L", cx, cy])
138 .attr({ 153 .attr({
139 stroke: this.colors[c.space], 154 stroke: this.colors[c.space],
140 "stroke-width": 2 155 "stroke-width": 2