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