Commit e1282d507f1a0321c4f25815470b0fa05265e6dd
1 parent
40576b87
Exists in
master
and in
4 other branches
BranchGraph now loads async
Centralized keyboard and drag events for BranchGraph
Showing
6 changed files
with
122 additions
and
94 deletions
Show diff stats
app/assets/javascripts/projects.js.coffee
... | ... | @@ -18,10 +18,3 @@ $ -> |
18 | 18 | # Ref switcher |
19 | 19 | $('.project-refs-select').on 'change', -> |
20 | 20 | $(@).parents('form').submit() |
21 | - | |
22 | -class @GraphNav | |
23 | - @init: -> | |
24 | - $('.graph svg').css 'position', 'relative' | |
25 | - $('body').bind 'keyup', (e) -> | |
26 | - $('.graph svg').animate(left: '+=400') if e.keyCode is 37 # left | |
27 | - $('.graph svg').animate(left: '-=400') if e.keyCode is 39 # right | ... | ... |
app/controllers/projects_controller.rb
... | ... | @@ -83,9 +83,19 @@ class ProjectsController < ProjectResourceController |
83 | 83 | end |
84 | 84 | |
85 | 85 | def graph |
86 | - graph = Gitlab::Graph::JsonBuilder.new(project) | |
86 | + | |
87 | + respond_to do |format| | |
88 | + format.html | |
89 | + format.json do | |
90 | + graph = Gitlab::Graph::JsonBuilder.new(project) | |
91 | + #@days_json, @commits_json = graph.days_json, graph.commits_json | |
92 | + render :text => graph.to_json | |
93 | + end | |
94 | + end | |
95 | + | |
96 | + | |
87 | 97 | |
88 | - @days_json, @commits_json = graph.days_json, graph.commits_json | |
98 | + | |
89 | 99 | end |
90 | 100 | |
91 | 101 | def destroy | ... | ... |
app/views/projects/graph.html.haml
... | ... | @@ -4,12 +4,10 @@ |
4 | 4 | %h4 |
5 | 5 | %small You can move around the graph by using the arrow keys. |
6 | 6 | #holder.graph |
7 | + .loading | |
7 | 8 | |
8 | 9 | :javascript |
9 | - var commits = #{@commits_json} | |
10 | - , days = #{@days_json}; | |
11 | - var branch_graph = new BranchGraph(days, commits); | |
10 | + var branch_graph; | |
12 | 11 | $(function(){ |
13 | - branch_graph.buildGraph($("#holder")[0]); | |
14 | - GraphNav.init(); | |
12 | + branch_graph = new BranchGraph($("#holder"), '#{url_for :controller => 'projects', :action => 'graph'}'); | |
15 | 13 | }); | ... | ... |
lib/gitlab/graph/commit.rb
lib/gitlab/graph/json_builder.rb
... | ... | @@ -17,16 +17,15 @@ module Gitlab |
17 | 17 | @commits = collect_commits |
18 | 18 | @days = index_commits |
19 | 19 | end |
20 | - | |
21 | - def days_json | |
22 | - @days_json = @days.compact.map { |d| [d.day, d.strftime("%b")] }.to_json | |
23 | - end | |
24 | - | |
25 | - def commits_json | |
26 | - @commits_json = @commits.map(&:to_graph_hash).to_json | |
20 | + | |
21 | + def to_json | |
22 | + { | |
23 | + days: @days.compact.map { |d| [d.day, d.strftime("%b")] }, | |
24 | + commits: @commits.map(&:to_graph_hash) | |
25 | + }.to_json | |
27 | 26 | end |
28 | - | |
29 | - protected | |
27 | + | |
28 | + protected | |
30 | 29 | |
31 | 30 | # Get commits from repository |
32 | 31 | # | ... | ... |
vendor/assets/javascripts/branch-graph.js
1 | 1 | !function(){ |
2 | 2 | |
3 | - var BranchGraph = function(days, commits){ | |
3 | + var BranchGraph = function(element, url){ | |
4 | + this.element = element; | |
5 | + this.url = url; | |
4 | 6 | |
5 | - this.days = days || {}; | |
6 | - this.commits = commits || {}; | |
7 | 7 | this.comms = {}; |
8 | - this.pixelsX = []; | |
9 | - this.pixelsY = []; | |
10 | 8 | this.mtime = 0; |
11 | 9 | this.mspace = 0; |
12 | 10 | this.parents = {}; |
13 | - this.ii = 0; | |
14 | 11 | this.colors = ["#000"]; |
15 | 12 | |
16 | - this.prepareData(); | |
13 | + this.load(); | |
17 | 14 | }; |
18 | 15 | |
19 | - BranchGraph.prototype.prepareData = function(){ | |
16 | + BranchGraph.prototype.load = function(){ | |
17 | + $.ajax({ | |
18 | + url: this.url, | |
19 | + method: 'get', | |
20 | + dataType: 'json', | |
21 | + success: $.proxy(function(data){ | |
22 | + $('.loading', this.element).hide(); | |
23 | + this.prepareData(data.days, data.commits); | |
24 | + this.buildGraph(this.element.get(0)); | |
25 | + }, this) | |
26 | + }); | |
27 | + }, | |
28 | + | |
29 | + BranchGraph.prototype.prepareData = function(days, commits){ | |
30 | + this.days = days; | |
31 | + this.commits = commits; | |
20 | 32 | ii = this.commits.length; |
21 | 33 | for (var i = 0; i < ii; i++) { |
22 | 34 | for (var j = 0, jj = this.commits[i].parents.length; j < jj; j++) { |
... | ... | @@ -25,8 +37,8 @@ |
25 | 37 | this.mtime = Math.max(this.mtime, this.commits[i].time); |
26 | 38 | this.mspace = Math.max(this.mspace, this.commits[i].space); |
27 | 39 | } |
28 | - this.mtime = this.mtime + 4; | |
29 | - this.mspace = this.mspace + 10; | |
40 | + this.mtime += 4; | |
41 | + this.mspace += 10; | |
30 | 42 | for (i = 0; i < ii; i++) { |
31 | 43 | if (this.commits[i].id in this.parents) { |
32 | 44 | this.commits[i].isParent = true; |
... | ... | @@ -41,10 +53,13 @@ |
41 | 53 | BranchGraph.prototype.buildGraph = function(holder){ |
42 | 54 | var ch = this.mspace * 20 + 20 |
43 | 55 | , cw = this.mtime * 20 + 20 |
44 | - , r = Raphael("holder", cw, ch) | |
56 | + , r = Raphael(holder, cw, ch) | |
45 | 57 | , top = r.set() |
46 | 58 | , cuday = 0 |
47 | - , cumonth = ""; | |
59 | + , cumonth = "" | |
60 | + , r; | |
61 | + | |
62 | + this.raphael = r; | |
48 | 63 | |
49 | 64 | r.rect(0, 0, this.days.length * 20 + 80, 30).attr({fill: "#222"}); |
50 | 65 | r.rect(0, 30, this.days.length * 20 + 80, 20).attr({fill: "#444"}); |
... | ... | @@ -116,66 +131,79 @@ |
116 | 131 | } |
117 | 132 | } |
118 | 133 | } |
119 | - (function (c, x, y) { | |
120 | - top.push(r.circle(x, y, 10).attr({ | |
121 | - fill: "#000", | |
122 | - opacity: 0, | |
123 | - cursor: "pointer" | |
124 | - }) | |
125 | - .click(function(){ | |
126 | - location.href = location.href.replace("graph", "commits/" + c.id); | |
127 | - }) | |
128 | - .hover(function () { | |
129 | - // Create empty node to convert entities to character | |
130 | - var m = $('<div />').html(c.message).text() | |
131 | - , s = r.text(100, 100, c.author + "\n \n" + c.id + "\n \n" + m).attr({ | |
132 | - fill: "#fff" | |
133 | - }); | |
134 | - this.popup = r.popupit(x, y + 5, s, 0); | |
135 | - top.push(this.popup.insertBefore(this)); | |
136 | - }, function () { | |
137 | - this.popup && this.popup.remove() && delete this.popup; | |
138 | - })); | |
139 | - }(this.commits[i], x, y)); | |
140 | - | |
141 | - top.toFront(); | |
142 | - var hw = holder.offsetWidth | |
143 | - , hh = holder.offsetHeight | |
144 | - , v = r.rect(hw - 8, 0, 4, Math.pow(hh, 2) / ch, 2).attr({ | |
145 | - fill: "#000", | |
146 | - opacity: 0 | |
147 | - }) | |
148 | - , h = r.rect(0, hh - 8, Math.pow(hw, 2) / cw, 4, 2).attr({ | |
149 | - fill: "#000", | |
150 | - opacity: 0 | |
151 | - }) | |
152 | - , bars = r.set(v, h) | |
153 | - , drag | |
154 | - , dragger = function (event) { | |
155 | - if (drag) { | |
156 | - event = event || window.event; | |
157 | - holder.scrollLeft = drag.sl - (event.clientX - drag.x); | |
158 | - holder.scrollTop = drag.st - (event.clientY - drag.y); | |
159 | - } | |
160 | - }; | |
161 | - holder.onmousedown = function (event) { | |
162 | - event = event || window.event; | |
163 | - drag = { | |
164 | - x: event.clientX, | |
165 | - y: event.clientY, | |
166 | - st: holder.scrollTop, | |
167 | - sl: holder.scrollLeft | |
168 | - }; | |
169 | - document.onmousemove = dragger; | |
170 | - bars.animate({opacity: .5}, 300); | |
134 | + this.appendAnchor(top, this.commits[i], x, y); | |
135 | + } | |
136 | + top.toFront(); | |
137 | + var hw = holder.offsetWidth | |
138 | + , hh = holder.offsetHeight | |
139 | + , v = r.rect(hw - 8, 0, 4, Math.pow(hh, 2) / ch, 2).attr({ | |
140 | + fill: "#000", | |
141 | + opacity: 0 | |
142 | + }) | |
143 | + , h = r.rect(0, hh - 8, Math.pow(hw, 2) / cw, 4, 2).attr({ | |
144 | + fill: "#000", | |
145 | + opacity: 0 | |
146 | + }) | |
147 | + , bars = r.set(v, h) | |
148 | + , drag | |
149 | + , dragger = function (event) { | |
150 | + if (drag) { | |
151 | + event = event || window.event; | |
152 | + holder.scrollLeft = drag.sl - (event.clientX - drag.x); | |
153 | + holder.scrollTop = drag.st - (event.clientY - drag.y); | |
154 | + } | |
171 | 155 | }; |
172 | - document.onmouseup = function () { | |
173 | - drag = false; | |
174 | - document.onmousemove = null; | |
175 | - bars.animate({opacity: 0}, 300); | |
156 | + holder.onmousedown = function (event) { | |
157 | + event = event || window.event; | |
158 | + drag = { | |
159 | + x: event.clientX, | |
160 | + y: event.clientY, | |
161 | + st: holder.scrollTop, | |
162 | + sl: holder.scrollLeft | |
176 | 163 | }; |
177 | - holder.scrollLeft = cw; | |
178 | - } | |
164 | + document.onmousemove = dragger; | |
165 | + bars.animate({opacity: .5}, 300); | |
166 | + }; | |
167 | + document.onmouseup = function () { | |
168 | + drag = false; | |
169 | + document.onmousemove = null; | |
170 | + bars.animate({opacity: 0}, 300); | |
171 | + }; | |
172 | + | |
173 | + $(window).on('keydown', function(event){ | |
174 | + if(event.keyCode == 37){ | |
175 | + holder.scrollLeft -= 50; | |
176 | + } | |
177 | + if(event.keyCode == 39){ | |
178 | + // right | |
179 | + holder.scrollLeft += 50; | |
180 | + } | |
181 | + }); | |
182 | + | |
183 | + | |
184 | + holder.scrollLeft = cw; | |
185 | + }; | |
186 | + | |
187 | + BranchGraph.prototype.appendAnchor = function(top, c, x, y) { | |
188 | + var r = this.raphael; | |
189 | + top.push(r.circle(x, y, 10).attr({ | |
190 | + fill: "#000", | |
191 | + opacity: 0, | |
192 | + cursor: "pointer" | |
193 | + }) | |
194 | + .click(function(){ | |
195 | + location.href = location.href.replace("graph", "commits/" + c.id); | |
196 | + }) | |
197 | + .hover(function () { | |
198 | + // Create empty node to convert entities to character | |
199 | + var s = r.text(100, 100, c.author + "\n \n" + c.id + "\n \n" + c.message).attr({ | |
200 | + fill: "#fff" | |
201 | + }); | |
202 | + this.popup = r.popupit(x, y + 5, s, 0); | |
203 | + top.push(this.popup.insertBefore(this)); | |
204 | + }, function () { | |
205 | + this.popup && this.popup.remove() && delete this.popup; | |
206 | + })); | |
179 | 207 | }; |
180 | 208 | |
181 | 209 | this.BranchGraph = BranchGraph; | ... | ... |