OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 /** | 5 /** |
6 * A TimelineGraphView displays a timeline graph on a canvas element. | 6 * A TimelineGraphView displays a timeline graph on a canvas element. |
7 */ | 7 */ |
8 var TimelineGraphView = (function() { | 8 var TimelineGraphView = (function() { |
9 'use strict'; | 9 'use strict'; |
10 // We inherit from TopMidBottomView. | 10 // We inherit from TopMidBottomView. |
(...skipping 29 matching lines...) Expand all Loading... |
40 // Number of pixels to scroll per pixel the mouse is dragged. | 40 // Number of pixels to scroll per pixel the mouse is dragged. |
41 var MOUSE_WHEEL_DRAG_RATE = 3; | 41 var MOUSE_WHEEL_DRAG_RATE = 3; |
42 | 42 |
43 var GRID_COLOR = '#CCC'; | 43 var GRID_COLOR = '#CCC'; |
44 var TEXT_COLOR = '#000'; | 44 var TEXT_COLOR = '#000'; |
45 var BACKGROUND_COLOR = '#FFF'; | 45 var BACKGROUND_COLOR = '#FFF'; |
46 | 46 |
47 // Which side of the canvas y-axis labels should go on, for a given Graph. | 47 // Which side of the canvas y-axis labels should go on, for a given Graph. |
48 // TODO(mmenke): Figure out a reasonable way to handle more than 2 sets | 48 // TODO(mmenke): Figure out a reasonable way to handle more than 2 sets |
49 // of labels. | 49 // of labels. |
50 var LabelAlign = { | 50 var LabelAlign = {LEFT: 0, RIGHT: 1}; |
51 LEFT: 0, | |
52 RIGHT: 1 | |
53 }; | |
54 | 51 |
55 /** | 52 /** |
56 * @constructor | 53 * @constructor |
57 */ | 54 */ |
58 function TimelineGraphView(divId, canvasId, scrollbarId, scrollbarInnerId) { | 55 function TimelineGraphView(divId, canvasId, scrollbarId, scrollbarInnerId) { |
59 this.scrollbar_ = new HorizontalScrollbarView(scrollbarId, | 56 this.scrollbar_ = new HorizontalScrollbarView( |
60 scrollbarInnerId, | 57 scrollbarId, scrollbarInnerId, this.onScroll_.bind(this)); |
61 this.onScroll_.bind(this)); | |
62 // Call superclass's constructor. | 58 // Call superclass's constructor. |
63 superClass.call(this, null, new DivView(divId), this.scrollbar_); | 59 superClass.call(this, null, new DivView(divId), this.scrollbar_); |
64 | 60 |
65 this.graphDiv_ = $(divId); | 61 this.graphDiv_ = $(divId); |
66 this.canvas_ = $(canvasId); | 62 this.canvas_ = $(canvasId); |
67 this.canvas_.onmousewheel = this.onMouseWheel_.bind(this); | 63 this.canvas_.onmousewheel = this.onMouseWheel_.bind(this); |
68 this.canvas_.onmousedown = this.onMouseDown_.bind(this); | 64 this.canvas_.onmousedown = this.onMouseDown_.bind(this); |
69 this.canvas_.onmousemove = this.onMouseMove_.bind(this); | 65 this.canvas_.onmousemove = this.onMouseMove_.bind(this); |
70 this.canvas_.onmouseup = this.onMouseUp_.bind(this); | 66 this.canvas_.onmouseup = this.onMouseUp_.bind(this); |
71 this.canvas_.onmouseout = this.onMouseUp_.bind(this); | 67 this.canvas_.onmouseout = this.onMouseUp_.bind(this); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
106 // Inherit the superclass's methods. | 102 // Inherit the superclass's methods. |
107 __proto__: superClass.prototype, | 103 __proto__: superClass.prototype, |
108 | 104 |
109 setGeometry: function(left, top, width, height) { | 105 setGeometry: function(left, top, width, height) { |
110 superClass.prototype.setGeometry.call(this, left, top, width, height); | 106 superClass.prototype.setGeometry.call(this, left, top, width, height); |
111 | 107 |
112 // The size of the canvas can only be set by using its |width| and | 108 // The size of the canvas can only be set by using its |width| and |
113 // |height| properties, which do not take padding into account, so we | 109 // |height| properties, which do not take padding into account, so we |
114 // need to use them ourselves. | 110 // need to use them ourselves. |
115 var style = getComputedStyle(this.canvas_); | 111 var style = getComputedStyle(this.canvas_); |
116 var horizontalPadding = parseInt(style.paddingRight) + | 112 var horizontalPadding = |
117 parseInt(style.paddingLeft); | 113 parseInt(style.paddingRight) + parseInt(style.paddingLeft); |
118 var verticalPadding = parseInt(style.paddingTop) + | 114 var verticalPadding = |
119 parseInt(style.paddingBottom); | 115 parseInt(style.paddingTop) + parseInt(style.paddingBottom); |
120 var canvasWidth = | 116 var canvasWidth = |
121 parseInt(this.graphDiv_.style.width) - horizontalPadding; | 117 parseInt(this.graphDiv_.style.width) - horizontalPadding; |
122 // For unknown reasons, there's an extra 3 pixels border between the | 118 // For unknown reasons, there's an extra 3 pixels border between the |
123 // bottom of the canvas and the bottom margin of the enclosing div. | 119 // bottom of the canvas and the bottom margin of the enclosing div. |
124 var canvasHeight = | 120 var canvasHeight = |
125 parseInt(this.graphDiv_.style.height) - verticalPadding - 3; | 121 parseInt(this.graphDiv_.style.height) - verticalPadding - 3; |
126 | 122 |
127 // Protect against degenerates. | 123 // Protect against degenerates. |
128 if (canvasWidth < 10) | 124 if (canvasWidth < 10) |
129 canvasWidth = 10; | 125 canvasWidth = 10; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 var newPosition = newMaxTime - this.canvas_.width; | 256 var newPosition = newMaxTime - this.canvas_.width; |
261 | 257 |
262 // Update range and scroll position. | 258 // Update range and scroll position. |
263 this.updateScrollbarRange_(false); | 259 this.updateScrollbarRange_(false); |
264 this.horizontalScroll_(newPosition - this.scrollbar_.getPosition()); | 260 this.horizontalScroll_(newPosition - this.scrollbar_.getPosition()); |
265 }, | 261 }, |
266 | 262 |
267 onMouseWheel_: function(event) { | 263 onMouseWheel_: function(event) { |
268 event.preventDefault(); | 264 event.preventDefault(); |
269 this.horizontalScroll_( | 265 this.horizontalScroll_( |
270 MOUSE_WHEEL_SCROLL_RATE * | 266 MOUSE_WHEEL_SCROLL_RATE * -event.wheelDeltaX / |
271 -event.wheelDeltaX / MOUSE_WHEEL_UNITS_PER_CLICK); | 267 MOUSE_WHEEL_UNITS_PER_CLICK); |
272 this.zoom_(Math.pow(MOUSE_WHEEL_ZOOM_RATE, | 268 this.zoom_(Math.pow( |
273 -event.wheelDeltaY / MOUSE_WHEEL_UNITS_PER_CLICK)); | 269 MOUSE_WHEEL_ZOOM_RATE, |
| 270 -event.wheelDeltaY / MOUSE_WHEEL_UNITS_PER_CLICK)); |
274 }, | 271 }, |
275 | 272 |
276 onMouseDown_: function(event) { | 273 onMouseDown_: function(event) { |
277 event.preventDefault(); | 274 event.preventDefault(); |
278 this.isDragging_ = true; | 275 this.isDragging_ = true; |
279 this.dragX_ = event.clientX; | 276 this.dragX_ = event.clientX; |
280 }, | 277 }, |
281 | 278 |
282 onMouseMove_: function(event) { | 279 onMouseMove_: function(event) { |
283 if (!this.isDragging_) | 280 if (!this.isDragging_) |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 var textHeight = height; | 356 var textHeight = height; |
360 height -= fontHeight + LABEL_VERTICAL_SPACING; | 357 height -= fontHeight + LABEL_VERTICAL_SPACING; |
361 this.drawTimeLabels(context, width, height, textHeight, visibleStartTime); | 358 this.drawTimeLabels(context, width, height, textHeight, visibleStartTime); |
362 | 359 |
363 // Draw outline of the main graph area. | 360 // Draw outline of the main graph area. |
364 context.strokeStyle = GRID_COLOR; | 361 context.strokeStyle = GRID_COLOR; |
365 context.strokeRect(0, 0, width - 1, height - 1); | 362 context.strokeRect(0, 0, width - 1, height - 1); |
366 | 363 |
367 // Layout graphs and have them draw their tick marks. | 364 // Layout graphs and have them draw their tick marks. |
368 for (var i = 0; i < this.graphs_.length; ++i) { | 365 for (var i = 0; i < this.graphs_.length; ++i) { |
369 this.graphs_[i].layout(width, height, fontHeight, visibleStartTime, | 366 this.graphs_[i].layout( |
370 this.scale_); | 367 width, height, fontHeight, visibleStartTime, this.scale_); |
371 this.graphs_[i].drawTicks(context); | 368 this.graphs_[i].drawTicks(context); |
372 } | 369 } |
373 | 370 |
374 // Draw the lines of all graphs, and then draw their labels. | 371 // Draw the lines of all graphs, and then draw their labels. |
375 for (var i = 0; i < this.graphs_.length; ++i) | 372 for (var i = 0; i < this.graphs_.length; ++i) |
376 this.graphs_[i].drawLines(context); | 373 this.graphs_[i].drawLines(context); |
377 for (var i = 0; i < this.graphs_.length; ++i) | 374 for (var i = 0; i < this.graphs_.length; ++i) |
378 this.graphs_[i].drawLabels(context); | 375 this.graphs_[i].drawLabels(context); |
379 | 376 |
380 // Restore original transformation matrix. | 377 // Restore original transformation matrix. |
381 context.restore(); | 378 context.restore(); |
382 }, | 379 }, |
383 | 380 |
384 /** | 381 /** |
385 * Draw time labels below the graph. Takes in start time as an argument | 382 * Draw time labels below the graph. Takes in start time as an argument |
386 * since it may not be |startTime_|, when we're displaying the entire | 383 * since it may not be |startTime_|, when we're displaying the entire |
387 * time range. | 384 * time range. |
388 */ | 385 */ |
389 drawTimeLabels: function(context, width, height, textHeight, startTime) { | 386 drawTimeLabels: function(context, width, height, textHeight, startTime) { |
390 // Text for a time string to use in determining how far apart | 387 // Text for a time string to use in determining how far apart |
391 // to place text labels. | 388 // to place text labels. |
392 var sampleText = (new Date(startTime)).toLocaleTimeString(); | 389 var sampleText = (new Date(startTime)).toLocaleTimeString(); |
393 | 390 |
394 // The desired spacing for text labels. | 391 // The desired spacing for text labels. |
395 var targetSpacing = context.measureText(sampleText).width + | 392 var targetSpacing = context.measureText(sampleText).width + |
396 LABEL_LABEL_HORIZONTAL_SPACING; | 393 LABEL_LABEL_HORIZONTAL_SPACING; |
397 | 394 |
398 // The allowed time step values between adjacent labels. Anything much | 395 // The allowed time step values between adjacent labels. Anything much |
399 // over a couple minutes isn't terribly realistic, given how much memory | 396 // over a couple minutes isn't terribly realistic, given how much memory |
400 // we use, and how slow a lot of the net-internals code is. | 397 // we use, and how slow a lot of the net-internals code is. |
401 var timeStepValues = [ | 398 var timeStepValues = [ |
402 1000, // 1 second | 399 1000, // 1 second |
403 1000 * 5, | 400 1000 * 5, 1000 * 30, |
404 1000 * 30, | |
405 1000 * 60, // 1 minute | 401 1000 * 60, // 1 minute |
406 1000 * 60 * 5, | 402 1000 * 60 * 5, 1000 * 60 * 30, |
407 1000 * 60 * 30, | |
408 1000 * 60 * 60, // 1 hour | 403 1000 * 60 * 60, // 1 hour |
409 1000 * 60 * 60 * 5 | 404 1000 * 60 * 60 * 5 |
410 ]; | 405 ]; |
411 | 406 |
412 // Find smallest time step value that gives us at least |targetSpacing|, | 407 // Find smallest time step value that gives us at least |targetSpacing|, |
413 // if any. | 408 // if any. |
414 var timeStep = null; | 409 var timeStep = null; |
415 for (var i = 0; i < timeStepValues.length; ++i) { | 410 for (var i = 0; i < timeStepValues.length; ++i) { |
416 if (timeStepValues[i] / this.scale_ >= targetSpacing) { | 411 if (timeStepValues[i] / this.scale_ >= targetSpacing) { |
417 timeStep = timeStepValues[i]; | 412 timeStep = timeStepValues[i]; |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
725 for (var i = 1; i < this.labels_.length; ++i) | 720 for (var i = 1; i < this.labels_.length; ++i) |
726 context.fillText(this.labels_[i], x, step * i); | 721 context.fillText(this.labels_[i], x, step * i); |
727 } | 722 } |
728 }; | 723 }; |
729 | 724 |
730 return Graph; | 725 return Graph; |
731 })(); | 726 })(); |
732 | 727 |
733 return TimelineGraphView; | 728 return TimelineGraphView; |
734 })(); | 729 })(); |
OLD | NEW |