OLD | NEW |
---|---|
1 /** | 1 /** |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 25 matching lines...) Expand all Loading... | |
36 WebInspector.FlameChartDelegate.prototype = { | 36 WebInspector.FlameChartDelegate.prototype = { |
37 /** | 37 /** |
38 * @param {number} startTime | 38 * @param {number} startTime |
39 * @param {number} endTime | 39 * @param {number} endTime |
40 */ | 40 */ |
41 requestWindowTimes: function(startTime, endTime) { }, | 41 requestWindowTimes: function(startTime, endTime) { }, |
42 } | 42 } |
43 | 43 |
44 /** | 44 /** |
45 * @constructor | 45 * @constructor |
46 * @extends {WebInspector.VBox} | 46 * @extends {WebInspector.HBox} |
47 * @param {!WebInspector.FlameChartDataProvider} dataProvider | 47 * @param {!WebInspector.FlameChartDataProvider} dataProvider |
48 * @param {!WebInspector.FlameChartDelegate} flameChartDelegate | 48 * @param {!WebInspector.FlameChartDelegate} flameChartDelegate |
49 * @param {boolean} isTopDown | 49 * @param {boolean} isTopDown |
50 * @param {boolean} timeBasedWindow | 50 * @param {boolean} timeBasedWindow |
51 */ | 51 */ |
52 WebInspector.FlameChart = function(dataProvider, flameChartDelegate, isTopDown, timeBasedWindow) | 52 WebInspector.FlameChart = function(dataProvider, flameChartDelegate, isTopDown, timeBasedWindow) |
53 { | 53 { |
54 WebInspector.VBox.call(this); | 54 WebInspector.HBox.call(this); |
55 this.element.classList.add("flame-chart-main-pane"); | 55 this.element.classList.add("flame-chart-main-pane"); |
56 this._flameChartDelegate = flameChartDelegate; | 56 this._flameChartDelegate = flameChartDelegate; |
57 this._isTopDown = isTopDown; | 57 this._isTopDown = isTopDown; |
58 this._timeBasedWindow = timeBasedWindow; | 58 this._timeBasedWindow = timeBasedWindow; |
59 | 59 |
60 this._calculator = new WebInspector.FlameChart.Calculator(); | 60 this._calculator = new WebInspector.FlameChart.Calculator(); |
61 | |
62 this._canvas = this.element.createChild("canvas"); | 61 this._canvas = this.element.createChild("canvas"); |
63 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this)); | 62 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this)); |
64 this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), f alse); | 63 this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), f alse); |
65 this._canvas.addEventListener("click", this._onClick.bind(this), false); | 64 this._canvas.addEventListener("click", this._onClick.bind(this), false); |
66 WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind( this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "mov e", null); | 65 WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind( this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "mov e", null); |
66 this._vScrollElement = this.element.createChild("div", "flame-chart-v-scroll "); | |
67 this._vScrollContent = this._vScrollElement.createChild("div"); | |
68 this._vScrollElement.addEventListener("scroll", this._scheduleUpdate.bind(th is), false); | |
67 | 69 |
68 this._entryInfo = this.element.createChild("div", "profile-entry-info"); | 70 this._entryInfo = this.element.createChild("div", "profile-entry-info"); |
69 this._highlightElement = this.element.createChild("div", "flame-chart-highli ght-element"); | 71 this._highlightElement = this.element.createChild("div", "flame-chart-highli ght-element"); |
70 this._selectedElement = this.element.createChild("div", "flame-chart-selecte d-element"); | 72 this._selectedElement = this.element.createChild("div", "flame-chart-selecte d-element"); |
71 | 73 |
72 this._dataProvider = dataProvider; | 74 this._dataProvider = dataProvider; |
73 | 75 |
74 this._windowLeft = 0.0; | 76 this._windowLeft = 0.0; |
75 this._windowRight = 1.0; | 77 this._windowRight = 1.0; |
76 this._windowWidth = 1.0; | 78 this._windowWidth = 1.0; |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
430 | 432 |
431 /** | 433 /** |
432 * @param {?MouseEvent} e | 434 * @param {?MouseEvent} e |
433 */ | 435 */ |
434 _onMouseWheel: function(e) | 436 _onMouseWheel: function(e) |
435 { | 437 { |
436 var windowLeft = this._timeWindowLeft ? this._timeWindowLeft : this._dat aProvider.zeroTime(); | 438 var windowLeft = this._timeWindowLeft ? this._timeWindowLeft : this._dat aProvider.zeroTime(); |
437 var windowRight = this._timeWindowRight !== Infinity ? this._timeWindowR ight : this._dataProvider.zeroTime() + this._dataProvider.totalTime(); | 439 var windowRight = this._timeWindowRight !== Infinity ? this._timeWindowR ight : this._dataProvider.zeroTime() + this._dataProvider.totalTime(); |
438 | 440 |
439 if (e.wheelDeltaY) { | 441 if (e.wheelDeltaY) { |
440 const mouseWheelZoomSpeed = 1 / 120; | 442 if (e.altKey) { |
441 var zoom = Math.pow(1.2, -e.wheelDeltaY * mouseWheelZoomSpeed) - 1; | 443 const mouseWheelZoomSpeed = 1 / 120; |
442 var cursorTime = this._cursorTime(e.offsetX); | 444 var zoom = Math.pow(1.2, -e.wheelDeltaY * mouseWheelZoomSpeed) - 1; |
443 windowLeft += (windowLeft - cursorTime) * zoom; | 445 var cursorTime = this._cursorTime(e.offsetX); |
444 windowRight += (windowRight - cursorTime) * zoom; | 446 windowLeft += (windowLeft - cursorTime) * zoom; |
447 windowRight += (windowRight - cursorTime) * zoom; | |
448 } else | |
449 this._vScrollElement.scrollTop += -e.wheelDeltaY / 120 * this._o ffsetHeight / 8; | |
pfeldman
2014/03/27 12:48:04
+= - ?
alph
2014/03/27 13:15:36
nit: perhaps move "e.wheelDeltaY / 120" out of the
| |
445 } else { | 450 } else { |
446 var shift = e.wheelDeltaX * this._pixelToTime; | 451 var shift = e.wheelDeltaX * this._pixelToTime; |
447 shift = Number.constrain(shift, this._zeroTime - windowLeft, this._t otalTime + this._zeroTime - windowRight); | 452 shift = Number.constrain(shift, this._zeroTime - windowLeft, this._t otalTime + this._zeroTime - windowRight); |
448 windowLeft += shift; | 453 windowLeft += shift; |
449 windowRight += shift; | 454 windowRight += shift; |
450 } | 455 } |
451 windowLeft = Number.constrain(windowLeft, this._zeroTime, this._totalTim e + this._zeroTime); | 456 windowLeft = Number.constrain(windowLeft, this._zeroTime, this._totalTim e + this._zeroTime); |
452 windowRight = Number.constrain(windowRight, this._zeroTime, this._totalT ime + this._zeroTime); | 457 windowRight = Number.constrain(windowRight, this._zeroTime, this._totalT ime + this._zeroTime); |
453 this._flameChartDelegate.requestWindowTimes(windowLeft, windowRight); | 458 this._flameChartDelegate.requestWindowTimes(windowLeft, windowRight); |
454 }, | 459 }, |
455 | 460 |
456 /** | 461 /** |
457 * @param {number} x | 462 * @param {number} x |
458 * @return {number} | 463 * @return {number} |
459 */ | 464 */ |
460 _cursorTime: function(x) | 465 _cursorTime: function(x) |
461 { | 466 { |
462 return (x + this._pixelWindowLeft - this._paddingLeft) * this._pixelToTi me + this._zeroTime; | 467 return (x + this._pixelWindowLeft - this._paddingLeft) * this._pixelToTi me + this._zeroTime; |
463 }, | 468 }, |
464 | 469 |
465 /** | 470 /** |
466 * @param {!number} x | 471 * @param {!number} x |
467 * @param {!number} y | 472 * @param {!number} y |
468 */ | 473 */ |
469 _coordinatesToEntryIndex: function(x, y) | 474 _coordinatesToEntryIndex: function(x, y) |
470 { | 475 { |
476 y += this._scrollTop; | |
pfeldman
2014/03/27 12:48:04
How does this work with the retina?
| |
471 var timelineData = this._timelineData(); | 477 var timelineData = this._timelineData(); |
472 if (!timelineData) | 478 if (!timelineData) |
473 return -1; | 479 return -1; |
474 var cursorTimeOffset = this._cursorTime(x) - this._zeroTime; | 480 var cursorTimeOffset = this._cursorTime(x) - this._zeroTime; |
475 var cursorLevel = this._isTopDown ? Math.floor((y - WebInspector.FlameCh art.DividersBarHeight) / this._barHeight) : Math.floor((this._canvas.height / wi ndow.devicePixelRatio - y) / this._barHeight); | 481 var cursorLevel = this._isTopDown ? Math.floor((y - WebInspector.FlameCh art.DividersBarHeight) / this._barHeight) : Math.floor((this._canvas.height / wi ndow.devicePixelRatio - y) / this._barHeight); |
476 var entryOffsets = timelineData.entryOffsets; | 482 var entryOffsets = timelineData.entryOffsets; |
477 var entryTotalTimes = timelineData.entryTotalTimes; | 483 var entryTotalTimes = timelineData.entryTotalTimes; |
478 var entryLevels = timelineData.entryLevels; | 484 var entryLevels = timelineData.entryLevels; |
479 var length = entryOffsets.length; | 485 var length = entryOffsets.length; |
480 for (var i = 0; i < length; ++i) { | 486 for (var i = 0; i < length; ++i) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
518 var lastTitleIndex = 0; | 524 var lastTitleIndex = 0; |
519 var textPadding = this._dataProvider.textPadding(); | 525 var textPadding = this._dataProvider.textPadding(); |
520 this._minTextWidth = 2 * textPadding + this._measureWidth(context, "\u20 26"); | 526 this._minTextWidth = 2 * textPadding + this._measureWidth(context, "\u20 26"); |
521 var minTextWidth = this._minTextWidth; | 527 var minTextWidth = this._minTextWidth; |
522 | 528 |
523 var lastDrawOffset = new Int32Array(this._dataProvider.maxStackDepth()); | 529 var lastDrawOffset = new Int32Array(this._dataProvider.maxStackDepth()); |
524 for (var i = 0; i < lastDrawOffset.length; ++i) | 530 for (var i = 0; i < lastDrawOffset.length; ++i) |
525 lastDrawOffset[i] = -1; | 531 lastDrawOffset[i] = -1; |
526 | 532 |
527 var barHeight = this._barHeight; | 533 var barHeight = this._barHeight; |
528 this._baseHeight = this._isTopDown ? WebInspector.FlameChart.DividersBar Height : height - barHeight; | |
529 | 534 |
530 var offsetToPosition = this._offsetToPosition.bind(this); | 535 var offsetToPosition = this._offsetToPosition.bind(this); |
531 var textBaseHeight = this._baseHeight + barHeight - this._dataProvider.t extBaseline(); | 536 var textBaseHeight = this._baseHeight + barHeight - this._dataProvider.t extBaseline(); |
532 var colorBuckets = {}; | 537 var colorBuckets = {}; |
533 var maxBarLevel = Math.min(this._dataProvider.maxStackDepth(), Math.ceil (height / barHeight)); | 538 var minVisibleBarLevel = Math.max(0, Math.floor((this._scrollTop - this. _baseHeight) / barHeight)); |
539 var maxVisibleBarLevel = Math.min(this._dataProvider.maxStackDepth(), Ma th.ceil((height + this._scrollTop) / barHeight)); | |
540 var visibleBarsCount = maxVisibleBarLevel - minVisibleBarLevel + 1; | |
534 | 541 |
542 context.translate(0, -this._scrollTop * ratio); | |
535 var levelsCompleted = 0; | 543 var levelsCompleted = 0; |
536 var lastEntryOnLevelPainted = []; | 544 var lastEntryOnLevelPainted = []; |
537 for (var i = 0; i < maxBarLevel; ++i) | 545 for (var i = 0; i < visibleBarsCount; ++i) |
538 lastEntryOnLevelPainted[i] = false; | 546 lastEntryOnLevelPainted[i] = false; |
539 | 547 |
540 for (var entryIndex = 0; levelsCompleted < maxBarLevel && entryIndex < e ntryOffsets.length; ++entryIndex) { | 548 for (var entryIndex = 0; levelsCompleted < visibleBarsCount && entryInde x < entryOffsets.length; ++entryIndex) { |
541 // skip if it is not visible (top/bottom side) | 549 // skip if it is not visible (top/bottom side) |
542 var barLevel = entryLevels[entryIndex]; | 550 var barLevel = entryLevels[entryIndex]; |
543 if (barLevel > maxBarLevel || lastEntryOnLevelPainted[barLevel]) | 551 if (barLevel < minVisibleBarLevel || barLevel > maxVisibleBarLevel | | lastEntryOnLevelPainted[barLevel - minVisibleBarLevel]) |
544 continue; | 552 continue; |
545 | 553 |
546 // stop if we reached right border in time (entries were ordered by start time). | 554 // stop if we reached right border in time (entries were ordered by start time). |
547 var entryOffset = entryOffsets[entryIndex]; | 555 var entryOffset = entryOffsets[entryIndex]; |
548 if (entryOffset > timeWindowRight) { | 556 if (entryOffset > timeWindowRight) { |
549 lastEntryOnLevelPainted[barLevel] = true; | 557 lastEntryOnLevelPainted[barLevel - minVisibleBarLevel] = true; |
550 levelsCompleted++; | 558 levelsCompleted++; |
551 continue; | 559 continue; |
552 } | 560 } |
553 | 561 |
554 // skip if it is not visible (left side). | 562 // skip if it is not visible (left side). |
555 var entryOffsetRight = entryOffset + entryTotalTimes[entryIndex]; | 563 var entryOffsetRight = entryOffset + entryTotalTimes[entryIndex]; |
556 if (entryOffsetRight < timeWindowLeft) | 564 if (entryOffsetRight < timeWindowLeft) |
557 continue; | 565 continue; |
558 | 566 |
559 var barRight = this._offsetToPosition(entryOffsetRight); | 567 var barRight = this._offsetToPosition(entryOffsetRight); |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 return; | 653 return; |
646 var timeRange = this._dataProvider.highlightTimeRange(entryIndex); | 654 var timeRange = this._dataProvider.highlightTimeRange(entryIndex); |
647 if (!timeRange) | 655 if (!timeRange) |
648 return; | 656 return; |
649 var timelineData = this._timelineData(); | 657 var timelineData = this._timelineData(); |
650 var barX = this._offsetToPosition(timeRange.startTimeOffset); | 658 var barX = this._offsetToPosition(timeRange.startTimeOffset); |
651 var barRight = this._offsetToPosition(timeRange.endTimeOffset); | 659 var barRight = this._offsetToPosition(timeRange.endTimeOffset); |
652 if (barRight === 0 || barX === this._canvas.width) | 660 if (barRight === 0 || barX === this._canvas.width) |
653 return; | 661 return; |
654 var barWidth = Math.max(barRight - barX, this._minWidth); | 662 var barWidth = Math.max(barRight - barX, this._minWidth); |
655 var barY = this._levelToHeight(timelineData.entryLevels[entryIndex]); | 663 var barY = this._levelToHeight(timelineData.entryLevels[entryIndex]) - t his._scrollTop; |
656 var style = element.style; | 664 var style = element.style; |
657 style.left = barX + "px"; | 665 style.left = barX + "px"; |
658 style.top = barY + "px"; | 666 style.top = barY + "px"; |
659 style.width = barWidth + "px"; | 667 style.width = barWidth + "px"; |
660 style.height = this._barHeight + "px"; | 668 style.height = this._barHeight + "px"; |
661 this.element.appendChild(element); | 669 this.element.appendChild(element); |
662 }, | 670 }, |
663 | 671 |
664 _offsetToPosition: function(offset) | 672 _offsetToPosition: function(offset) |
665 { | 673 { |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
749 } | 757 } |
750 | 758 |
751 this._pixelWindowWidth = this._offsetWidth - this._paddingLeft; | 759 this._pixelWindowWidth = this._offsetWidth - this._paddingLeft; |
752 this._totalPixels = Math.floor(this._pixelWindowWidth / this._windowWidt h); | 760 this._totalPixels = Math.floor(this._pixelWindowWidth / this._windowWidt h); |
753 this._pixelWindowLeft = Math.floor(this._totalPixels * this._windowLeft) ; | 761 this._pixelWindowLeft = Math.floor(this._totalPixels * this._windowLeft) ; |
754 this._pixelWindowRight = Math.floor(this._totalPixels * this._windowRigh t); | 762 this._pixelWindowRight = Math.floor(this._totalPixels * this._windowRigh t); |
755 | 763 |
756 this._timeToPixel = this._totalPixels / this._totalTime; | 764 this._timeToPixel = this._totalPixels / this._totalTime; |
757 this._pixelToTime = this._totalTime / this._totalPixels; | 765 this._pixelToTime = this._totalTime / this._totalPixels; |
758 this._paddingLeftTime = this._paddingLeft / this._timeToPixel; | 766 this._paddingLeftTime = this._paddingLeft / this._timeToPixel; |
767 | |
768 this._baseHeight = this._isTopDown ? WebInspector.FlameChart.DividersBar Height : this._offsetHeight - this._barHeight; | |
769 | |
770 var totalHeight = this._levelToHeight(this._dataProvider.maxStackDepth() ); | |
771 this._vScrollContent.style.height = totalHeight + "px"; | |
772 this._scrollTop = this._vScrollElement.scrollTop; | |
759 }, | 773 }, |
760 | 774 |
761 onResize: function() | 775 onResize: function() |
762 { | 776 { |
763 this._offsetWidth = this.element.offsetWidth; | 777 this._offsetWidth = this.element.offsetWidth - this._vScrollElement.offs etWidth; |
764 this._offsetHeight = this.element.offsetHeight; | 778 this._offsetHeight = this.element.offsetHeight; |
765 this._canvas.style.width = this._offsetWidth + "px"; | 779 this._canvas.style.width = this._offsetWidth + "px"; |
766 this._canvas.style.height = this._offsetHeight + "px"; | 780 this._canvas.style.height = this._offsetHeight + "px"; |
767 this._scheduleUpdate(); | 781 this._scheduleUpdate(); |
768 }, | 782 }, |
769 | 783 |
770 _scheduleUpdate: function() | 784 _scheduleUpdate: function() |
771 { | 785 { |
772 if (this._updateTimerId) | 786 if (this._updateTimerId) |
773 return; | 787 return; |
(...skipping 12 matching lines...) Expand all Loading... | |
786 }, | 800 }, |
787 | 801 |
788 reset: function() | 802 reset: function() |
789 { | 803 { |
790 this._highlightedEntryIndex = -1; | 804 this._highlightedEntryIndex = -1; |
791 this._selectedEntryIndex = -1; | 805 this._selectedEntryIndex = -1; |
792 this._textWidth = {}; | 806 this._textWidth = {}; |
793 this.update(); | 807 this.update(); |
794 }, | 808 }, |
795 | 809 |
796 __proto__: WebInspector.VBox.prototype | 810 __proto__: WebInspector.HBox.prototype |
797 } | 811 } |
OLD | NEW |