Commit 233d285c68e5cb180aa5f96d9e213257ef0d91dc

Authored by Dmitriy Zaporozhets
2 parents 75fbdc40 1ae9c697

Merge pull request #3741 from hiroponz/improve-performance-of-network-graph

Improve performance of network graph
app/assets/javascripts/branch-graph.js.coffee
... ... @@ -9,6 +9,7 @@ class BranchGraph
9 9 @offsetY = 20
10 10 @unitTime = 30
11 11 @unitSpace = 10
  12 + @prev_start = -1
12 13 @load()
13 14  
14 15 load: ->
... ... @@ -24,10 +25,18 @@ class BranchGraph
24 25  
25 26 prepareData: (@days, @commits) ->
26 27 @collectParents()
  28 + @graphHeight = $(@element).height()
  29 + @graphWidth = $(@element).width()
  30 + ch = Math.max(@graphHeight, @offsetY + @unitTime * @mtime + 150)
  31 + cw = Math.max(@graphWidth, @offsetX + @unitSpace * @mspace + 300)
  32 + @r = Raphael(@element.get(0), cw, ch)
  33 + @top = @r.set()
  34 + @barHeight = Math.max(@graphHeight, @unitTime * @days.length + 320)
27 35  
28 36 for c in @commits
29 37 c.isParent = true if c.id of @parents
30 38 @preparedCommits[c.id] = c
  39 + @markCommit(c)
31 40  
32 41 @collectColors()
33 42  
... ... @@ -49,18 +58,12 @@ class BranchGraph
49 58 k++
50 59  
51 60 buildGraph: ->
52   - graphHeight = $(@element).height()
53   - graphWidth = $(@element).width()
54   - ch = Math.max(graphHeight, @offsetY + @unitTime * @mtime + 150)
55   - cw = Math.max(graphWidth, @offsetX + @unitSpace * @mspace + 300)
56   - @r = r = Raphael(@element.get(0), cw, ch)
57   - top = r.set()
  61 + r = @r
58 62 cuday = 0
59 63 cumonth = ""
60   - barHeight = Math.max(graphHeight, @unitTime * @days.length + 320)
61 64  
62   - r.rect(0, 0, 26, barHeight).attr fill: "#222"
63   - r.rect(26, 0, 20, barHeight).attr fill: "#444"
  65 + r.rect(0, 0, 26, @barHeight).attr fill: "#222"
  66 + r.rect(26, 0, 20, @barHeight).attr fill: "#444"
64 67  
65 68 for day, mm in @days
66 69 if cuday isnt day[0]
... ... @@ -81,42 +84,50 @@ class BranchGraph
81 84 )
82 85 cumonth = day[1]
83 86  
84   - for commit in @commits
85   - x = @offsetX + @unitSpace * (@mspace - commit.space)
86   - y = @offsetY + @unitTime * commit.time
  87 + @renderPartialGraph()
  88 +
  89 + @bindEvents()
87 90  
88   - @drawDot(x, y, commit)
  91 + renderPartialGraph: ->
  92 + start = Math.floor((@element.scrollTop() - @offsetY) / @unitTime) - 10
  93 + start = 0 if start < 0
  94 + end = start + 40
  95 + end = @commits.length if @commits.length < end
89 96  
90   - @drawLines(x, y, commit)
  97 + if @prev_start == -1 or Math.abs(@prev_start - start) > 10
  98 + i = start
91 99  
92   - @appendLabel(x, y, commit.refs) if commit.refs
  100 + @prev_start = start
93 101  
94   - @appendAnchor(top, commit, x, y)
  102 + while i < end
  103 + commit = @commits[i]
  104 + i += 1
95 105  
96   - @markCommit(x, y, commit, graphHeight)
  106 + if commit.hasDrawn isnt true
  107 + x = @offsetX + @unitSpace * (@mspace - commit.space)
  108 + y = @offsetY + @unitTime * commit.time
97 109  
98   - top.toFront()
99   - @bindEvents()
  110 + @drawDot(x, y, commit)
  111 +
  112 + @drawLines(x, y, commit)
  113 +
  114 + @appendLabel(x, y, commit)
  115 +
  116 + @appendAnchor(x, y, commit)
  117 +
  118 + commit.hasDrawn = true
  119 +
  120 + @top.toFront()
