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