Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(191)

Side by Side Diff: Source/devtools/front_end/TimelineOverviewPane.js

Issue 104523002: [DevTools] Add power profiler and power overview in timeline panel. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 21 matching lines...) Expand all
32 * @constructor 32 * @constructor
33 * @extends {WebInspector.View} 33 * @extends {WebInspector.View}
34 * @param {WebInspector.TimelineModel} model 34 * @param {WebInspector.TimelineModel} model
35 */ 35 */
36 WebInspector.TimelineOverviewPane = function(model) 36 WebInspector.TimelineOverviewPane = function(model)
37 { 37 {
38 WebInspector.View.call(this); 38 WebInspector.View.call(this);
39 this.element.id = "timeline-overview-panel"; 39 this.element.id = "timeline-overview-panel";
40 this.element.addStyleClass("hbox"); 40 this.element.addStyleClass("hbox");
41 41
42 this._powerProfileEnabled = WebInspector.experimentsSettings.powerProfile.is Enabled();
43 if (this._powerProfileEnabled)
44 this.element.addStyleClass("with-power");
45
42 this._windowStartTime = 0; 46 this._windowStartTime = 0;
43 this._windowEndTime = Infinity; 47 this._windowEndTime = Infinity;
44 this._eventDividers = []; 48 this._eventDividers = [];
45 49
46 this._model = model; 50 this._model = model;
47 51
48 this._topPaneSidebarElement = document.createElement("div"); 52 this._topPaneSidebarElement = document.createElement("div");
49 this._topPaneSidebarElement.id = "timeline-overview-sidebar"; 53 this._topPaneSidebarElement.id = "timeline-overview-sidebar";
50 54
51 var overviewTreeElement = document.createElement("ol"); 55 var overviewTreeElement = document.createElement("ol");
52 overviewTreeElement.className = "sidebar-tree vbox"; 56 overviewTreeElement.className = "sidebar-tree vbox";
53 this._topPaneSidebarElement.appendChild(overviewTreeElement); 57 this._topPaneSidebarElement.appendChild(overviewTreeElement);
54 this.element.appendChild(this._topPaneSidebarElement); 58 this.element.appendChild(this._topPaneSidebarElement);
55 59
56 var topPaneSidebarTree = new TreeOutline(overviewTreeElement); 60 var topPaneSidebarTree = new TreeOutline(overviewTreeElement);
57 61
58 this._overviewItems = {}; 62 this._overviewItems = {};
59 this._overviewItems[WebInspector.TimelineOverviewPane.Mode.Events] = new Web Inspector.SidebarTreeElement("timeline-overview-sidebar-events", 63 this._overviewItems[WebInspector.TimelineOverviewPane.Mode.Events] = new Web Inspector.SidebarTreeElement("timeline-overview-sidebar-events",
60 WebInspector.UIString("Events")); 64 WebInspector.UIString("Events"));
61 this._overviewItems[WebInspector.TimelineOverviewPane.Mode.Frames] = new Web Inspector.SidebarTreeElement("timeline-overview-sidebar-frames", 65 this._overviewItems[WebInspector.TimelineOverviewPane.Mode.Frames] = new Web Inspector.SidebarTreeElement("timeline-overview-sidebar-frames",
62 WebInspector.UIString("Frames")); 66 WebInspector.UIString("Frames"));
63 this._overviewItems[WebInspector.TimelineOverviewPane.Mode.Memory] = new Web Inspector.SidebarTreeElement("timeline-overview-sidebar-memory", 67 this._overviewItems[WebInspector.TimelineOverviewPane.Mode.Memory] = new Web Inspector.SidebarTreeElement("timeline-overview-sidebar-memory",
64 WebInspector.UIString("Memory")); 68 WebInspector.UIString("Memory"));
65 69
70 if (this._powerProfileEnabled)
71 this._overviewItems[WebInspector.TimelineOverviewPane.Mode.Power] = new WebInspector.SidebarTreeElement("timeline-overview-sidebar-power",
72 WebInspector.UIString("Power"))
73
66 for (var mode in this._overviewItems) { 74 for (var mode in this._overviewItems) {
67 var item = this._overviewItems[mode]; 75 var item = this._overviewItems[mode];
68 item.onselect = this.setMode.bind(this, mode); 76 item.onselect = this.setMode.bind(this, mode);
69 topPaneSidebarTree.appendChild(item); 77 topPaneSidebarTree.appendChild(item);
70 } 78 }
71 79
72 this._overviewGrid = new WebInspector.OverviewGrid("timeline"); 80 this._overviewGrid = new WebInspector.OverviewGrid("timeline");
73 81
74 this.element.appendChild(this._overviewGrid.element); 82 this.element.appendChild(this._overviewGrid.element);
75 83
76 this._innerSetMode(WebInspector.TimelineOverviewPane.Mode.Events); 84 this._innerSetMode(WebInspector.TimelineOverviewPane.Mode.Events);
77 85
78 var categories = WebInspector.TimelinePresentationModel.categories(); 86 var categories = WebInspector.TimelinePresentationModel.categories();
79 for (var category in categories) 87 for (var category in categories)
80 categories[category].addEventListener(WebInspector.TimelineCategory.Even ts.VisibilityChanged, this._onCategoryVisibilityChanged, this); 88 categories[category].addEventListener(WebInspector.TimelineCategory.Even ts.VisibilityChanged, this._onCategoryVisibilityChanged, this);
81 89
82 this._overviewCalculator = new WebInspector.TimelineOverviewCalculator(); 90 this._overviewCalculator = new WebInspector.TimelineOverviewCalculator();
83 91
84 model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._ onRecordAdded, this); 92 model.addEventListener(WebInspector.TimelineModel.Events.RecordAdded, this._ onRecordAdded, this);
85 model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleared, thi s._reset, this); 93 model.addEventListener(WebInspector.TimelineModel.Events.RecordsCleared, thi s._reset, this);
86 this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowC hanged, this._onWindowChanged, this); 94 this._overviewGrid.addEventListener(WebInspector.OverviewGrid.Events.WindowC hanged, this._onWindowChanged, this);
87 } 95 }
88 96
89 WebInspector.TimelineOverviewPane.Mode = { 97 WebInspector.TimelineOverviewPane.Mode = {
90 Events: "Events", 98 Events: "Events",
91 Frames: "Frames", 99 Frames: "Frames",
92 Memory: "Memory" 100 Memory: "Memory",
101 Power: "Power"
93 }; 102 };
94 103
95 WebInspector.TimelineOverviewPane.Events = { 104 WebInspector.TimelineOverviewPane.Events = {
96 ModeChanged: "ModeChanged", 105 ModeChanged: "ModeChanged",
97 WindowChanged: "WindowChanged" 106 WindowChanged: "WindowChanged"
98 }; 107 };
99 108
100 WebInspector.TimelineOverviewPane.prototype = { 109 WebInspector.TimelineOverviewPane.prototype = {
101 wasShown: function() 110 wasShown: function()
102 { 111 {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
138 */ 147 */
139 _createOverviewControl: function() 148 _createOverviewControl: function()
140 { 149 {
141 switch (this._currentMode) { 150 switch (this._currentMode) {
142 case WebInspector.TimelineOverviewPane.Mode.Events: 151 case WebInspector.TimelineOverviewPane.Mode.Events:
143 return new WebInspector.TimelineEventOverview(this._model); 152 return new WebInspector.TimelineEventOverview(this._model);
144 case WebInspector.TimelineOverviewPane.Mode.Frames: 153 case WebInspector.TimelineOverviewPane.Mode.Frames:
145 return new WebInspector.TimelineFrameOverview(this._model); 154 return new WebInspector.TimelineFrameOverview(this._model);
146 case WebInspector.TimelineOverviewPane.Mode.Memory: 155 case WebInspector.TimelineOverviewPane.Mode.Memory:
147 return new WebInspector.TimelineMemoryOverview(this._model); 156 return new WebInspector.TimelineMemoryOverview(this._model);
157 case WebInspector.TimelineOverviewPane.Mode.Power:
158 if (this._powerProfileEnabled) {
159 return new WebInspector.TimelinePowerOverview(this._model, this. _windowStartTime, this._windowEndTime);
160 } else {
161 this._currentMode = WebInspector.TimelineOverviewPane.Mode.Event s;
162 return new WebInspector.TimelineEventOverview(this._model);
163 }
148 } 164 }
149 throw new Error("Invalid overview mode: " + this._currentMode); 165 throw new Error("Invalid overview mode: " + this._currentMode);
150 }, 166 },
151 167
152 _onCategoryVisibilityChanged: function(event) 168 _onCategoryVisibilityChanged: function(event)
153 { 169 {
154 this._overviewControl.categoryVisibilityChanged(); 170 this._overviewControl.categoryVisibilityChanged();
155 }, 171 },
156 172
157 _update: function() 173 _update: function()
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 windowLeft: function() 267 windowLeft: function()
252 { 268 {
253 return this._overviewGrid.windowLeft(); 269 return this._overviewGrid.windowLeft();
254 }, 270 },
255 271
256 windowRight: function() 272 windowRight: function()
257 { 273 {
258 return this._overviewGrid.windowRight(); 274 return this._overviewGrid.windowRight();
259 }, 275 },
260 276
261 _onWindowChanged: function() 277 _onWindowChanged: function(timeLeft, timeRight)
262 { 278 {
263 if (this._ignoreWindowChangedEvent) 279 if (this._ignoreWindowChangedEvent)
264 return; 280 return;
265 var times = this._overviewControl.windowTimes(this.windowLeft(), this.wi ndowRight()); 281 var times = this._overviewControl.windowTimes(this.windowLeft(), this.wi ndowRight());
282 this._overviewControl.windowChanged(times.startTime, times.endTime);
266 this._windowStartTime = times.startTime; 283 this._windowStartTime = times.startTime;
267 this._windowEndTime = times.endTime; 284 this._windowEndTime = times.endTime;
268 this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.W indowChanged); 285 this.dispatchEventToListeners(WebInspector.TimelineOverviewPane.Events.W indowChanged);
269 }, 286 },
270 287
271 /** 288 /**
272 * @param {Number} startTime 289 * @param {Number} startTime
273 * @param {Number} endTime 290 * @param {Number} endTime
274 */ 291 */
275 setWindowTimes: function(startTime, endTime) 292 setWindowTimes: function(startTime, endTime)
276 { 293 {
277 this._windowStartTime = startTime; 294 this._windowStartTime = startTime;
278 this._windowEndTime = endTime; 295 this._windowEndTime = endTime;
279 this._updateWindow(); 296 this._updateWindow();
280 }, 297 },
281 298
282 _updateWindow: function() 299 _updateWindow: function()
283 { 300 {
284 var windowBoundaries = this._overviewControl.windowBoundaries(this._wind owStartTime, this._windowEndTime); 301 var windowBoundaries = this._overviewControl.windowBoundaries(this._wind owStartTime, this._windowEndTime);
285 this._ignoreWindowChangedEvent = true; 302 this._ignoreWindowChangedEvent = true;
286 this._overviewGrid.setWindow(windowBoundaries.left, windowBoundaries.rig ht); 303 // frame overview will return zero windowBoundaries when no frame bar we re covered, we should avoid this.
304 if (!(this._windowStartTime < this._windowEndTime && windowBoundaries.le ft === 0 && windowBoundaries.right === 0))
305 this._overviewGrid.setWindow(windowBoundaries.left, windowBoundaries.r ight);
287 this._overviewGrid.setResizeEnabled(this._model.records.length); 306 this._overviewGrid.setResizeEnabled(this._model.records.length);
288 this._ignoreWindowChangedEvent = false; 307 this._ignoreWindowChangedEvent = false;
289 }, 308 },
290 309
291 _scheduleRefresh: function() 310 _scheduleRefresh: function()
292 { 311 {
293 if (this._refreshTimeout) 312 if (this._refreshTimeout)
294 return; 313 return;
295 if (!this.isShowing()) 314 if (!this.isShowing())
296 return; 315 return;
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 411
393 this._model = model; 412 this._model = model;
394 this._canvas = this.element.createChild("canvas", "fill"); 413 this._canvas = this.element.createChild("canvas", "fill");
395 this._context = this._canvas.getContext("2d"); 414 this._context = this._canvas.getContext("2d");
396 } 415 }
397 416
398 WebInspector.TimelineOverviewBase.prototype = { 417 WebInspector.TimelineOverviewBase.prototype = {
399 update: function() { }, 418 update: function() { },
400 reset: function() { }, 419 reset: function() { },
401 420
421 windowChanged: function(timeLeft, timeRight) { },
422
402 categoryVisibilityChanged: function() { }, 423 categoryVisibilityChanged: function() { },
403 424
404 /** 425 /**
405 * @param {WebInspector.TimelineFrame} frame 426 * @param {WebInspector.TimelineFrame} frame
406 */ 427 */
407 addFrame: function(frame) { }, 428 addFrame: function(frame) { },
408 429
409 /** 430 /**
410 * @param {number} windowLeft 431 * @param {number} windowLeft
411 * @param {number} windowRight 432 * @param {number} windowRight
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after
1018 */ 1039 */
1019 _firstBarAfter: function(time, comparator) 1040 _firstBarAfter: function(time, comparator)
1020 { 1041 {
1021 return insertionIndexForObjectInListSortedByFunction(time, this._barTime s, comparator); 1042 return insertionIndexForObjectInListSortedByFunction(time, this._barTime s, comparator);
1022 }, 1043 },
1023 1044
1024 __proto__: WebInspector.TimelineOverviewBase.prototype 1045 __proto__: WebInspector.TimelineOverviewBase.prototype
1025 } 1046 }
1026 1047
1027 /** 1048 /**
1049 * @constructor
1050 * @extends {WebInspector.TimelineOverviewBase}
1051 * @param {WebInspector.TimelineModel} model
1052 */
1053 WebInspector.TimelinePowerOverview = function(model, windowStartTime, windowEndT ime)
pfeldman 2014/01/09 11:38:52 This change probably needs merging. Could you reba
Pan 2014/02/24 09:49:47 rebased, thanks!
1054 {
1055 WebInspector.TimelineOverviewBase.call(this, model);
1056 this.element.id = "timeline-overview-power";
1057 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this));
1058 this._powerEventsHistogram = [];
1059 this._maxPower = 0;
1060 this._minPower = 0;
1061 this._yFactor = 0;
1062 this._powerDrawHeight = 0;
1063 this._windowStartTime = windowStartTime;
1064 this._windowEndTime = windowEndTime;
1065 }
1066
1067 WebInspector.TimelinePowerOverview.prototype = {
1068 windowChanged: function(startTime, endTime)
1069 {
1070 this._windowStartTime = startTime;
1071 this._windowEndTime = endTime;
1072 this._drawEnergy(startTime, endTime);
1073 },
1074
1075 _calculateEnergyInSelectedRegion: function(startX, endX) {
1076
1077 // if pos is on the power event, just the prev and next will be similer to pos
1078 function findAdjacents(pos, histograms) {
1079 var prevPowerEventIndex;
1080 var nextPowerEventIndex;
1081 // find previous power Event
1082 for(var i = pos; i >= 0; i--) {
1083 if (histograms[i]) {
1084 prevPowerEventIndex = i;
1085 break;
1086 }
1087 }
1088 // find next Event
1089 for(var i = pos; i < histograms.length; i++) {
1090 if (histograms[i]) {
1091 nextPowerEventIndex= i;
1092 break;
1093 }
1094 }
1095 // as pos may fall into a blank region, which only have next or prev . in this case we will return 0 timespance
1096 return {
1097 prev : prevPowerEventIndex,
1098 next : nextPowerEventIndex,
1099 timeSpan : (!prevPowerEventIndex || !nextPowerEventIndex) ? 0 : (histograms[nextPowerEventIndex].startTime - histograms[prevPowerEventIndex].sta rtTime) / 1000, // in seconds
1100 xSpan : (!prevPowerEventIndex || !nextPowerEventIndex) ? 0 : (ne xtPowerEventIndex - prevPowerEventIndex),
1101 power : (!nextPowerEventIndex) ? 0 : histograms[nextPowerEventIn dex].value
1102 };
1103 }
1104
1105 var energy = 0;
1106 var startAdjancents = findAdjacents(startX, this._powerEventsHistogram);
1107 var endAdjancents = findAdjacents(endX, this._powerEventsHistogram);
1108
1109 // cross a power event
1110 if (startAdjancents.prev !== endAdjancents.prev) {
1111
1112 if (startAdjancents.timeSpan)
1113 energy += (startAdjancents.next - startX) / startAdjancents.xSpan * startAdjancents.timeSpan * startAdjancents.power;
1114
1115 if (endAdjancents.timeSpan)
1116 energy += (endX- endAdjancents.prev) / endAdjancents.xSpan * endAdja ncents.timeSpan * endAdjancents.power;
1117
1118 } else { //start and end are in the same power event duration.
1119 energy += (endX - startX) / startAdjancents.xSpan * startAdjancents. timeSpan * endAdjancents.power;
1120 }
1121
1122 var prevX = -1;
1123 for(var i = startX; i <= endX; i++) {
1124 if (!this._powerEventsHistogram[i])
1125 continue;
1126 if (prevX !== -1) {
1127 var timeSpan = (this._powerEventsHistogram[i].startTime- this._p owerEventsHistogram[prevX].startTime) / 1000;
1128 energy += timeSpan * this._powerEventsHistogram[i].value;
1129 }
1130 prevX = i;
1131 }
1132 return energy;
1133
1134 },
1135
1136 _drawEnergy: function(startTime, endTime) {
1137 // clear power value firstly
1138 this._restorePowerMarker();
1139
1140 var startX = Math.round(this._xFactor * (startTime - this._model.minimum RecordTime()));
1141 var endX = Math.round(this._xFactor * (endTime- this._model.minimumRecor dTime()));
1142
1143 var energy = this._calculateEnergyInSelectedRegion(startX, endX);
1144
1145 this._restoreImageUnderMarker(this._energyTextSaver);
1146 if (energy)
1147 this._drawEnergyText(startX, endX, energy);
1148 },
1149
1150 _createTextLabel: function(labelName)
1151 {
1152 const labelPadding = 4 * window.devicePixelRatio;
1153 var labelWidth = this._context.measureText(labelName).width + 2 * labelP adding;
1154 var contextFont = this._context.font;
1155 var labelHeight = contextFont.substr(0, contextFont.indexOf("px ")) - 0;
1156 return { name : labelName,
1157 width : labelWidth,
1158 height : labelHeight
1159 };
1160 },
1161
1162 _drawEnergyText: function(startX, endX, energyValue)
1163 {
1164 var label = this._createTextLabel(WebInspector.UIString("%.2f\u2009joule ", energyValue));
1165 var textXPos = (startX + endX) > label.width ? Math.round((startX + endX - label.width) / 2) : Math.round((startX + endX) / 2);
1166 var textYPos = Math.round(this._powerDrawHeight / 2);
1167 this._context.beginPath();
1168 this._energyTextSaver = this._saveRectImageUnderMarker(textXPos, textYPo s - label.height, label.width, label.height + 2);
1169 this._context.strokeStyle = "black";
1170 this._context.fillStyle = "black";
1171 this._context.fillText(label.name, textXPos, textYPos);
1172 this._context.stroke();
1173 },
1174
1175 _resetPowerBoundaries: function(allRecords)
1176 {
1177 var maxPower = 0;
1178 var minPower = 100000000000;
1179 var minTime = this._model.minimumRecordTime();
1180 WebInspector.TimelinePresentationModel.forAllRecords(allRecords, functio n(r) {
1181 if (r.type !== WebInspector.TimelineModel.RecordType.SoC_Package || WebInspector.TimelineModel.endTimeInSeconds(r) < minTime)
1182 return;
1183 maxPower = Math.max(maxPower, r.value);
1184 minPower = Math.min(minPower, r.value);
1185 });
1186 minPower = Math.min(minPower, maxPower);
1187 this._maxPower = maxPower;
1188 this._minPower = minPower;
1189 },
1190
1191 _prepareHistograms: function(allRecords)
1192 {
1193 const lowerOffset = 3;
1194 var width = this._canvas.width;
1195 var height = this._canvas.height - lowerOffset;
1196 var minTime = this._model.minimumRecordTime();
1197 var maxTime = this._model.maximumRecordTime();
1198 var xFactor = width / (maxTime - minTime);
1199 var yFactor = height / (this._maxPower - this._minPower);
1200 this._xFactor = xFactor;
1201 this._yFactor = yFactor;
1202
1203 var histogram = new Array(width);
1204 var powerEventsHistogram = new Array(width);
1205 var minPower = this._minPower;
1206 WebInspector.TimelinePresentationModel.forAllRecords(allRecords, functio n(r) {
1207 if (r.type !== WebInspector.TimelineModel.RecordType.SoC_Package || WebInspector.TimelineModel.endTimeInSeconds(r) < minTime)
1208 return;
1209 var x = Math.round((WebInspector.TimelineModel.endTimeInSeconds(r) - minTime) * xFactor);
1210 var y = Math.round((r.value- minPower ) * yFactor);
1211 histogram[x] = Math.max(histogram[x] || 0, y);
1212 powerEventsHistogram[x] = r;
1213 });
1214
1215 this._powerEventsHistogram = powerEventsHistogram;
1216
1217 // +1 so that the border always fit into the canvas area.
1218 this._powerDrawHeight = height + 1;
1219
1220 return histogram;
1221 },
1222
1223 update: function()
1224 {
1225 this._resetCanvas();
1226 delete this._pointSaver;
1227 delete this._powerTextSaver;
1228 delete this._energyTextSaver;
1229
1230 this._powerEventsHistogram = [];
1231 this._yFactor = 0;
1232
1233 var records = this._model.records;
1234 if (!records.length)
1235 return;
1236
1237 this._resetPowerBoundaries(records);
1238
1239 var histogram = this._prepareHistograms(records);
1240
1241 var height = this._powerDrawHeight;
1242 // draw gridline
1243 this._drawGridline(this._minPower, this._maxPower, height);
1244
1245 // draw power graph
1246 // as we only have power samples in timestamp, we should eliminated the first event as we don't know its start point of time period.
1247 var initialX = 0;
1248 var initialY = 0;
1249 var previousX = 0;
1250 for (var k = 0; k < histogram.length; k++) {
1251 var value = histogram[k];
1252 if (value !== undefined) {
1253 initialX = k;
1254 previousX = k;
1255 initialY = value;
1256 break;
1257 }
1258 }
1259
1260 var ctx = this._context;
1261 ctx.beginPath();
1262 var isFirst = true;
1263
1264 for (var x = previousX + 1; x < histogram.length; x++) {
1265 if (histogram[x] === undefined)
1266 continue;
1267 var currentY = height - histogram[x];
1268 if (!isFirst) {
1269 ctx.lineTo(previousX, currentY);
1270 } else {
1271 ctx.moveTo(initialX, currentY);
1272 isFirst = false;
1273 }
1274 ctx.lineTo(x, currentY);
1275 previousX = x;
1276 }
1277
1278 ctx.lineWidth = 0.5;
1279 ctx.strokeStyle = "rgba(20,0,0,0.8)";
1280 ctx.stroke();
1281
1282 ctx.fillStyle = "rgba(255,192,0, 0.8);";
1283 ctx.lineTo(previousX, this._canvas.height);
1284 ctx.lineTo(initialX, this._canvas.height);
1285 ctx.lineTo(initialX, height - initialY);
1286 ctx.fill();
1287 ctx.closePath();
1288
1289 // draw energy for a selected time period
1290 if (this._windowStartTime > 0 && this._windowEndTime < Infinity && this. _windowStartTime < this._windowEndTime)
1291 this._drawEnergy(this._windowStartTime, this._windowEndTime);
1292 },
1293
1294 _drawGridline: function(minPower, maxPower, height)
1295 {
1296 var ctx = this._context;
1297 var width = this._canvas.width;
1298 var yFactor = (maxPower - minPower) / height;
1299 const labelPadding = 4 * window.devicePixelRatio;
1300
1301 ctx.strokeStyle = "rgba(128,128,128,0.5)";
1302 var gridHeight = height / 4;
1303 var yPositions = [];
1304 var powerScales = [];
1305
1306 for (var i = 1; i < 4; i++) {
1307 var yPos = Math.round(gridHeight * i) - 0.5;
1308 var powerScale = yFactor * (height - yPos) + minPower;
1309
1310 //draw gridline
1311 ctx.beginPath();
1312 ctx.moveTo(0, yPos);
1313 ctx.lineTo(width, yPos);
1314 ctx.stroke();
1315
1316 //draw scale for gridline
1317 if (!powerScale)
1318 continue;
1319 ctx.beginPath();
1320 var label = this._createTextLabel(WebInspector.UIString("%.2f\u2009w att", powerScale));
1321 ctx.save();
1322 this._context.fillStyle = "black";
1323 ctx.fillText(label.name, 2, yPos - 2);
1324 ctx.stroke();
1325 ctx.restore();
1326 }
1327 },
1328
1329 _restorePowerMarker: function()
1330 {
1331 this._restoreImageUnderMarker(this._pointSaver);
1332 delete this._pointSaver;
1333
1334 this._restoreImageUnderMarker(this._powerTextSaver);
1335 delete this._powerTextSaver;
1336 },
1337
1338 _onMouseMove: function(event)
1339 {
1340 this._restorePowerMarker();
1341 var powerValue;
1342 var index = Math.round(event.offsetX);
1343 var isInBlankArea = true;
1344 for (var i = 0; i < index + 1; i++) {
1345 if (this._powerEventsHistogram[i]) {
1346 isInBlankArea = false;
1347 break;
1348 }
1349 }
1350 if (isInBlankArea)
1351 return;
1352
1353 for (var i = index + 1; i < this._powerEventsHistogram.length; i++) {
1354 if (this._powerEventsHistogram[i]) {
1355 powerValue = this._powerEventsHistogram[i].value;
1356 break;
1357 }
1358 }
1359
1360 var xPos = event.offsetX;
1361 var yPos = this._powerDrawHeight - Math.round(this._yFactor * (powerValu e - this._minPower));
1362 this._drawPoint(xPos, yPos);
1363
1364 this._drawPowerText(xPos, yPos, powerValue);
1365 },
1366
1367 _drawPoint: function(xPos, yPos)
1368 {
1369 const radius = 2;
1370 this._pointSaver = this._saveArcImageUnderMarker(xPos, yPos, radius);
1371 this._context.beginPath();
1372 this._context.arc(xPos, yPos, radius, Math.PI*2, false)
1373 this._context.strokeStyle = "red";
1374 this._context.fillStyle = "red";
1375 this._context.fill();
1376 this._context.stroke();
1377 },
1378
1379 _drawPowerText: function(xPointPos, yPointPos, powerValue)
1380 {
1381 var label = this._createTextLabel(WebInspector.UIString("%.2f\u2009watt" , powerValue));
1382 var textYPos = yPointPos - 3 - label.height > 0 ? yPointPos - 3: yPointP os + 3 + label.height;
1383 var textXPos = xPointPos + label.width > this._canvas.width ? this._canv as.width - label.width : xPointPos;
1384 this._context.beginPath();
1385 this._powerTextSaver = this._saveRectImageUnderMarker(textXPos, textYPos - label.height, label.width, label.height);
1386 this._context.fillText(label.name, textXPos, textYPos);
1387 this._context.stroke();
1388 },
1389
1390 _saveArcImageUnderMarker: function(x, y, radius)
1391 {
1392 const w = radius + 1;
1393 var imageData = this._context.getImageData(x - w, y - w, 2 * w, 2 * w);
1394 return {
1395 x: x - w,
1396 y: y - w,
1397 imageData: imageData
1398 };
1399 },
1400
1401 _saveRectImageUnderMarker: function(x, y, w, h)
1402 {
1403 var imageData = this._context.getImageData(x, y, w, h);
1404 return {
1405 x: x,
1406 y: y,
1407 imageData: imageData
1408 };
1409 },
1410
1411
1412 _restoreImageUnderMarker: function(imageUnderMarker)
1413 {
1414 if (imageUnderMarker)
1415 this._context.putImageData(imageUnderMarker.imageData, imageUnderMar ker.x, imageUnderMarker.y);
1416 },
1417
1418 __proto__: WebInspector.TimelineOverviewBase.prototype
1419 }
1420
1421 /**
1028 * @param {WebInspector.TimelineOverviewPane} pane 1422 * @param {WebInspector.TimelineOverviewPane} pane
1029 * @constructor 1423 * @constructor
1030 * @implements {WebInspector.TimelinePresentationModel.Filter} 1424 * @implements {WebInspector.TimelinePresentationModel.Filter}
1031 */ 1425 */
1032 WebInspector.TimelineWindowFilter = function(pane) 1426 WebInspector.TimelineWindowFilter = function(pane)
1033 { 1427 {
1034 this._pane = pane; 1428 this._pane = pane;
1035 } 1429 }
1036 1430
1037 WebInspector.TimelineWindowFilter.prototype = { 1431 WebInspector.TimelineWindowFilter.prototype = {
1038 /** 1432 /**
1039 * @param {!WebInspector.TimelinePresentationModel.Record} record 1433 * @param {!WebInspector.TimelinePresentationModel.Record} record
1040 * @return {boolean} 1434 * @return {boolean}
1041 */ 1435 */
1042 accept: function(record) 1436 accept: function(record)
1043 { 1437 {
1044 return record.lastChildEndTime >= this._pane._windowStartTime && record. startTime <= this._pane._windowEndTime; 1438 return record.lastChildEndTime >= this._pane._windowStartTime && record. startTime <= this._pane._windowEndTime;
1045 } 1439 }
1046 } 1440 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698