100 121  
101 122 bindEvents: ->
102 123 drag = {}
103 124 element = @element
104   - dragger = (event) ->
105   - element.scrollLeft drag.sl - (event.clientX - drag.x)
106   - element.scrollTop drag.st - (event.clientY - drag.y)
107   -
108   - element.on mousedown: (event) ->
109   - drag =
110   - x: event.clientX
111   - y: event.clientY
112   - st: element.scrollTop()
113   - sl: element.scrollLeft()
114   - $(window).on "mousemove", dragger
  125 +
  126 + $(element).scroll (event) =>
  127 + @renderPartialGraph()
115 128  
116 129 $(window).on
117   - mouseup: ->
118   - $(window).off "mousemove", dragger
119   - keydown: (event) ->
  130 + keydown: (event) =>
120 131 # left
121 132 element.scrollLeft element.scrollLeft() - 50 if event.keyCode is 37
122 133 # top
... ... @@ -125,17 +136,20 @@ class BranchGraph
125 136 element.scrollLeft element.scrollLeft() + 50 if event.keyCode is 39
126 137 # bottom
127 138 element.scrollTop element.scrollTop() + 50 if event.keyCode is 40
  139 + @renderPartialGraph()
  140 +
  141 + appendLabel: (x, y, commit) ->
  142 + return unless commit.refs
128 143  
129   - appendLabel: (x, y, refs) ->
130 144 r = @r
131   - shortrefs = refs
  145 + shortrefs = commit.refs
132 146 # Truncate if longer than 15 chars
133 147 shortrefs = shortrefs.substr(0, 15) + "…" if shortrefs.length > 17
134 148 text = r.text(x + 4, y, shortrefs).attr(
135 149 "text-anchor": "start"
136 150 font: "10px Monaco, monospace"
137 151 fill: "#FFF"
138   - title: refs
  152 + title: commit.refs
139 153 )
140 154 textbox = text.getBBox()
141 155 # Create rectangle based on the size of the textbox
... ... @@ -156,8 +170,9 @@ class BranchGraph
156 170 # Set text to front
157 171 text.toFront()
158 172  
159   - appendAnchor: (top, commit, x, y) ->
  173 + appendAnchor: (x, y, commit) ->
160 174 r = @r
  175 + top = @top
161 176 options = @options
162 177 anchor = r.circle(x, y, 10).attr(
163 178 fill: "#000"
... ... @@ -240,16 +255,18 @@ class BranchGraph
240 255 stroke: color
241 256 "stroke-width": 2)
242 257  
243   - markCommit: (x, y, commit, graphHeight) ->
  258 + markCommit: (commit) ->
244 259 if commit.id is @options.commit_id
245 260 r = @r
  261 + x = @offsetX + @unitSpace * (@mspace - commit.space)
  262 + y = @offsetY + @unitTime * commit.time
246 263 r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr(
247 264 fill: "#000"
248 265 "fill-opacity": .5
249 266 stroke: "none"
250 267 )
251 268 # Displayed in the center
252   - @element.scrollTop(y - graphHeight / 2)
  269 + @element.scrollTop(y - @graphHeight / 2)
253 270  
254 271 Raphael::commitTooltip = (x, y, commit) ->
255 272 boxWidth = 300
... ...
app/assets/stylesheets/sections/graph.scss
... ... @@ -13,7 +13,8 @@
13 13 background: #f1f1f1;
14 14 cursor: move;
15 15 height: 500px;
16   - overflow: hidden;
  16 + overflow-y: scroll;
  17 + overflow-x: hidden;
17 18 }
18 19 }
19 20  
... ...
app/helpers/graph_helper.rb
... ... @@ -4,8 +4,7 @@ module GraphHelper
4 4 refs += commit.refs.collect{|r|r.name}.join(" ") if commit.refs
5 5  
6 6 # append note count
7   - notes = @project.notes.for_commit_id(commit.id)
8   - refs += "[#{notes.count}]" if notes.any?
  7 + refs += "[#{@graph.notes[commit.id]}]" if @graph.notes[commit.id] > 0
9 8  
10 9 refs
11 10 end
... ...
app/models/network/graph.rb
... ... @@ -2,7 +2,7 @@ require &quot;grit&quot;
2 2  
3 3 module Network
4 4 class Graph
5   - attr_reader :days, :commits, :map
  5 + attr_reader :days, :commits, :map, :notes
