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; | ... | ... |