Commit 90cba379a436a942d5d71bfb0bb5a9a321fcbd2b
1 parent
f04597d9
Exists in
master
and in
4 other branches
Updated graph tooltips and labels
Showing
2 changed files
with
117 additions
and
45 deletions
Show diff stats
lib/gitlab/graph/commit.rb
... | ... | @@ -22,14 +22,16 @@ module Gitlab |
22 | 22 | h[:parents] = self.parents.collect do |p| |
23 | 23 | [p.id,0,0] |
24 | 24 | end |
25 | - h[:author] = author.name | |
25 | + h[:author] = { | |
26 | + name: author.name, | |
27 | + email: author.email | |
28 | + } | |
26 | 29 | h[:time] = time |
27 | 30 | h[:space] = space |
28 | 31 | h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil? |
29 | 32 | h[:id] = sha |
30 | 33 | h[:date] = date |
31 | 34 | h[:message] = message |
32 | - h[:login] = author.email | |
33 | 35 | h |
34 | 36 | end |
35 | 37 | ... | ... |
vendor/assets/javascripts/branch-graph.js
... | ... | @@ -85,7 +85,7 @@ |
85 | 85 | if(cuday != this.days[mm][0]){ |
86 | 86 | // Dates |
87 | 87 | r.text(offsetX + mm * 20, 31, this.days[mm][0]).attr({ |
88 | - font: "12px Monaco, Arial", | |
88 | + font: "12px Monaco, monospace", | |
89 | 89 | fill: "#DDD" |
90 | 90 | }); |
91 | 91 | cuday = this.days[mm][0]; |
... | ... | @@ -93,7 +93,7 @@ |
93 | 93 | if(cumonth != this.days[mm][1]){ |
94 | 94 | // Months |
95 | 95 | r.text(offsetX + mm * 20, 11, this.days[mm][1]).attr({ |
96 | - font: "12px Monaco, Arial", | |
96 | + font: "12px Monaco, monospace", | |
97 | 97 | fill: "#EEE" |
98 | 98 | }); |
99 | 99 | cumonth = this.days[mm][1]; |
... | ... | @@ -103,17 +103,16 @@ |
103 | 103 | |
104 | 104 | for (i = 0; i < this.commitCount; i++) { |
105 | 105 | var x = offsetX + 20 * this.commits[i].time |
106 | - , y = offsetY + 20 * this.commits[i].space; | |
106 | + , y = offsetY + 20 * this.commits[i].space | |
107 | + , c; | |
108 | + | |
109 | + // Draw dot | |
107 | 110 | r.circle(x, y, 3).attr({ |
108 | 111 | fill: this.colors[this.commits[i].space], |
109 | 112 | stroke: "none" |
110 | 113 | }); |
111 | 114 | |
112 | - | |
113 | - if (this.commits[i].refs) { | |
114 | - this.appendLabel(x, y, this.commits[i].refs); | |
115 | - } | |
116 | - var c; | |
115 | + // Draw lines | |
117 | 116 | for (var j = 0, jj = this.commits[i].parents.length; j < jj; j++) { |
118 | 117 | c = this.preparedCommits[this.commits[i].parents[j][0]]; |
119 | 118 | if (c) { |
... | ... | @@ -143,6 +142,11 @@ |
143 | 142 | } |
144 | 143 | } |
145 | 144 | } |
145 | + | |
146 | + if (this.commits[i].refs) { | |
147 | + this.appendLabel(x, y, this.commits[i].refs); | |
148 | + } | |
149 | + | |
146 | 150 | this.appendAnchor(top, this.commits[i], x, y); |
147 | 151 | } |
148 | 152 | top.toFront(); |
... | ... | @@ -201,13 +205,13 @@ |
201 | 205 | , shortrefs = refs |
202 | 206 | , text, textbox, rect; |
203 | 207 | |
204 | - if (shortrefs.length > 15){ | |
208 | + if (shortrefs.length > 17){ | |
205 | 209 | // Truncate if longer than 15 chars |
206 | - shortrefs = shortrefs.substr(0,13) + "..."; | |
210 | + shortrefs = shortrefs.substr(0,15) + "…"; | |
207 | 211 | } |
208 | 212 | |
209 | - text = r.text(x+5, y+8, shortrefs).attr({ | |
210 | - font: "12px Monaco, Arial", | |
213 | + text = r.text(x+5, y+8 + 10, shortrefs).attr({ | |
214 | + font: "10px Monaco, monospace", | |
211 | 215 | fill: "#FFF", |
212 | 216 | title: refs |
213 | 217 | }); |
... | ... | @@ -220,22 +224,33 @@ |
220 | 224 | |
221 | 225 | // Create rectangle based on the size of the textbox |
222 | 226 | rect = r.rect(x, y, textbox.width + 15, textbox.height + 5, 4).attr({ |
223 | - fill: "#000", | |
224 | - "fill-opacity": .5, | |
225 | - stroke: "none" | |
227 | + "fill": "#000", | |
228 | + "fill-opacity": .7, | |
229 | + "stroke": "none" | |
230 | + }); | |
231 | + | |
232 | + triangle = r.path([ | |
233 | + 'M', x, y + 5, | |
234 | + 'L', x + 4, y + 15, | |
235 | + 'L', x - 4, y + 15, | |
236 | + 'Z' | |
237 | + ]).attr({ | |
238 | + "fill": "#000", | |
239 | + "fill-opacity": .7, | |
240 | + "stroke": "none" | |
226 | 241 | }); |
227 | 242 | |
228 | 243 | // Rotate and reposition rectangle over text |
229 | 244 | rect.transform([ |
230 | 245 | 'r', 90, x, y, |
231 | - 't', 5, -10 | |
246 | + 't', 15, -9 | |
232 | 247 | ]); |
233 | 248 | |
234 | 249 | // Set text to front |
235 | 250 | text.toFront(); |
236 | 251 | }; |
237 | 252 | |
238 | - BranchGraph.prototype.appendAnchor = function(top, c, x, y) { | |
253 | + BranchGraph.prototype.appendAnchor = function(top, commit, x, y) { | |
239 | 254 | var r = this.raphael |
240 | 255 | , options = this.options |
241 | 256 | , anchor; |
... | ... | @@ -245,16 +260,13 @@ |
245 | 260 | cursor: "pointer" |
246 | 261 | }) |
247 | 262 | .click(function(){ |
248 | - window.location = options.commit_url.replace('%s', c.id); | |
263 | + window.location = options.commit_url.replace('%s', commit.id); | |
249 | 264 | }) |
250 | 265 | .hover(function(){ |
251 | - var text = r.text(100, 100, c.author + "\n \n" + c.id + "\n \n" + c.message).attr({ | |
252 | - fill: "#fff" | |
253 | - }); | |
254 | - this.popup = r.tooltip(x, y + 5, text, 0); | |
255 | - top.push(this.popup.insertBefore(this)); | |
266 | + this.tooltip = r.commitTooltip(x, y + 5, commit); | |
267 | + top.push(this.tooltip.insertBefore(this)); | |
256 | 268 | }, function(){ |
257 | - this.popup && this.popup.remove() && delete this.popup; | |
269 | + this.tooltip && this.tooltip.remove() && delete this.tooltip; | |
258 | 270 | }); |
259 | 271 | top.push(anchor); |
260 | 272 | }; |
... | ... | @@ -262,23 +274,81 @@ |
262 | 274 | this.BranchGraph = BranchGraph; |
263 | 275 | |
264 | 276 | }(this); |
265 | -Raphael.fn.tooltip = function (x, y, set, dir, size) { | |
266 | - dir = dir == null ? 2 : dir; | |
267 | - size = size || 5; | |
268 | - x = Math.round(x); | |
269 | - y = Math.round(y); | |
270 | - var mmax = Math.max | |
271 | - , bb = set.getBBox() | |
272 | - , w = Math.round(bb.width / 2) | |
273 | - , h = Math.round(bb.height / 2) | |
274 | - , dx = [0, w + size * 2, 0, -w - size * 2] | |
275 | - , dy = [-h * 2 - size * 3, -h - size, 0, -h - size] | |
276 | - , p = ["M", x - dx[dir], y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size, | |
277 | - "l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size, | |
278 | - "l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size, | |
279 | - "l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size, | |
280 | - "l", -mmax(w - size, 0), 0, "z"].join(",") | |
281 | - , xy = [{x: x, y: y + size * 2 + h}, {x: x - size * 2 - w, y: y}, {x: x, y: y - size * 2 - h}, {x: x + size * 2 + w, y: y}][dir]; | |
282 | - set.transform(['t', xy.x - w - bb.x, xy.y - h - bb.y]); | |
283 | - return this.set(this.path(p).attr({fill: "#234", stroke: "none"}).insertBefore(set.node ? set : set[0]), set); | |
277 | +Raphael.fn.commitTooltip = function(x, y, commit){ | |
278 | + var nameText, idText, messageText | |
279 | + , boxWidth = 300 | |
280 | + , boxHeight = 200; | |
281 | + | |
282 | + nameText = this.text(x, y + 10, commit.author.name); | |
283 | + idText = this.text(x, y + 35, commit.id); | |
284 | + messageText = this.text(x, y + 50, commit.message); | |
285 | + | |
286 | + textSet = this.set(nameText, idText, messageText).attr({ | |
287 | + "text-anchor": "start", | |
288 | + "font": "12px Monaco, monospace" | |
289 | + }); | |
290 | + | |
291 | + nameText.attr({ | |
292 | + "font": "14px Arial", | |
293 | + "font-weight": "bold" | |
294 | + }); | |
295 | + | |
296 | + idText.attr({ | |
297 | + "fill": "#AAA" | |
298 | + }); | |
299 | + | |
300 | + textWrap(messageText, boxWidth - 50); | |
301 | + | |
302 | + var rect = this.rect(x - 10, y - 10, boxWidth, 100, 4).attr({ | |
303 | + "fill": "#FFF", | |
304 | + "stroke": "#000", | |
305 | + "stroke-linecap": "round", | |
306 | + "stroke-width": 2 | |
307 | + }); | |
308 | + var tooltip = this.set(rect, textSet); | |
309 | + | |
310 | + rect.attr({ | |
311 | + "height" : tooltip.getBBox().height + 10, | |
312 | + "width" : tooltip.getBBox().width + 10 | |
313 | + }); | |
314 | + | |
315 | + tooltip.transform([ | |
316 | + 't', 20, 20 | |
317 | + ]); | |
318 | + | |
319 | + return tooltip; | |
284 | 320 | }; |
321 | + | |
322 | +function textWrap(t, width) { | |
323 | + var content = t.attr("text"); | |
324 | + var abc = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; | |
325 | + t.attr({ | |
326 | + "text" : abc | |
327 | + }); | |
328 | + var letterWidth = t.getBBox().width / abc.length; | |
329 | + | |
330 | + t.attr({ | |
331 | + "text" : content | |
332 | + }); | |
333 | + | |
334 | + var words = content.split(" "); | |
335 | + var x = 0, s = []; | |
336 | + for ( var i = 0; i < words.length; i++) { | |
337 | + | |
338 | + var l = words[i].length; | |
339 | + if (x + (l * letterWidth) > width) { | |
340 | + s.push("\n"); | |
341 | + x = 0; | |
342 | + } | |
343 | + x += l * letterWidth; | |
344 | + s.push(words[i] + " "); | |
345 | + } | |
346 | + t.attr({ | |
347 | + "text" : s.join("") | |
348 | + }); | |
349 | + var b = t.getBBox() | |
350 | + , h = Math.abs(b.y2) - Math.abs(b.y) + 1; | |
351 | + t.attr({ | |
352 | + "y": b.y + h | |
353 | + }); | |
354 | +} | |
285 | 355 | \ No newline at end of file | ... | ... |