6 6  
7 7 def self.max_count
8 8 @max_count ||= 650
... ... @@ -16,10 +16,19 @@ module Network
16 16  
17 17 @commits = collect_commits
18 18 @days = index_commits
  19 + @notes = collect_notes
19 20 end
20 21  
21 22 protected
22 23  
  24 + def collect_notes
  25 + h = Hash.new(0)
  26 + @project.notes.where('noteable_type = ?' ,"Commit").group('notes.commit_id').select('notes.commit_id, count(notes.id) as note_count').each do |item|
  27 + h[item["commit_id"]] = item["note_count"]
  28 + end
  29 + h
  30 + end
  31 +
23 32 # Get commits from repository
24 33 #
25 34 def collect_commits
... ... @@ -181,7 +190,7 @@ module Network
181 190 l.spaces << space
182 191 # Also add space to parent
183 192 l.parents(@map).each do |parent|
184   - if parent.space > 0
  193 + if 0 < parent.space && parent.space < space
185 194 parent.spaces << space
186 195 end
187 196 end
... ...
features/project/network.feature
... ... @@ -11,14 +11,16 @@ Feature: Project Network Graph
11 11 And page should have "master" on graph
12 12  
13 13 @javascript
14   - Scenario: I should switch ref to "stable"
  14 + Scenario: I should switch "branch" and "tag"
15 15 When I switch ref to "stable"
16   - Then page should have network graph
17   - And page should select "stable" in select box
  16 + Then page should select "stable" in select box
18 17 And page should have "stable" on graph
  18 + When I switch ref to "v2.1.0"
  19 + Then page should select "v2.1.0" in select box
  20 + And page should have "v2.1.0" on graph
19 21  
20 22 @javascript
21   - Scenario: I should looking for a commit by SHA of "v2.1.0"
  23 + Scenario: I should looking for a commit by SHA
22 24 When I looking for a commit by SHA of "v2.1.0"
23 25 Then page should have network graph
24 26 And page should select "master" in select box
... ...
features/steps/project/project_network_graph.rb
... ... @@ -30,10 +30,19 @@ class ProjectNetworkGraph &lt; Spinach::FeatureSteps
30 30 sleep 2
31 31 end
32 32  
  33 + When 'I switch ref to "v2.1.0"' do
  34 + page.select 'v2.1.0', :from => 'ref'
  35 + sleep 2
  36 + end
  37 +
33 38 And 'page should select "stable" in select box' do
34 39 page.should have_selector '#ref_chzn span', :text => "stable"
35 40 end
36 41  
  42 + And 'page should select "v2.1.0" in select box' do
  43 + page.should have_selector '#ref_chzn span', :text => "v2.1.0"
  44 + end
  45 +
37 46 And 'page should have "stable" on graph' do
38 47 within '.graph' do
39 48 page.should have_content 'stable'
... ...
lib/extracts_path.rb
... ... @@ -98,9 +98,7 @@ module ExtractsPath
98 98  
99 99 @ref, @path = extract_ref(@id)
100 100  
101   - # It is used "@project.repository.commits(@ref, @path, 1, 0)",
102   - # because "@project.repository.commit(@ref)" returns wrong commit when @ref is tag name.
103   - @commit = @project.repository.commits(@ref, @path, 1, 0).first
  101 + @commit = @project.repository.commit(@ref)
104 102  
105 103 @tree = Tree.new(@project.repository, @commit.id, @ref, @path)
106 104  
... ...
lib/gitlab/git/repository.rb
... ... @@ -49,7 +49,16 @@ module Gitlab
49 49  
50 50 def commit(commit_id = nil)
51 51 commit = if commit_id
52   - repo.commit(commit_id)
  52 + # Find repo.refs first,
  53 + # because if commit_id is "tag name",
  54 + # repo.commit(commit_id) returns wrong commit sha
  55 + # that is git tag object sha.
  56 + ref = repo.refs.find {|r| r.name == commit_id}
  57 + if ref
  58 + ref.commit
  59 + else
  60 + repo.commit(commit_id)
  61 + end
53 62 else
54 63 repo.commits(root_ref).first
55 64 end
... ...