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