Commit 59b6de93cebe4aaa8cca121e6147fd7c83786f17
1 parent
7ba4f2dc
Exists in
master
and in
4 other branches
Improve overlap of lines in network graph
Showing
3 changed files
with
91 additions
and
26 deletions
Show diff stats
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 |