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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 /** | 101 /** |
| 102 * @interface | 102 * @interface |
| 103 */ | 103 */ |
| 104 WebInspector.FlameChartDataProvider = function() | 104 WebInspector.FlameChartDataProvider = function() |
| 105 { | 105 { |
| 106 } | 106 } |
| 107 | 107 |
| 108 /** @typedef {!{ | 108 /** @typedef {!{ |
| 109 entryLevels: !Array.<number>, | 109 entryLevels: !Array.<number>, |
| 110 entryTotalTimes: !Array.<number>, | 110 entryTotalTimes: !Array.<number>, |
| 111 entryOffsets: !Array.<number>, | 111 entryOffsets: !Array.<number> |
| 112 colorEntryIndexes: !Array.<number> | |
| 113 }} | 112 }} |
| 114 */ | 113 */ |
| 115 WebInspector.FlameChart.TimelineData; | 114 WebInspector.FlameChart.TimelineData; |
| 116 | 115 |
| 117 WebInspector.FlameChartDataProvider.prototype = { | 116 WebInspector.FlameChartDataProvider.prototype = { |
| 118 /** | 117 /** |
| 119 * @return {number} | 118 * @return {number} |
| 120 */ | 119 */ |
| 121 barHeight: function() { }, | 120 barHeight: function() { }, |
| 122 | 121 |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 141 * @return {number} | 140 * @return {number} |
| 142 */ | 141 */ |
| 143 maxStackDepth: function() { }, | 142 maxStackDepth: function() { }, |
| 144 | 143 |
| 145 /** | 144 /** |
| 146 * @return {?WebInspector.FlameChart.TimelineData} | 145 * @return {?WebInspector.FlameChart.TimelineData} |
| 147 */ | 146 */ |
| 148 timelineData: function() { }, | 147 timelineData: function() { }, |
| 149 | 148 |
| 150 /** | 149 /** |
| 151 * @return {!WebInspector.FlameChart.ColorGenerator} | |
| 152 */ | |
| 153 colorGenerator: function() { }, | |
| 154 | |
| 155 /** | |
| 156 * @param {number} entryIndex | 150 * @param {number} entryIndex |
| 157 * @return {?Array.<!{title: string, text: string}>} | 151 * @return {?Array.<!{title: string, text: string}>} |
| 158 */ | 152 */ |
| 159 prepareHighlightedEntryInfo: function(entryIndex) { }, | 153 prepareHighlightedEntryInfo: function(entryIndex) { }, |
| 160 | 154 |
| 161 /** | 155 /** |
| 162 * @param {number} entryIndex | 156 * @param {number} entryIndex |
| 163 * @return {boolean} | 157 * @return {boolean} |
| 164 */ | 158 */ |
| 165 canJumpToEntry: function(entryIndex) { }, | 159 canJumpToEntry: function(entryIndex) { }, |
| 166 | 160 |
| 167 /** | 161 /** |
| 168 * @param {number} entryIndex | 162 * @param {number} entryIndex |
| 169 * @return {?Object} | 163 * @return {?Object} |
| 170 */ | 164 */ |
| 171 entryData: function(entryIndex) { }, | 165 entryData: function(entryIndex) { }, |
| 172 | 166 |
| 173 /** | 167 /** |
| 174 * @param {number} entryIndex | 168 * @param {number} entryIndex |
| 175 * @return {?string} | 169 * @return {?string} |
| 176 */ | 170 */ |
| 177 entryTitle: function(entryIndex) { }, | 171 entryTitle: function(entryIndex) { }, |
| 178 | 172 |
| 179 /** | 173 /** |
| 180 * @param {number} entryIndex | 174 * @param {number} entryIndex |
| 181 * @return {?string} | 175 * @return {?string} |
| 182 */ | 176 */ |
| 183 entryFont: function(entryIndex) { }, | 177 entryFont: function(entryIndex) { }, |
| 178 | |
| 179 /** | |
| 180 * @param {number} entryIndex | |
| 181 * @return {!string} | |
| 182 */ | |
| 183 entryColor: function(entryIndex) { }, | |
| 184 } | 184 } |
| 185 | 185 |
| 186 /** | 186 /** |
| 187 * @constructor | 187 * @constructor |
| 188 * @implements {WebInspector.TimelineGrid.Calculator} | 188 * @implements {WebInspector.TimelineGrid.Calculator} |
| 189 */ | 189 */ |
| 190 WebInspector.FlameChart.Calculator = function() | 190 WebInspector.FlameChart.Calculator = function() |
| 191 { | 191 { |
| 192 this._paddingLeft = 0; | 192 this._paddingLeft = 0; |
| 193 } | 193 } |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 356 WebInspector.FlameChart.Events = { | 356 WebInspector.FlameChart.Events = { |
| 357 EntrySelected: "EntrySelected" | 357 EntrySelected: "EntrySelected" |
| 358 } | 358 } |
| 359 | 359 |
| 360 /** | 360 /** |
| 361 * @constructor | 361 * @constructor |
| 362 */ | 362 */ |
| 363 WebInspector.FlameChart.ColorGenerator = function() | 363 WebInspector.FlameChart.ColorGenerator = function() |
| 364 { | 364 { |
| 365 this._colors = {}; | 365 this._colors = {}; |
| 366 this._colorIndexes = []; | |
| 367 this._currentColorIndex = 0; | 366 this._currentColorIndex = 0; |
| 368 } | 367 } |
| 369 | 368 |
| 370 WebInspector.FlameChart.ColorGenerator.prototype = { | 369 WebInspector.FlameChart.ColorGenerator.prototype = { |
| 371 /** | 370 /** |
| 372 * @param {string} id | 371 * @param {string} id |
| 373 * @param {string|!CanvasGradient} color | 372 * @param {string|!CanvasGradient} color |
| 374 */ | 373 */ |
| 375 setColorForID: function(id, color) | 374 setColorForID: function(id, color) |
| 376 { | 375 { |
| 377 var colorData = {index: this._currentColorIndex++, color: color}; | 376 this._colors[id] = color; |
| 378 this._colors[id] = colorData; | |
| 379 this._colorIndexes[colorData.index] = colorData; | |
| 380 }, | 377 }, |
| 381 | 378 |
| 382 /** | 379 /** |
| 383 * @param {!string} id | 380 * @param {!string} id |
| 384 * @param {number=} sat | 381 * @param {number=} sat |
| 385 * @return {!Object} | 382 * @return {!string} |
| 386 */ | 383 */ |
| 387 colorForID: function(id, sat) | 384 colorForID: function(id, sat) |
| 388 { | 385 { |
| 389 if (typeof sat !== "number") | 386 if (typeof sat !== "number") |
| 390 sat = 100; | 387 sat = 100; |
| 391 var colors = this._colors; | 388 var color = this._colors[id]; |
| 392 var color = colors[id]; | |
| 393 if (!color) { | 389 if (!color) { |
| 394 colors[id] = color = this._createColor(this._currentColorIndex++, sa t); | 390 color = this._createColor(this._currentColorIndex++, sat); |
| 395 this._colorIndexes[color.index] = color; | 391 this._colors[id] = color; |
| 396 } | 392 } |
| 397 return color; | 393 return color; |
| 398 }, | 394 }, |
| 399 | 395 |
| 400 /** | 396 /** |
| 401 * @param {!number} index | 397 * @param {!number} index |
| 402 */ | |
| 403 _colorForIndex: function(index) | |
| 404 { | |
| 405 return this._colorIndexes[index]; | |
| 406 }, | |
| 407 | |
| 408 /** | |
| 409 * @param {!number} index | |
| 410 * @param {!number} sat | 398 * @param {!number} sat |
| 411 */ | 399 */ |
| 412 _createColor: function(index, sat) | 400 _createColor: function(index, sat) |
| 413 { | 401 { |
| 414 var hue = (index * 7 + 12 * (index % 2)) % 360; | 402 var hue = (index * 7 + 12 * (index % 2)) % 360; |
| 415 return {index: index, color: "hsla(" + hue + ", " + sat + "%, 66%, 0.7)" }; | 403 return "hsla(" + hue + ", " + sat + "%, 66%, 0.7)"; |
| 416 } | 404 } |
| 417 } | 405 } |
| 418 | 406 |
| 419 /** | 407 /** |
| 420 * @constructor | 408 * @constructor |
| 421 * @extends {WebInspector.View} | 409 * @extends {WebInspector.View} |
| 422 * @implements {WebInspector.TimeRangeController} | 410 * @implements {WebInspector.TimeRangeController} |
| 423 * @param {!WebInspector.FlameChartDataProvider} dataProvider | 411 * @param {!WebInspector.FlameChartDataProvider} dataProvider |
| 424 */ | 412 */ |
| 425 WebInspector.FlameChart.OverviewPane = function(dataProvider) | 413 WebInspector.FlameChart.OverviewPane = function(dataProvider) |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 811 if (!timelineData) | 799 if (!timelineData) |
| 812 return; | 800 return; |
| 813 var ratio = window.devicePixelRatio; | 801 var ratio = window.devicePixelRatio; |
| 814 this._canvas.width = width * ratio; | 802 this._canvas.width = width * ratio; |
| 815 this._canvas.height = height * ratio; | 803 this._canvas.height = height * ratio; |
| 816 this._canvas.style.width = width + "px"; | 804 this._canvas.style.width = width + "px"; |
| 817 this._canvas.style.height = height + "px"; | 805 this._canvas.style.height = height + "px"; |
| 818 | 806 |
| 819 var context = this._canvas.getContext("2d"); | 807 var context = this._canvas.getContext("2d"); |
| 820 context.scale(ratio, ratio); | 808 context.scale(ratio, ratio); |
| 821 var timeWindowRight = this._timeWindowRight; | 809 var timeWindowRight = this._timeWindowRight - this._zeroTime; |
| 810 var timeWindowLeft = this._timeWindowLeft - this._zeroTime; | |
| 822 var timeToPixel = this._timeToPixel; | 811 var timeToPixel = this._timeToPixel; |
| 823 var pixelWindowLeft = this._pixelWindowLeft; | 812 var pixelWindowLeft = this._pixelWindowLeft; |
| 824 var paddingLeft = this._paddingLeft; | 813 var paddingLeft = this._paddingLeft; |
| 825 var minWidth = this._minWidth; | 814 var minWidth = this._minWidth; |
| 826 var entryTotalTimes = timelineData.entryTotalTimes; | 815 var entryTotalTimes = timelineData.entryTotalTimes; |
| 827 var entryOffsets = timelineData.entryOffsets; | 816 var entryOffsets = timelineData.entryOffsets; |
| 828 var entryLevels = timelineData.entryLevels; | 817 var entryLevels = timelineData.entryLevels; |
| 829 var colorEntryIndexes = timelineData.colorEntryIndexes; | |
| 830 | 818 |
| 831 var colorGenerator = this._dataProvider.colorGenerator(); | |
| 832 var titleIndexes = new Uint32Array(timelineData.entryTotalTimes); | 819 var titleIndexes = new Uint32Array(timelineData.entryTotalTimes); |
| 833 var lastTitleIndex = 0; | 820 var lastTitleIndex = 0; |
| 834 var dotsWidth = context.measureText("\u2026").width; | 821 var dotsWidth = context.measureText("\u2026").width; |
| 835 var textPaddingLeft = 2; | 822 var textPaddingLeft = 2; |
| 836 this._minTextWidth = context.measureText("\u2026").width + textPaddingLe ft; | 823 this._minTextWidth = context.measureText("\u2026").width + textPaddingLe ft; |
| 837 var minTextWidth = this._minTextWidth; | 824 var minTextWidth = this._minTextWidth; |
| 838 | 825 |
| 839 var marksField = []; | 826 var marksField = []; |
| 840 for (var i = 0; i < this._dataProvider.maxStackDepth(); ++i) | 827 for (var i = 0; i < this._dataProvider.maxStackDepth(); ++i) |
| 841 marksField.push(new Uint16Array(width)); | 828 marksField.push(new Uint16Array(width)); |
| 829 var marksRow; | |
| 842 | 830 |
| 843 var barX = 0; | 831 var barX = 0; |
| 832 var barY = 0; | |
| 844 var barWidth = 0; | 833 var barWidth = 0; |
| 845 var barRight = 0; | 834 var barRight = 0; |
| 846 var barLevel = 0; | 835 var barLevel = 0; |
| 836 var barHeight = this._barHeight; | |
| 847 this._baseHeight = this._isTopDown ? WebInspector.FlameChart.DividersBar Height : height - this._barHeight; | 837 this._baseHeight = this._isTopDown ? WebInspector.FlameChart.DividersBar Height : height - this._barHeight; |
| 848 context.strokeStyle = "black"; | 838 context.strokeStyle = "black"; |
| 849 var color; | 839 var color; |
| 850 var entryIndex = 0; | 840 var entryIndex = 0; |
| 851 var entryOffset = 0; | 841 var entryOffset = 0; |
| 852 for (var colorIndex = 0; colorIndex < colorEntryIndexes.length; ++colorI ndex) { | 842 |
| 853 color = colorGenerator._colorForIndex(colorIndex); | 843 var colorBackets = {}; |
| 854 context.fillStyle = color.color; | 844 var colors = []; |
| 855 var indexes = colorEntryIndexes[colorIndex]; | 845 var backet = []; |
| 856 if (!indexes) | 846 |
| 847 var textBaseHeight = this._baseHeight + this._barHeight - 4; | |
| 848 var lastUsedFont = ""; | |
| 849 var font; | |
| 850 var text = ""; | |
| 851 var xText = 0; | |
| 852 var widthText = 0; | |
| 853 var title = ""; | |
| 854 | |
| 855 var entryOffsetRight = 0; | |
| 856 var maxBarLevel = height / this._barHeight; | |
| 857 for (entryIndex = 0; entryIndex < entryOffsets.length; ++entryIndex) { | |
| 858 // stop if we reached right border in time (entries were ordered by start time). | |
| 859 entryOffset = entryOffsets[entryIndex]; | |
| 860 if (entryOffset > timeWindowRight) | |
| 861 break; | |
| 862 | |
| 863 // skip if it is not visible (top/bottom side) | |
| 864 barLevel = entryLevels[entryIndex]; | |
| 865 if (barLevel > maxBarLevel) | |
| 857 continue; | 866 continue; |
| 867 | |
| 868 // skip if it is not visible (left side). | |
| 869 entryOffsetRight = entryOffset + entryTotalTimes[entryIndex]; | |
| 870 if (entryOffsetRight < timeWindowLeft) | |
|
alph
2014/03/03 10:06:04
Is it possible to find the bound using binary sear
loislo
2014/03/03 11:53:31
Nope. The array is sorted by the bar offset, so th
alph
2014/03/03 12:31:04
So, you can find the right window bound then, whic
| |
| 871 continue; | |
| 872 | |
| 873 barX = this._offsetToPosition(entryOffset); | |
| 874 barRight = this._offsetToPosition(entryOffsetRight); | |
| 875 barWidth = (barRight - barX) || minWidth; | |
|
alph
2014/03/03 10:06:04
nit: Should be Math.max
loislo
2014/03/03 11:53:31
Done.
| |
| 876 | |
| 877 // skip the bar if there is another bar here on the same level with the same or longer length. | |
| 878 marksRow = marksField[barLevel]; | |
| 879 if (barWidth <= marksRow[barX]) | |
| 880 continue; | |
| 881 | |
| 882 marksRow[barX] = barWidth; | |
| 883 color = this._dataProvider.entryColor(entryIndex); | |
| 884 backet = colorBackets[color]; | |
| 885 if (!backet) | |
| 886 backet = colorBackets[color] = []; | |
| 887 backet.push(entryIndex); | |
| 888 } | |
| 889 | |
| 890 colors = Object.keys(colorBackets); | |
| 891 for (var c = 0; c < colors.length; ++c) { | |
| 892 color = colors[c]; | |
| 893 context.fillStyle = color; | |
| 894 var indexes = colorBackets[color]; | |
| 858 context.beginPath(); | 895 context.beginPath(); |
| 859 for (var i = 0; i < indexes.length; ++i) { | 896 for (var i = 0; i < indexes.length; ++i) { |
| 860 entryIndex = indexes[i]; | 897 entryIndex = indexes[i]; |
| 861 entryOffset = entryOffsets[entryIndex]; | 898 entryOffset = entryOffsets[entryIndex]; |
| 862 if (entryOffset > timeWindowRight) | |
| 863 break; | |
| 864 barX = this._offsetToPosition(entryOffset); | 899 barX = this._offsetToPosition(entryOffset); |
| 865 if (barX >= width) | |
| 866 continue; | |
| 867 barRight = this._offsetToPosition(entryOffset + entryTotalTimes[ entryIndex]); | 900 barRight = this._offsetToPosition(entryOffset + entryTotalTimes[ entryIndex]); |
| 868 if (barRight < 0) | |
| 869 continue; | |
| 870 barWidth = (barRight - barX) || minWidth; | 901 barWidth = (barRight - barX) || minWidth; |
|
alph
2014/03/03 10:06:04
ditto.
loislo
2014/03/03 11:53:31
Done.
| |
| 871 barLevel = entryLevels[entryIndex]; | 902 barLevel = entryLevels[entryIndex]; |
| 872 var marksRow = marksField[barLevel]; | 903 barY = this._levelToHeight(barLevel); |
| 873 if (barWidth <= marksRow[barX]) // skip the bar if there is anot her bar here. | |
| 874 continue; | |
| 875 marksRow[barX] = barWidth; | |
| 876 var barY = this._levelToHeight(barLevel); | |
| 877 context.rect(barX, barY, barWidth, this._barHeight); | 904 context.rect(barX, barY, barWidth, this._barHeight); |
| 878 if (barWidth > minTextWidth) | 905 if (barWidth > minTextWidth) |
| 879 titleIndexes[lastTitleIndex++] = entryIndex; | 906 titleIndexes[lastTitleIndex++] = entryIndex; |
| 880 } | 907 } |
| 881 context.fill(); | 908 context.fill(); |
| 882 } | 909 } |
| 883 | 910 |
| 884 context.textBaseline = "alphabetic"; | 911 context.textBaseline = "alphabetic"; |
| 885 context.fillStyle = "#333"; | 912 context.fillStyle = "#333"; |
| 886 this._dotsWidth = context.measureText("\u2026").width; | 913 this._dotsWidth = context.measureText("\u2026").width; |
| 887 | 914 |
| 888 var textBaseHeight = this._baseHeight + this._barHeight - 4; | |
| 889 var lastUsedFont = ""; | |
| 890 var font; | |
| 891 for (var i = 0; i < lastTitleIndex; ++i) { | 915 for (var i = 0; i < lastTitleIndex; ++i) { |
| 892 entryIndex = titleIndexes[i]; | 916 entryIndex = titleIndexes[i]; |
| 893 var text = this._dataProvider.entryTitle(entryIndex); | 917 text = this._dataProvider.entryTitle(entryIndex); |
| 894 if (!text || !text.length) | 918 if (!text || !text.length) |
| 895 continue; | 919 continue; |
| 896 font = this._dataProvider.entryFont(entryIndex); | 920 font = this._dataProvider.entryFont(entryIndex); |
| 897 if (font !== lastUsedFont) | 921 if (font !== lastUsedFont) |
| 898 context.font = font; | 922 context.font = font; |
| 899 | 923 |
| 900 entryOffset = entryOffsets[entryIndex]; | 924 entryOffset = entryOffsets[entryIndex]; |
| 901 barX = this._offsetToPosition(entryOffset); | 925 barX = this._offsetToPosition(entryOffset); |
| 902 barRight = this._offsetToPosition(entryOffset + entryTotalTimes[entr yIndex]); | 926 barRight = this._offsetToPosition(entryOffset + entryTotalTimes[entr yIndex]); |
| 903 barWidth = (barRight - barX) || minWidth; | 927 barWidth = (barRight - barX) || minWidth; |
|
alph
2014/03/03 10:06:04
ditto
loislo
2014/03/03 11:53:31
Done.
| |
| 904 var xText = Math.max(0, barX); | 928 xText = Math.max(0, barX); |
| 905 var widthText = barWidth - textPaddingLeft + barX - xText; | 929 widthText = barWidth - textPaddingLeft + barX - xText; |
| 906 var title = this._prepareText(context, text, widthText); | 930 title = this._prepareText(context, text, widthText); |
| 907 if (title) | 931 if (title) |
| 908 context.fillText(title, xText + textPaddingLeft, textBaseHeight - entryLevels[entryIndex] * this._barHeightDelta); | 932 context.fillText(title, xText + textPaddingLeft, textBaseHeight - entryLevels[entryIndex] * this._barHeightDelta); |
| 909 } | 933 } |
| 910 | 934 |
| 911 this._updateHighlightElement(); | 935 this._updateHighlightElement(); |
| 912 }, | 936 }, |
| 913 | 937 |
| 914 _updateHighlightElement: function() | 938 _updateHighlightElement: function() |
| 915 { | 939 { |
| 916 if (this._highlightElement.parentElement) | 940 if (this._highlightElement.parentElement) |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1049 this._timelineGrid.hideDividers(); | 1073 this._timelineGrid.hideDividers(); |
| 1050 this.draw(this.element.clientWidth, this.element.clientHeight); | 1074 this.draw(this.element.clientWidth, this.element.clientHeight); |
| 1051 this._calculator._updateBoundaries(this); | 1075 this._calculator._updateBoundaries(this); |
| 1052 this._timelineGrid.element.style.width = this.element.clientWidth; | 1076 this._timelineGrid.element.style.width = this.element.clientWidth; |
| 1053 var offsets = this._dataProvider.dividerOffsets(this._calculator.minimum Boundary(), this._calculator.maximumBoundary()); | 1077 var offsets = this._dataProvider.dividerOffsets(this._calculator.minimum Boundary(), this._calculator.maximumBoundary()); |
| 1054 this._timelineGrid.updateDividers(this._calculator, offsets, true); | 1078 this._timelineGrid.updateDividers(this._calculator, offsets, true); |
| 1055 }, | 1079 }, |
| 1056 | 1080 |
| 1057 __proto__: WebInspector.View.prototype | 1081 __proto__: WebInspector.View.prototype |
| 1058 } | 1082 } |
| OLD | NEW |