Commit 01594211 authored by loislo@chromium.org's avatar loislo@chromium.org

TimelineFlameChart: selectRecord implementation.

BUG=349392
R=pfeldman@chromium.org

Review URL: https://codereview.chromium.org/183763036

git-svn-id: svn://svn.chromium.org/blink/trunk@168484 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 29010da6
......@@ -386,8 +386,8 @@ WebInspector.CPUProfileView.prototype = {
{
if (this._flameChart)
return;
var dataProvider = new WebInspector.CPUFlameChartDataProvider(this);
this._flameChart = new WebInspector.FlameChart(dataProvider);
this._dataProvider = new WebInspector.CPUFlameChartDataProvider(this);
this._flameChart = new WebInspector.FlameChart(this._dataProvider);
this._flameChart.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected.bind(this));
},
......@@ -396,7 +396,8 @@ WebInspector.CPUProfileView.prototype = {
*/
_onEntrySelected: function(event)
{
var node = event.data;
var entryIndex = event.data;
var node = this._dataProvider._entryNodes[entryIndex];
if (!node || !node.scriptId)
return;
var script = WebInspector.debuggerModel.scriptForId(node.scriptId)
......@@ -1329,21 +1330,25 @@ WebInspector.CPUFlameChartDataProvider.prototype = {
/**
* @param {number} entryIndex
* @return {!Object}
* @return {!string}
*/
entryData: function(entryIndex)
entryColor: function(entryIndex)
{
return this._entryNodes[entryIndex];
var node = this._entryNodes[entryIndex];
return this._colorGenerator.colorForID(node.functionName + ":" + node.url + ":" + node.lineNumber);;
},
/**
* @param {number} entryIndex
* @return {!string}
* @return {!{startTimeOffset: number, endTimeOffset: number}}
*/
entryColor: function(entryIndex)
highlightTimeRange: function(entryIndex)
{
var node = this._entryNodes[entryIndex];
return this._colorGenerator.colorForID(node.functionName + ":" + node.url + ":" + node.lineNumber);;
var startTimeOffset = this._timelineData.entryOffsets[entryIndex];
return {
startTimeOffset: startTimeOffset,
endTimeOffset: startTimeOffset + this._timelineData.entryTotalTimes[entryIndex]
};
},
/**
......
......@@ -31,14 +31,14 @@
/**
* @interface
*/
WebInspector.TimeRangeController = function() { }
WebInspector.FlameChartDelegate = function() { }
WebInspector.TimeRangeController.prototype = {
WebInspector.FlameChartDelegate.prototype = {
/**
* @param {number} startTime
* @param {number} endTime
*/
requestWindowTimes: function(startTime, endTime) { }
requestWindowTimes: function(startTime, endTime) { },
}
/**
......@@ -158,12 +158,6 @@ WebInspector.FlameChartDataProvider.prototype = {
*/
canJumpToEntry: function(entryIndex) { },
/**
* @param {number} entryIndex
* @return {?Object}
*/
entryData: function(entryIndex) { },
/**
* @param {number} entryIndex
* @return {?string}
......@@ -196,7 +190,12 @@ WebInspector.FlameChartDataProvider.prototype = {
/**
* @return {number}
*/
textPadding: function() { }
textPadding: function() { },
/**
* @return {!{startTimeOffset: number, endTimeOffset: number}}
*/
highlightTimeRange: function(entryIndex) { }
}
/**
......@@ -423,7 +422,7 @@ WebInspector.FlameChart.ColorGenerator.prototype = {
/**
* @constructor
* @extends {WebInspector.View}
* @implements {WebInspector.TimeRangeController}
* @implements {WebInspector.FlameChartDelegate}
* @param {!WebInspector.FlameChartDataProvider} dataProvider
*/
WebInspector.FlameChart.OverviewPane = function(dataProvider)
......@@ -575,15 +574,15 @@ WebInspector.FlameChart.OverviewPane.drawOverviewCanvas = function(dataProvider,
* @constructor
* @extends {WebInspector.View}
* @param {!WebInspector.FlameChartDataProvider} dataProvider
* @param {!WebInspector.TimeRangeController} timeRangeController
* @param {!WebInspector.FlameChartDelegate} flameChartDelegate
* @param {boolean} isTopDown
* @param {boolean} timeBasedWindow
*/
WebInspector.FlameChart.MainPane = function(dataProvider, timeRangeController, isTopDown, timeBasedWindow)
WebInspector.FlameChart.MainPane = function(dataProvider, flameChartDelegate, isTopDown, timeBasedWindow)
{
WebInspector.View.call(this);
this.element.classList.add("flame-chart-main-pane");
this._timeRangeController = timeRangeController;
this._flameChartDelegate = flameChartDelegate;
this._isTopDown = isTopDown;
this._timeBasedWindow = timeBasedWindow;
......@@ -599,6 +598,7 @@ WebInspector.FlameChart.MainPane = function(dataProvider, timeRangeController, i
this._entryInfo = this.element.createChild("div", "profile-entry-info");
this._highlightElement = this.element.createChild("div", "flame-chart-highlight-element");
this._selectedElement = this.element.createChild("div", "flame-chart-selected-element");
this._dataProvider = dataProvider;
......@@ -612,6 +612,7 @@ WebInspector.FlameChart.MainPane = function(dataProvider, timeRangeController, i
this._minWidth = 1;
this._paddingLeft = 15;
this._highlightedEntryIndex = -1;
this._selectedEntryIndex = -1;
}
WebInspector.FlameChart.MainPane.prototype = {
......@@ -682,7 +683,7 @@ WebInspector.FlameChart.MainPane.prototype = {
);
var windowLeft = this._dragStartWindowLeft + timeShift;
var windowRight = this._dragStartWindowRight + timeShift;
this._timeRangeController.requestWindowTimes(windowLeft, windowRight);
this._flameChartDelegate.requestWindowTimes(windowLeft, windowRight);
this._wasDragged = true;
},
......@@ -698,7 +699,6 @@ WebInspector.FlameChart.MainPane.prototype = {
{
if (this._isDragging)
return;
var entryIndex = this._coordinatesToEntryIndex(event.offsetX, event.offsetY);
if (this._highlightedEntryIndex === entryIndex)
......@@ -711,7 +711,7 @@ WebInspector.FlameChart.MainPane.prototype = {
this._highlightedEntryIndex = entryIndex;
this._updateHighlightElement();
this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex);
this._entryInfo.removeChildren();
if (this._highlightedEntryIndex === -1)
......@@ -733,9 +733,7 @@ WebInspector.FlameChart.MainPane.prototype = {
return;
if (this._highlightedEntryIndex === -1)
return;
var data = this._dataProvider.entryData(this._highlightedEntryIndex);
if (data)
this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, data);
this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelected, this._highlightedEntryIndex);
},
/**
......@@ -760,7 +758,7 @@ WebInspector.FlameChart.MainPane.prototype = {
}
windowLeft = Number.constrain(windowLeft, this._zeroTime, this._totalTime + this._zeroTime);
windowRight = Number.constrain(windowRight, this._zeroTime, this._totalTime + this._zeroTime);
this._timeRangeController.requestWindowTimes(windowLeft, windowRight);
this._flameChartDelegate.requestWindowTimes(windowLeft, windowRight);
},
/**
......@@ -781,16 +779,16 @@ WebInspector.FlameChart.MainPane.prototype = {
var timelineData = this._timelineData();
if (!timelineData)
return -1;
var cursorTime = this._cursorTime(x);
var cursorLevel = this._isTopDown ? Math.floor(y / this._barHeight - 1) : Math.floor((this._canvas.height / window.devicePixelRatio - y) / this._barHeight);
var cursorTimeOffset = this._cursorTime(x) - this._zeroTime;
var cursorLevel = this._isTopDown ? Math.floor((y - WebInspector.FlameChart.DividersBarHeight) / this._barHeight) : Math.floor((this._canvas.height / window.devicePixelRatio - y) / this._barHeight);
var entryOffsets = timelineData.entryOffsets;
var entryTotalTimes = timelineData.entryTotalTimes;
var entryLevels = timelineData.entryLevels;
var length = entryOffsets.length;
for (var i = 0; i < length; ++i) {
if (cursorTime < entryOffsets[i])
if (cursorTimeOffset < entryOffsets[i])
return -1;
if (cursorTime < (entryOffsets[i] + entryTotalTimes[i])
if (cursorTimeOffset < (entryOffsets[i] + entryTotalTimes[i])
&& cursorLevel === entryLevels[i])
return i;
}
......@@ -919,6 +917,7 @@ WebInspector.FlameChart.MainPane.prototype = {
}
context.fill();
}
context.textBaseline = "alphabetic";
context.fillStyle = "#333";
this._dotsWidth = context.measureText("\u2026").width;
......@@ -949,28 +948,34 @@ WebInspector.FlameChart.MainPane.prototype = {
}
context.fillText(title, xText + textPadding, textBaseHeight - entryLevels[entryIndex] * this._barHeightDelta);
}
this._updateHighlightElement();
this._updateElementPosition(this._highlightElement, this._highlightedEntryIndex);
this._updateElementPosition(this._selectedElement, this._selectedEntryIndex);
},
setSelectedEntry: function(entryIndex)
{
this._selectedEntryIndex = entryIndex;
this._updateElementPosition(this._selectedElement, this._selectedEntryIndex);
},
_updateHighlightElement: function()
_updateElementPosition: function(element, entryIndex)
{
if (this._highlightElement.parentElement)
this._highlightElement.remove();
var entryIndex = this._highlightedEntryIndex;
if (element.parentElement)
element.remove();
if (entryIndex === -1)
return;
var timelineData = this._timelineData();
var entryOffset = timelineData.entryOffsets[entryIndex];
var barX = this._offsetToPosition(entryOffset);
var barRight = this._offsetToPosition(entryOffset + timelineData.entryTotalTimes[entryIndex]);
var timeRange = this._dataProvider.highlightTimeRange(entryIndex);
var barX = this._offsetToPosition(timeRange.startTimeOffset);
var barRight = this._offsetToPosition(timeRange.endTimeOffset);
var barWidth = Math.max(barRight - barX, this._minWidth);
var style = this._highlightElement.style;
var barY = this._levelToHeight(timelineData.entryLevels[entryIndex]);
var style = element.style;
style.left = barX + "px";
style.top = barY + "px";
style.width = barWidth + "px";
style.top = this._levelToHeight(timelineData.entryLevels[entryIndex]) + "px";
style.height = this._barHeight + "px";
this.element.appendChild(this._highlightElement);
this.element.appendChild(element);
},
_offsetToPosition: function(offset)
......@@ -1095,5 +1100,12 @@ WebInspector.FlameChart.MainPane.prototype = {
this._timelineGrid.updateDividers(this._calculator, offsets, true);
},
reset: function()
{
this._highlightedEntryIndex = -1;
this._selectedEntryIndex = -1;
this.update();
},
__proto__: WebInspector.View.prototype
}
......@@ -186,7 +186,7 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
this._startTime = this._startTime ? Math.min(this._startTime, record.startTime) : record.startTime;
this._zeroTime = this._startTime;
var recordEndTime = record.endTime || record.startTime;
var recordEndTime = record.endTime;
this._endTime = Math.max(this._endTime, recordEndTime);
this._totalTime = Math.max(1000, this._endTime - this._startTime);
......@@ -194,17 +194,29 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
if (record.type === WebInspector.TimelineModel.RecordType.GPUTask || !!record.thread)
return;
} else {
if (record.type === WebInspector.TimelineModel.RecordType.Program || !record.thread)
if (record.type === WebInspector.TimelineModel.RecordType.Program || !record.thread || record.thread === "gpu")
return;
}
var recordIndex = this._pushRecord(record, true, level, record.startTime, record.endTime);
var currentTime = record.startTime;
for (var i = 0; i < record.children.length; ++i) {
var childRecord = record.children[i];
var childStartTime = childRecord.startTime;
if (currentTime !== childStartTime)
this._pushRecord(record, true, level, currentTime, childStartTime);
var childEndTime = childRecord.endTime || childRecord.startTime;
var childEndTime = childRecord.endTime;
if (childStartTime === childEndTime) {
this._appendRecord(childRecord, level + 1);
continue;
}
if (currentTime !== childStartTime) {
if (recordIndex !== -1) {
this._timelineData.entryTotalTimes[recordIndex] = childStartTime - record.startTime;
recordIndex = -1;
} else {
this._pushRecord(record, true, level, currentTime, childStartTime);
}
}
this._pushRecord(record, false, level, childStartTime, childEndTime);
this._appendRecord(childRecord, level + 1);
currentTime = childEndTime;
......@@ -221,6 +233,7 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
* @param {number} level
* @param {number} startTime
* @param {number} endTime
* @return {number}
*/
_pushRecord: function(record, isSelfSegment, level, startTime, endTime)
{
......@@ -230,6 +243,7 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
this._timelineData.entryLevels[index] = level;
this._timelineData.entryTotalTimes[index] = endTime - startTime;
this._isSelfSegment[index] = isSelfSegment;
return index;
},
/**
......@@ -252,21 +266,25 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
/**
* @param {number} entryIndex
* @return {?Object}
* @return {!string}
*/
entryData: function(entryIndex)
entryColor: function(entryIndex)
{
return null;
var category = WebInspector.TimelineUIUtils.categoryForRecord(this._records[entryIndex]);
return this._isSelfSegment[entryIndex] ? category.fillColorStop1 : category.backgroundColor;
},
/**
* @param {number} entryIndex
* @return {!string}
* @return {!{startTimeOffset: number, endTimeOffset: number}}
*/
entryColor: function(entryIndex)
highlightTimeRange: function(entryIndex)
{
var category = WebInspector.TimelineUIUtils.categoryForRecord(this._records[entryIndex]);
return this._isSelfSegment[entryIndex] ? category.fillColorStop1 : category.backgroundColor;
var record = this._records[entryIndex];
return {
startTimeOffset: record.startTime - this._zeroTime,
endTimeOffset: record.endTime - this._zeroTime
};
},
/**
......@@ -283,7 +301,7 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
* @constructor
* @extends {WebInspector.View}
* @implements {WebInspector.TimelineModeView}
* @implements {WebInspector.TimeRangeController}
* @implements {WebInspector.FlameChartDelegate}
* @param {!WebInspector.TimelineModeViewDelegate} delegate
* @param {!WebInspector.TimelineModel} model
* @param {!WebInspector.TimelineFrameModel} frameModel
......@@ -292,12 +310,15 @@ WebInspector.TimelineFlameChartDataProvider.prototype = {
WebInspector.TimelineFlameChart = function(delegate, model, frameModel, mainThread)
{
WebInspector.View.call(this);
this.element.classList.add("timeline-flamechart");
this.registerRequiredCSS("flameChart.css");
this._delegate = delegate;
this._model = model;
this._dataProvider = new WebInspector.TimelineFlameChartDataProvider(model, frameModel, mainThread);
this._mainView = new WebInspector.FlameChart.MainPane(this._dataProvider, this, true, true);
this._mainView.show(this.element);
this._model.addEventListener(WebInspector.TimelineModel.Events.RecordingStarted, this._onRecordingStarted, this);
this._mainView.addEventListener(WebInspector.FlameChart.Events.EntrySelected, this._onEntrySelected, this);
}
WebInspector.TimelineFlameChart.prototype = {
......@@ -316,7 +337,8 @@ WebInspector.TimelineFlameChart.prototype = {
refreshRecords: function(textFilter)
{
this._dataProvider.reset();
this._mainView._scheduleUpdate();
this._mainView.reset();
this.setSelectedRecord(this._selectedRecord);
},
reset: function()
......@@ -324,6 +346,7 @@ WebInspector.TimelineFlameChart.prototype = {
this._automaticallySizeWindow = true;
this._dataProvider.reset();
this._mainView.setWindowTimes(0, Infinity);
delete this._selectedRecord;
},
_onRecordingStarted: function()
......@@ -389,6 +412,29 @@ WebInspector.TimelineFlameChart.prototype = {
*/
setSelectedRecord: function(record)
{
this._selectedRecord = record;
var entryRecords = this._dataProvider._records;
for (var entryIndex = 0; entryIndex < entryRecords.length; ++entryIndex) {
if (entryRecords[entryIndex] === record) {
this._mainView.setSelectedEntry(entryIndex);
return;
}
}
this._mainView.setSelectedEntry(-1);
if (this._selectedElement) {
this._selectedElement.remove();
delete this._selectedElement;
}
},
/**
* @param {!WebInspector.Event} event
*/
_onEntrySelected: function(event)
{
var entryIndex = event.data;
var record = this._dataProvider._records[entryIndex];
this._delegate.selectRecord(record);
},
__proto__: WebInspector.View.prototype
......
......@@ -581,6 +581,7 @@ WebInspector.TimelinePanel.prototype = {
{
this.requestWindowTimes(0, Infinity);
this._windowFilter._reset();
delete this._selectedRecord;
if (this._lazyFrameModel)
this._lazyFrameModel.reset();
for (var i = 0; i < this._currentViews.length; ++i)
......@@ -749,6 +750,9 @@ WebInspector.TimelinePanel.prototype = {
_updateSelectionDetails: function()
{
if (this._selectedRecord)
return;
var startTime = this._windowStartTime;
var endTime = this._windowEndTime;
......@@ -818,6 +822,7 @@ WebInspector.TimelinePanel.prototype = {
selectRecord: function(record)
{
this._detailsLinkifier.reset();
this._selectedRecord = record;
if (!record) {
this._updateSelectionDetails();
......
......@@ -14,6 +14,10 @@
pointer-events: auto;
}
.flame-chart-main-pane {
overflow: hidden;
}
.flame-chart-overview-pane {
flex: 0 0 80px !important;
}
......@@ -47,4 +51,13 @@
position: absolute;
opacity: 0.2;
pointer-events: none;
}
\ No newline at end of file
}
.flame-chart-selected-element {
position: absolute;
pointer-events: none;
border-color: rgb(56, 121, 217);
border-width: 2px;
border-style: solid;
background-color: rgba(56, 121, 217, 0.2);
}
......@@ -793,10 +793,6 @@
margin-left: 20px;
}
.flame-chart-main-pane {
overflow: hidden;
}
.timeline-flamechart-view #timeline-overview-grid {
display: none;
}
......@@ -804,3 +800,7 @@
.timeline-flamechart-view .flame-chart-main-pane .resources-divider-label {
text-align: center;
}
.timeline-flamechart {
overflow: hidden;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment