Chromium Code Reviews| 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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this), fal se); | 61 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this), fal se); |
| 62 this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), f alse); | 62 this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), f alse); |
| 63 this._canvas.addEventListener("click", this._onClick.bind(this), false); | 63 this._canvas.addEventListener("click", this._onClick.bind(this), false); |
| 64 WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind( this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "mov e", null); | 64 WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind( this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "mov e", null); |
| 65 | 65 |
| 66 this._vScrollElement = this.element.createChild("div", "flame-chart-v-scroll "); | 66 this._vScrollElement = this.element.createChild("div", "flame-chart-v-scroll "); |
| 67 this._vScrollContent = this._vScrollElement.createChild("div"); | 67 this._vScrollContent = this._vScrollElement.createChild("div"); |
| 68 this._vScrollElement.addEventListener("scroll", this.scheduleUpdate.bind(thi s), false); | 68 this._vScrollElement.addEventListener("scroll", this.scheduleUpdate.bind(thi s), false); |
| 69 | 69 |
| 70 this._entryInfo = this.element.createChild("div", "profile-entry-info"); | 70 this._entryInfo = this.element.createChild("div", "profile-entry-info"); |
| 71 this._markerHighlighElement = this.element.createChild("div", "flame-chart-m arker-highlight-element"); | |
| 71 this._highlightElement = this.element.createChild("div", "flame-chart-highli ght-element"); | 72 this._highlightElement = this.element.createChild("div", "flame-chart-highli ght-element"); |
| 72 this._selectedElement = this.element.createChild("div", "flame-chart-selecte d-element"); | 73 this._selectedElement = this.element.createChild("div", "flame-chart-selecte d-element"); |
| 73 | 74 |
| 74 this._dataProvider = dataProvider; | 75 this._dataProvider = dataProvider; |
| 75 | 76 |
| 76 this._windowLeft = 0.0; | 77 this._windowLeft = 0.0; |
| 77 this._windowRight = 1.0; | 78 this._windowRight = 1.0; |
| 78 this._windowWidth = 1.0; | 79 this._windowWidth = 1.0; |
| 79 this._timeWindowLeft = 0; | 80 this._timeWindowLeft = 0; |
| 80 this._timeWindowRight = Infinity; | 81 this._timeWindowRight = Infinity; |
| 81 this._barHeight = dataProvider.barHeight(); | 82 this._barHeight = dataProvider.barHeight(); |
| 82 this._barHeightDelta = this._isTopDown ? -this._barHeight : this._barHeight; | 83 this._barHeightDelta = this._isTopDown ? -this._barHeight : this._barHeight; |
| 83 this._minWidth = 1; | 84 this._minWidth = 1; |
| 84 this._paddingLeft = this._dataProvider.paddingLeft(); | 85 this._paddingLeft = this._dataProvider.paddingLeft(); |
| 85 this._markerPadding = 2; | 86 this._markerPadding = 2; |
| 86 this._markerRadius = this._barHeight / 2 - this._markerPadding; | 87 this._markerRadius = this._barHeight / 2 - this._markerPadding; |
| 88 this._highlightedMarkerIndex = -1; | |
| 87 this._highlightedEntryIndex = -1; | 89 this._highlightedEntryIndex = -1; |
| 88 this._selectedEntryIndex = -1; | 90 this._selectedEntryIndex = -1; |
| 89 this._textWidth = {}; | 91 this._textWidth = {}; |
| 90 } | 92 } |
| 91 | 93 |
| 92 WebInspector.FlameChart.DividersBarHeight = 20; | 94 WebInspector.FlameChart.DividersBarHeight = 20; |
| 93 | 95 |
| 94 /** | 96 /** |
| 95 * @interface | 97 * @interface |
| 96 */ | 98 */ |
| 97 WebInspector.FlameChartDataProvider = function() | 99 WebInspector.FlameChartDataProvider = function() |
| 98 { | 100 { |
| 99 } | 101 } |
| 100 | 102 |
| 101 /** @typedef {!{ | 103 /** |
| 102 entryLevels: (!Array.<number>|!Uint8Array), | 104 * @constructor |
| 103 entryTotalTimes: (!Array.<number>|!Float32Array), | 105 * @param {!Array.<number>|!Uint8Array} entryLevels |
| 104 entryStartTimes: (!Array.<number>|!Float64Array) | 106 * @param {!Array.<number>|!Float32Array} entryTotalTimes |
| 105 }} | 107 * @param {!Array.<number>|!Float64Array} entryStartTimes |
| 106 */ | 108 */ |
| 107 WebInspector.FlameChart.TimelineData; | 109 WebInspector.FlameChart.TimelineData = function(entryLevels, entryTotalTimes, en tryStartTimes) |
| 110 { | |
| 111 this.entryLevels = entryLevels; | |
| 112 this.entryTotalTimes = entryTotalTimes; | |
| 113 this.entryStartTimes = entryStartTimes; | |
| 114 /** @type {!Array.<number>} */ | |
| 115 this.markerTimestamps = []; | |
| 116 } | |
| 108 | 117 |
| 109 WebInspector.FlameChartDataProvider.prototype = { | 118 WebInspector.FlameChartDataProvider.prototype = { |
| 110 /** | 119 /** |
| 111 * @return {number} | 120 * @return {number} |
| 112 */ | 121 */ |
| 113 barHeight: function() { }, | 122 barHeight: function() { }, |
| 114 | 123 |
| 115 /** | 124 /** |
| 116 * @param {number} startTime | 125 * @param {number} startTime |
| 117 * @param {number} endTime | 126 * @param {number} endTime |
| 118 * @return {?Array.<number>} | 127 * @return {?Array.<number>} |
| 119 */ | 128 */ |
| 120 dividerOffsets: function(startTime, endTime) { }, | 129 dividerOffsets: function(startTime, endTime) { }, |
| 121 | 130 |
| 122 /** | 131 /** |
| 132 * @param {number} index | |
| 133 * @return {string} | |
| 134 */ | |
| 135 markerColor: function(index) { }, | |
| 136 | |
| 137 /** | |
| 138 * @param {number} index | |
| 139 * @return {string} | |
| 140 */ | |
| 141 markerTitle: function(index) { }, | |
| 142 | |
| 143 /** | |
| 123 * @return {number} | 144 * @return {number} |
| 124 */ | 145 */ |
| 125 minimumBoundary: function() { }, | 146 minimumBoundary: function() { }, |
| 126 | 147 |
| 127 /** | 148 /** |
| 128 * @return {number} | 149 * @return {number} |
| 129 */ | 150 */ |
| 130 totalTime: function() { }, | 151 totalTime: function() { }, |
| 131 | 152 |
| 132 /** | 153 /** |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 this._isDragging = false; | 469 this._isDragging = false; |
| 449 }, | 470 }, |
| 450 | 471 |
| 451 /** | 472 /** |
| 452 * @param {!Event} event | 473 * @param {!Event} event |
| 453 */ | 474 */ |
| 454 _onMouseMove: function(event) | 475 _onMouseMove: function(event) |
| 455 { | 476 { |
| 456 if (this._isDragging) | 477 if (this._isDragging) |
| 457 return; | 478 return; |
| 479 | |
| 480 var inDividersBar = event.offsetY < WebInspector.FlameChart.DividersBarH eight; | |
| 481 this._highlightedMarkerIndex = inDividersBar ? this._markerIndexAtPositi on(event.offsetX) : -1; | |
| 482 this._updateMarkerHighlight(); | |
| 483 if (inDividersBar) | |
| 484 return; | |
| 485 | |
| 458 var entryIndex = this._coordinatesToEntryIndex(event.offsetX, event.offs etY); | 486 var entryIndex = this._coordinatesToEntryIndex(event.offsetX, event.offs etY); |
| 459 | 487 |
| 460 if (this._highlightedEntryIndex === entryIndex) | 488 if (this._highlightedEntryIndex === entryIndex) |
| 461 return; | 489 return; |
| 462 | 490 |
| 463 if (entryIndex === -1 || !this._dataProvider.canJumpToEntry(entryIndex)) | 491 if (entryIndex === -1 || !this._dataProvider.canJumpToEntry(entryIndex)) |
| 464 this._canvas.style.cursor = "default"; | 492 this._canvas.style.cursor = "default"; |
| 465 else | 493 else |
| 466 this._canvas.style.cursor = "pointer"; | 494 this._canvas.style.cursor = "pointer"; |
| 467 | 495 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 555 } else { | 583 } else { |
| 556 cursorLevel = Math.floor((this._canvas.height / window.devicePixelRa tio - y) / this._barHeight); | 584 cursorLevel = Math.floor((this._canvas.height / window.devicePixelRa tio - y) / this._barHeight); |
| 557 offsetFromLevel = this._canvas.height / window.devicePixelRatio - cu rsorLevel * this._barHeight; | 585 offsetFromLevel = this._canvas.height / window.devicePixelRatio - cu rsorLevel * this._barHeight; |
| 558 } | 586 } |
| 559 var entryStartTimes = timelineData.entryStartTimes; | 587 var entryStartTimes = timelineData.entryStartTimes; |
| 560 var entryTotalTimes = timelineData.entryTotalTimes; | 588 var entryTotalTimes = timelineData.entryTotalTimes; |
| 561 var entryIndexes = this._timelineLevels[cursorLevel]; | 589 var entryIndexes = this._timelineLevels[cursorLevel]; |
| 562 if (!entryIndexes || !entryIndexes.length) | 590 if (!entryIndexes || !entryIndexes.length) |
| 563 return -1; | 591 return -1; |
| 564 | 592 |
| 593 /** | |
| 594 * @param {number} time | |
| 595 * @param {number} entryIndex | |
| 596 * @return {number} | |
| 597 */ | |
| 565 function comparator(time, entryIndex) | 598 function comparator(time, entryIndex) |
| 566 { | 599 { |
| 567 return time - entryStartTimes[entryIndex]; | 600 return time - entryStartTimes[entryIndex]; |
| 568 } | 601 } |
| 569 var indexOnLevel = Math.max(entryIndexes.upperBound(cursorTime, comparat or) - 1, 0); | 602 var indexOnLevel = Math.max(entryIndexes.upperBound(cursorTime, comparat or) - 1, 0); |
| 570 | 603 |
| 571 /** | 604 /** |
| 572 * @this {WebInspector.FlameChart} | 605 * @this {WebInspector.FlameChart} |
| 573 * @param {number} entryIndex | 606 * @param {number} entryIndex |
| 574 * @return {boolean} | 607 * @return {boolean} |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 592 var entryIndex = entryIndexes[indexOnLevel]; | 625 var entryIndex = entryIndexes[indexOnLevel]; |
| 593 if (checkEntryHit.call(this, entryIndex)) | 626 if (checkEntryHit.call(this, entryIndex)) |
| 594 return entryIndex; | 627 return entryIndex; |
| 595 entryIndex = entryIndexes[indexOnLevel + 1]; | 628 entryIndex = entryIndexes[indexOnLevel + 1]; |
| 596 if (checkEntryHit.call(this, entryIndex)) | 629 if (checkEntryHit.call(this, entryIndex)) |
| 597 return entryIndex; | 630 return entryIndex; |
| 598 return -1; | 631 return -1; |
| 599 }, | 632 }, |
| 600 | 633 |
| 601 /** | 634 /** |
| 635 * @param {number} x | |
| 636 * @return {number} | |
| 637 */ | |
| 638 _markerIndexAtPosition: function(x) | |
| 639 { | |
| 640 var markers = this._timelineData().markerTimestamps; | |
| 641 if (!markers) | |
| 642 return -1; | |
| 643 var accurracyOffsetPx = 1; | |
| 644 var time = this._cursorTime(x); | |
| 645 var leftTime = this._cursorTime(x - accurracyOffsetPx); | |
| 646 var rightTime = this._cursorTime(x + accurracyOffsetPx); | |
| 647 | |
| 648 /** | |
| 649 * @param {number} time | |
| 650 * @param {number} markerTimestamp | |
| 651 * @return {number} | |
| 652 */ | |
| 653 function comparator(time, markerTimestamp) | |
| 654 { | |
| 655 return time - markerTimestamp; | |
| 656 } | |
| 657 var left = markers.lowerBound(leftTime, comparator); | |
| 658 var markerIndex = -1; | |
| 659 var distance = Infinity; | |
| 660 for (var i = left; i < markers.length; i++) { | |
| 661 if (markers[i] > rightTime) | |
|
alph
2014/07/21 14:21:07
nit: you can move the check into the for condition
yurys
2014/07/21 14:30:00
Done.
| |
| 662 break; | |
| 663 var nextDistance = Math.abs(markers[i] - time); | |
| 664 if (nextDistance < distance) { | |
| 665 markerIndex = i; | |
| 666 distance = nextDistance; | |
| 667 } | |
| 668 } | |
| 669 return markerIndex; | |
| 670 }, | |
| 671 | |
| 672 /** | |
| 602 * @param {number} height | 673 * @param {number} height |
| 603 * @param {number} width | 674 * @param {number} width |
| 604 */ | 675 */ |
| 605 _draw: function(width, height) | 676 _draw: function(width, height) |
| 606 { | 677 { |
| 607 var timelineData = this._timelineData(); | 678 var timelineData = this._timelineData(); |
| 608 if (!timelineData) | 679 if (!timelineData) |
| 609 return; | 680 return; |
| 610 | 681 |
| 611 var context = this._canvas.getContext("2d"); | 682 var context = this._canvas.getContext("2d"); |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 if (!text || !text.length) | 810 if (!text || !text.length) |
| 740 continue; | 811 continue; |
| 741 | 812 |
| 742 context.fillStyle = this._dataProvider.textColor(entryIndex); | 813 context.fillStyle = this._dataProvider.textColor(entryIndex); |
| 743 context.fillText(text, barX + textPadding, textBaseHeight - barLevel * this._barHeightDelta); | 814 context.fillText(text, barX + textPadding, textBaseHeight - barLevel * this._barHeightDelta); |
| 744 } | 815 } |
| 745 context.restore(); | 816 context.restore(); |
| 746 | 817 |
| 747 var offsets = this._dataProvider.dividerOffsets(this._calculator.minimum Boundary(), this._calculator.maximumBoundary()); | 818 var offsets = this._dataProvider.dividerOffsets(this._calculator.minimum Boundary(), this._calculator.maximumBoundary()); |
| 748 WebInspector.TimelineGrid.drawCanvasGrid(this._canvas, this._calculator, offsets); | 819 WebInspector.TimelineGrid.drawCanvasGrid(this._canvas, this._calculator, offsets); |
| 820 this._drawMarkers(); | |
| 749 | 821 |
| 750 this._updateElementPosition(this._highlightElement, this._highlightedEnt ryIndex); | 822 this._updateElementPosition(this._highlightElement, this._highlightedEnt ryIndex); |
| 751 this._updateElementPosition(this._selectedElement, this._selectedEntryIn dex); | 823 this._updateElementPosition(this._selectedElement, this._selectedEntryIn dex); |
| 824 this._updateMarkerHighlight(); | |
| 825 }, | |
| 826 | |
| 827 _drawMarkers: function() | |
| 828 { | |
| 829 var markerTimestamps = this._timelineData().markerTimestamps; | |
| 830 /** | |
| 831 * @param {number} time | |
| 832 * @param {number} markerTimestamp | |
| 833 * @return {number} | |
| 834 */ | |
| 835 function compare(time, markerTimestamp) | |
| 836 { | |
| 837 return time - markerTimestamp; | |
| 838 } | |
| 839 var left = markerTimestamps.lowerBound(this._calculator.minimumBoundary( ), compare); | |
| 840 var right = markerTimestamps.upperBound(this._calculator.maximumBoundary (), compare); | |
|
alph
2014/07/21 14:21:07
nit: you don't really need to calculate it. you ca
yurys
2014/07/21 14:30:00
Done.
| |
| 841 | |
| 842 var context = this._canvas.getContext("2d"); | |
| 843 context.save(); | |
| 844 var ratio = window.devicePixelRatio; | |
| 845 context.scale(ratio, ratio); | |
| 846 var height = WebInspector.FlameChart.DividersBarHeight - 1; | |
| 847 context.lineWidth = 2; | |
| 848 for (var i = left; i < right; i++) { | |
| 849 var timestamp = markerTimestamps[i]; | |
| 850 var position = this._calculator.computePosition(timestamp); | |
| 851 context.strokeStyle = this._dataProvider.markerColor(i); | |
| 852 context.beginPath(); | |
| 853 context.moveTo(position, 0); | |
| 854 context.lineTo(position, height); | |
| 855 context.stroke(); | |
| 856 } | |
| 857 context.restore(); | |
| 858 }, | |
| 859 | |
| 860 _updateMarkerHighlight: function() | |
| 861 { | |
| 862 var element = this._markerHighlighElement; | |
| 863 if (element.parentElement) | |
| 864 element.remove(); | |
| 865 var markerIndex = this._highlightedMarkerIndex; | |
| 866 if (markerIndex === -1) | |
| 867 return; | |
| 868 var barX = this._timeToPosition(this._timelineData().markerTimestamps[ma rkerIndex]); | |
| 869 element.title = this._dataProvider.markerTitle(markerIndex); | |
| 870 var style = element.style; | |
| 871 style.left = barX + "px"; | |
| 872 style.backgroundColor = this._dataProvider.markerColor(markerIndex); | |
| 873 this.element.appendChild(element); | |
| 752 }, | 874 }, |
| 753 | 875 |
| 754 /** | 876 /** |
| 755 * @param {?WebInspector.FlameChart.TimelineData} timelineData | 877 * @param {?WebInspector.FlameChart.TimelineData} timelineData |
| 756 */ | 878 */ |
| 757 _processTimelineData: function(timelineData) | 879 _processTimelineData: function(timelineData) |
| 758 { | 880 { |
| 759 if (!timelineData) { | 881 if (!timelineData) { |
| 760 this._timelineLevels = null; | 882 this._timelineLevels = null; |
| 761 this._rawTimelineData = null; | 883 this._rawTimelineData = null; |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 946 if (!this._timelineData()) | 1068 if (!this._timelineData()) |
| 947 return; | 1069 return; |
| 948 this._resetCanvas(); | 1070 this._resetCanvas(); |
| 949 this._updateBoundaries(); | 1071 this._updateBoundaries(); |
| 950 this._calculator._updateBoundaries(this); | 1072 this._calculator._updateBoundaries(this); |
| 951 this._draw(this._offsetWidth, this._offsetHeight); | 1073 this._draw(this._offsetWidth, this._offsetHeight); |
| 952 }, | 1074 }, |
| 953 | 1075 |
| 954 reset: function() | 1076 reset: function() |
| 955 { | 1077 { |
| 1078 this._highlightedMarkerIndex = -1; | |
| 956 this._highlightedEntryIndex = -1; | 1079 this._highlightedEntryIndex = -1; |
| 957 this._selectedEntryIndex = -1; | 1080 this._selectedEntryIndex = -1; |
| 958 this._textWidth = {}; | 1081 this._textWidth = {}; |
| 959 this.update(); | 1082 this.update(); |
| 960 }, | 1083 }, |
| 961 | 1084 |
| 962 __proto__: WebInspector.HBox.prototype | 1085 __proto__: WebInspector.HBox.prototype |
| 963 } | 1086 } |
| OLD | NEW |