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

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/timeline/CountersGraph.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month 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) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 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
11 * copyright notice, this list of conditions and the following disclaimer 11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the 12 * in the documentation and/or other materials provided with the
13 * distribution. 13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its 14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from 15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission. 16 * this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 /**
31 * @implements {WebInspector.TimelineModeView}
32 * @unrestricted
33 */
34 WebInspector.CountersGraph = class extends WebInspector.VBox {
35 /**
36 * @param {!WebInspector.TimelineModeViewDelegate} delegate
37 * @param {!WebInspector.TimelineModel} model
38 * @param {!Array<!WebInspector.TimelineModel.Filter>} filters
39 */
40 constructor(delegate, model, filters) {
41 super();
30 42
31 /** 43 this.element.id = 'memory-graphs-container';
32 * @constructor
33 * @extends {WebInspector.VBox}
34 * @implements {WebInspector.TimelineModeView}
35 * @param {!WebInspector.TimelineModeViewDelegate} delegate
36 * @param {!WebInspector.TimelineModel} model
37 * @param {!Array<!WebInspector.TimelineModel.Filter>} filters
38 */
39 WebInspector.CountersGraph = function(delegate, model, filters)
40 {
41 WebInspector.VBox.call(this);
42
43 this.element.id = "memory-graphs-container";
44 44
45 this._delegate = delegate; 45 this._delegate = delegate;
46 this._model = model; 46 this._model = model;
47 this._filters = filters; 47 this._filters = filters;
48 this._calculator = new WebInspector.CounterGraphCalculator(this._model); 48 this._calculator = new WebInspector.CounterGraphCalculator(this._model);
49 49
50 // Create selectors 50 // Create selectors
51 this._infoWidget = new WebInspector.HBox(); 51 this._infoWidget = new WebInspector.HBox();
52 this._infoWidget.element.classList.add("memory-counter-selector-swatches", " timeline-toolbar-resizer"); 52 this._infoWidget.element.classList.add('memory-counter-selector-swatches', ' timeline-toolbar-resizer');
53 this._infoWidget.show(this.element); 53 this._infoWidget.show(this.element);
54 54
55 this._graphsContainer = new WebInspector.VBox(); 55 this._graphsContainer = new WebInspector.VBox();
56 this._graphsContainer.show(this.element); 56 this._graphsContainer.show(this.element);
57 var canvasWidget = new WebInspector.VBoxWithResizeCallback(this._resize.bind (this)); 57 var canvasWidget = new WebInspector.VBoxWithResizeCallback(this._resize.bind (this));
58 canvasWidget.show(this._graphsContainer.element); 58 canvasWidget.show(this._graphsContainer.element);
59 this._createCurrentValuesBar(); 59 this._createCurrentValuesBar();
60 this._canvasContainer = canvasWidget.element; 60 this._canvasContainer = canvasWidget.element;
61 this._canvasContainer.id = "memory-graphs-canvas-container"; 61 this._canvasContainer.id = 'memory-graphs-canvas-container';
62 this._canvas = this._canvasContainer.createChild("canvas"); 62 this._canvas = this._canvasContainer.createChild('canvas');
63 this._canvas.id = "memory-counters-graph"; 63 this._canvas.id = 'memory-counters-graph';
64 64
65 this._canvasContainer.addEventListener("mouseover", this._onMouseMove.bind(t his), true); 65 this._canvasContainer.addEventListener('mouseover', this._onMouseMove.bind(t his), true);
66 this._canvasContainer.addEventListener("mousemove", this._onMouseMove.bind(t his), true); 66 this._canvasContainer.addEventListener('mousemove', this._onMouseMove.bind(t his), true);
67 this._canvasContainer.addEventListener("mouseleave", this._onMouseLeave.bind (this), true); 67 this._canvasContainer.addEventListener('mouseleave', this._onMouseLeave.bind (this), true);
68 this._canvasContainer.addEventListener("click", this._onClick.bind(this), tr ue); 68 this._canvasContainer.addEventListener('click', this._onClick.bind(this), tr ue);
69 // We create extra timeline grid here to reuse its event dividers. 69 // We create extra timeline grid here to reuse its event dividers.
70 this._timelineGrid = new WebInspector.TimelineGrid(); 70 this._timelineGrid = new WebInspector.TimelineGrid();
71 this._canvasContainer.appendChild(this._timelineGrid.dividersElement); 71 this._canvasContainer.appendChild(this._timelineGrid.dividersElement);
72 72
73 this._counters = []; 73 this._counters = [];
74 this._counterUI = []; 74 this._counterUI = [];
75 }
76
77 _createCurrentValuesBar() {
78 this._currentValuesBar = this._graphsContainer.element.createChild('div');
79 this._currentValuesBar.id = 'counter-values-bar';
80 }
81
82 /**
83 * @param {string} uiName
84 * @param {string} uiValueTemplate
85 * @param {string} color
86 * @param {function(number):string=} formatter
87 * @return {!WebInspector.CountersGraph.Counter}
88 */
89 createCounter(uiName, uiValueTemplate, color, formatter) {
90 var counter = new WebInspector.CountersGraph.Counter();
91 this._counters.push(counter);
92 this._counterUI.push(
93 new WebInspector.CountersGraph.CounterUI(this, uiName, uiValueTemplate, color, counter, formatter));
94 return counter;
95 }
96
97 /**
98 * @override
99 * @return {!WebInspector.Widget}
100 */
101 view() {
102 return this;
103 }
104
105 /**
106 * @override
107 */
108 dispose() {
109 }
110
111 /**
112 * @override
113 */
114 reset() {
115 for (var i = 0; i < this._counters.length; ++i) {
116 this._counters[i].reset();
117 this._counterUI[i].reset();
118 }
119 this.refresh();
120 }
121
122 /**
123 * @override
124 * @return {?Element}
125 */
126 resizerElement() {
127 return this._infoWidget.element;
128 }
129
130 _resize() {
131 var parentElement = this._canvas.parentElement;
132 this._canvas.width = parentElement.clientWidth * window.devicePixelRatio;
133 this._canvas.height = parentElement.clientHeight * window.devicePixelRatio;
134 var timelinePaddingLeft = 15;
135 this._calculator.setDisplayWindow(this._canvas.width, timelinePaddingLeft);
136 this.refresh();
137 }
138
139 /**
140 * @override
141 * @param {number} startTime
142 * @param {number} endTime
143 */
144 setWindowTimes(startTime, endTime) {
145 this._calculator.setWindow(startTime, endTime);
146 this.scheduleRefresh();
147 }
148
149 scheduleRefresh() {
150 WebInspector.invokeOnceAfterBatchUpdate(this, this.refresh);
151 }
152
153 draw() {
154 for (var i = 0; i < this._counters.length; ++i) {
155 this._counters[i]._calculateVisibleIndexes(this._calculator);
156 this._counters[i]._calculateXValues(this._canvas.width);
157 }
158 this._clear();
159
160 for (var i = 0; i < this._counterUI.length; i++)
161 this._counterUI[i]._drawGraph(this._canvas);
162 }
163
164 /**
165 * @param {!Event} event
166 */
167 _onClick(event) {
168 var x = event.x - this._canvasContainer.totalOffsetLeft();
169 var minDistance = Infinity;
170 var bestTime;
171 for (var i = 0; i < this._counterUI.length; ++i) {
172 var counterUI = this._counterUI[i];
173 if (!counterUI.counter.times.length)
174 continue;
175 var index = counterUI._recordIndexAt(x);
176 var distance = Math.abs(x * window.devicePixelRatio - counterUI.counter.x[ index]);
177 if (distance < minDistance) {
178 minDistance = distance;
179 bestTime = counterUI.counter.times[index];
180 }
181 }
182 if (bestTime !== undefined)
183 this._delegate.selectEntryAtTime(bestTime);
184 }
185
186 /**
187 * @param {!Event} event
188 */
189 _onMouseLeave(event) {
190 delete this._markerXPosition;
191 this._clearCurrentValueAndMarker();
192 }
193
194 _clearCurrentValueAndMarker() {
195 for (var i = 0; i < this._counterUI.length; i++)
196 this._counterUI[i]._clearCurrentValueAndMarker();
197 }
198
199 /**
200 * @param {!Event} event
201 */
202 _onMouseMove(event) {
203 var x = event.x - this._canvasContainer.totalOffsetLeft();
204 this._markerXPosition = x;
205 this._refreshCurrentValues();
206 }
207
208 _refreshCurrentValues() {
209 if (this._markerXPosition === undefined)
210 return;
211 for (var i = 0; i < this._counterUI.length; ++i)
212 this._counterUI[i].updateCurrentValue(this._markerXPosition);
213 }
214
215 refresh() {
216 this._timelineGrid.updateDividers(this._calculator);
217 this.draw();
218 this._refreshCurrentValues();
219 }
220
221 /**
222 * @override
223 */
224 refreshRecords() {
225 }
226
227 _clear() {
228 var ctx = this._canvas.getContext('2d');
229 ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
230 }
231
232 /**
233 * @override
234 * @param {?WebInspector.TracingModel.Event} event
235 * @param {string=} regex
236 * @param {boolean=} select
237 */
238 highlightSearchResult(event, regex, select) {
239 }
240
241 /**
242 * @override
243 * @param {?WebInspector.TracingModel.Event} event
244 */
245 highlightEvent(event) {
246 }
247
248 /**
249 * @override
250 * @param {?WebInspector.TimelineSelection} selection
251 */
252 setSelection(selection) {
253 }
75 }; 254 };
76 255
77 WebInspector.CountersGraph.prototype = {
78 _createCurrentValuesBar: function()
79 {
80 this._currentValuesBar = this._graphsContainer.element.createChild("div" );
81 this._currentValuesBar.id = "counter-values-bar";
82 },
83
84 /**
85 * @param {string} uiName
86 * @param {string} uiValueTemplate
87 * @param {string} color
88 * @param {function(number):string=} formatter
89 * @return {!WebInspector.CountersGraph.Counter}
90 */
91 createCounter: function(uiName, uiValueTemplate, color, formatter)
92 {
93 var counter = new WebInspector.CountersGraph.Counter();
94 this._counters.push(counter);
95 this._counterUI.push(new WebInspector.CountersGraph.CounterUI(this, uiNa me, uiValueTemplate, color, counter, formatter));
96 return counter;
97 },
98
99 /**
100 * @override
101 * @return {!WebInspector.Widget}
102 */
103 view: function()
104 {
105 return this;
106 },
107
108 /**
109 * @override
110 */
111 dispose: function()
112 {
113 },
114
115 /**
116 * @override
117 */
118 reset: function()
119 {
120 for (var i = 0; i < this._counters.length; ++i) {
121 this._counters[i].reset();
122 this._counterUI[i].reset();
123 }
124 this.refresh();
125 },
126
127 /**
128 * @override
129 * @return {?Element}
130 */
131 resizerElement: function()
132 {
133 return this._infoWidget.element;
134 },
135
136 _resize: function()
137 {
138 var parentElement = this._canvas.parentElement;
139 this._canvas.width = parentElement.clientWidth * window.devicePixelRati o;
140 this._canvas.height = parentElement.clientHeight * window.devicePixelRat io;
141 var timelinePaddingLeft = 15;
142 this._calculator.setDisplayWindow(this._canvas.width, timelinePaddingLef t);
143 this.refresh();
144 },
145
146 /**
147 * @override
148 * @param {number} startTime
149 * @param {number} endTime
150 */
151 setWindowTimes: function(startTime, endTime)
152 {
153 this._calculator.setWindow(startTime, endTime);
154 this.scheduleRefresh();
155 },
156
157 scheduleRefresh: function()
158 {
159 WebInspector.invokeOnceAfterBatchUpdate(this, this.refresh);
160 },
161
162 draw: function()
163 {
164 for (var i = 0; i < this._counters.length; ++i) {
165 this._counters[i]._calculateVisibleIndexes(this._calculator);
166 this._counters[i]._calculateXValues(this._canvas.width);
167 }
168 this._clear();
169
170 for (var i = 0; i < this._counterUI.length; i++)
171 this._counterUI[i]._drawGraph(this._canvas);
172 },
173
174 /**
175 * @param {!Event} event
176 */
177 _onClick: function(event)
178 {
179 var x = event.x - this._canvasContainer.totalOffsetLeft();
180 var minDistance = Infinity;
181 var bestTime;
182 for (var i = 0; i < this._counterUI.length; ++i) {
183 var counterUI = this._counterUI[i];
184 if (!counterUI.counter.times.length)
185 continue;
186 var index = counterUI._recordIndexAt(x);
187 var distance = Math.abs(x * window.devicePixelRatio - counterUI.coun ter.x[index]);
188 if (distance < minDistance) {
189 minDistance = distance;
190 bestTime = counterUI.counter.times[index];
191 }
192 }
193 if (bestTime !== undefined)
194 this._delegate.selectEntryAtTime(bestTime);
195 },
196
197 /**
198 * @param {!Event} event
199 */
200 _onMouseLeave: function(event)
201 {
202 delete this._markerXPosition;
203 this._clearCurrentValueAndMarker();
204 },
205
206 _clearCurrentValueAndMarker: function()
207 {
208 for (var i = 0; i < this._counterUI.length; i++)
209 this._counterUI[i]._clearCurrentValueAndMarker();
210 },
211
212 /**
213 * @param {!Event} event
214 */
215 _onMouseMove: function(event)
216 {
217 var x = event.x - this._canvasContainer.totalOffsetLeft();
218 this._markerXPosition = x;
219 this._refreshCurrentValues();
220 },
221
222 _refreshCurrentValues: function()
223 {
224 if (this._markerXPosition === undefined)
225 return;
226 for (var i = 0; i < this._counterUI.length; ++i)
227 this._counterUI[i].updateCurrentValue(this._markerXPosition);
228 },
229
230 refresh: function()
231 {
232 this._timelineGrid.updateDividers(this._calculator);
233 this.draw();
234 this._refreshCurrentValues();
235 },
236
237 /**
238 * @override
239 */
240 refreshRecords: function() { },
241
242 _clear: function()
243 {
244 var ctx = this._canvas.getContext("2d");
245 ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
246 },
247
248 /**
249 * @override
250 * @param {?WebInspector.TracingModel.Event} event
251 * @param {string=} regex
252 * @param {boolean=} select
253 */
254 highlightSearchResult: function(event, regex, select)
255 {
256 },
257
258 /**
259 * @override
260 * @param {?WebInspector.TracingModel.Event} event
261 */
262 highlightEvent: function(event)
263 {
264 },
265
266 /**
267 * @override
268 * @param {?WebInspector.TimelineSelection} selection
269 */
270 setSelection: function(selection)
271 {
272 },
273
274 __proto__: WebInspector.VBox.prototype
275 };
276
277 /** 256 /**
278 * @constructor 257 * @unrestricted
279 */ 258 */
280 WebInspector.CountersGraph.Counter = function() 259 WebInspector.CountersGraph.Counter = class {
281 { 260 constructor() {
282 this.times = []; 261 this.times = [];
283 this.values = []; 262 this.values = [];
263 }
264
265 /**
266 * @param {number} time
267 * @param {number} value
268 */
269 appendSample(time, value) {
270 if (this.values.length && this.values.peekLast() === value)
271 return;
272 this.times.push(time);
273 this.values.push(value);
274 }
275
276 reset() {
277 this.times = [];
278 this.values = [];
279 }
280
281 /**
282 * @param {number} value
283 */
284 setLimit(value) {
285 this._limitValue = value;
286 }
287
288 /**
289 * @return {!{min: number, max: number}}
290 */
291 _calculateBounds() {
292 var maxValue;
293 var minValue;
294 for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
295 var value = this.values[i];
296 if (minValue === undefined || value < minValue)
297 minValue = value;
298 if (maxValue === undefined || value > maxValue)
299 maxValue = value;
300 }
301 minValue = minValue || 0;
302 maxValue = maxValue || 1;
303 if (this._limitValue) {
304 if (maxValue > this._limitValue * 0.5)
305 maxValue = Math.max(maxValue, this._limitValue);
306 minValue = Math.min(minValue, this._limitValue);
307 }
308 return {min: minValue, max: maxValue};
309 }
310
311 /**
312 * @param {!WebInspector.CounterGraphCalculator} calculator
313 */
314 _calculateVisibleIndexes(calculator) {
315 var start = calculator.minimumBoundary();
316 var end = calculator.maximumBoundary();
317
318 // Maximum index of element whose time <= start.
319 this._minimumIndex = Number.constrain(this.times.upperBound(start) - 1, 0, t his.times.length - 1);
320
321 // Minimum index of element whose time >= end.
322 this._maximumIndex = Number.constrain(this.times.lowerBound(end), 0, this.ti mes.length - 1);
323
324 // Current window bounds.
325 this._minTime = start;
326 this._maxTime = end;
327 }
328
329 /**
330 * @param {number} width
331 */
332 _calculateXValues(width) {
333 if (!this.values.length)
334 return;
335
336 var xFactor = width / (this._maxTime - this._minTime);
337
338 this.x = new Array(this.values.length);
339 for (var i = this._minimumIndex + 1; i <= this._maximumIndex; i++)
340 this.x[i] = xFactor * (this.times[i] - this._minTime);
341 }
284 }; 342 };
285 343
286 WebInspector.CountersGraph.Counter.prototype = {
287 /**
288 * @param {number} time
289 * @param {number} value
290 */
291 appendSample: function(time, value)
292 {
293 if (this.values.length && this.values.peekLast() === value)
294 return;
295 this.times.push(time);
296 this.values.push(value);
297 },
298
299 reset: function()
300 {
301 this.times = [];
302 this.values = [];
303 },
304
305 /**
306 * @param {number} value
307 */
308 setLimit: function(value)
309 {
310 this._limitValue = value;
311 },
312
313 /**
314 * @return {!{min: number, max: number}}
315 */
316 _calculateBounds: function()
317 {
318 var maxValue;
319 var minValue;
320 for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
321 var value = this.values[i];
322 if (minValue === undefined || value < minValue)
323 minValue = value;
324 if (maxValue === undefined || value > maxValue)
325 maxValue = value;
326 }
327 minValue = minValue || 0;
328 maxValue = maxValue || 1;
329 if (this._limitValue) {
330 if (maxValue > this._limitValue * 0.5)
331 maxValue = Math.max(maxValue, this._limitValue);
332 minValue = Math.min(minValue, this._limitValue);
333 }
334 return { min: minValue, max: maxValue };
335 },
336
337 /**
338 * @param {!WebInspector.CounterGraphCalculator} calculator
339 */
340 _calculateVisibleIndexes: function(calculator)
341 {
342 var start = calculator.minimumBoundary();
343 var end = calculator.maximumBoundary();
344
345 // Maximum index of element whose time <= start.
346 this._minimumIndex = Number.constrain(this.times.upperBound(start) - 1, 0, this.times.length - 1);
347
348 // Minimum index of element whose time >= end.
349 this._maximumIndex = Number.constrain(this.times.lowerBound(end), 0, thi s.times.length - 1);
350
351 // Current window bounds.
352 this._minTime = start;
353 this._maxTime = end;
354 },
355
356 /**
357 * @param {number} width
358 */
359 _calculateXValues: function(width)
360 {
361 if (!this.values.length)
362 return;
363
364 var xFactor = width / (this._maxTime - this._minTime);
365
366 this.x = new Array(this.values.length);
367 for (var i = this._minimumIndex + 1; i <= this._maximumIndex; i++)
368 this.x[i] = xFactor * (this.times[i] - this._minTime);
369 }
370 };
371
372 /** 344 /**
373 * @constructor 345 * @unrestricted
374 * @param {!WebInspector.CountersGraph} memoryCountersPane
375 * @param {string} title
376 * @param {string} currentValueLabel
377 * @param {string} graphColor
378 * @param {!WebInspector.CountersGraph.Counter} counter
379 * @param {(function(number): string)|undefined} formatter
380 */ 346 */
381 WebInspector.CountersGraph.CounterUI = function(memoryCountersPane, title, curre ntValueLabel, graphColor, counter, formatter) 347 WebInspector.CountersGraph.CounterUI = class {
382 { 348 /**
349 * @param {!WebInspector.CountersGraph} memoryCountersPane
350 * @param {string} title
351 * @param {string} currentValueLabel
352 * @param {string} graphColor
353 * @param {!WebInspector.CountersGraph.Counter} counter
354 * @param {(function(number): string)|undefined} formatter
355 */
356 constructor(memoryCountersPane, title, currentValueLabel, graphColor, counter, formatter) {
383 this._memoryCountersPane = memoryCountersPane; 357 this._memoryCountersPane = memoryCountersPane;
384 this.counter = counter; 358 this.counter = counter;
385 this._formatter = formatter || Number.withThousandsSeparator; 359 this._formatter = formatter || Number.withThousandsSeparator;
386 var container = memoryCountersPane._infoWidget.element.createChild("div", "m emory-counter-selector-info"); 360 var container = memoryCountersPane._infoWidget.element.createChild('div', 'm emory-counter-selector-info');
387 361
388 this._setting = WebInspector.settings.createSetting("timelineCountersGraph-" + title, true); 362 this._setting = WebInspector.settings.createSetting('timelineCountersGraph-' + title, true);
389 this._filter = new WebInspector.ToolbarCheckbox(title, title, this._setting) ; 363 this._filter = new WebInspector.ToolbarCheckbox(title, title, this._setting) ;
390 this._filter.inputElement.classList.add("-theme-preserve"); 364 this._filter.inputElement.classList.add('-theme-preserve');
391 var color = WebInspector.Color.parse(graphColor).setAlpha(0.5).asString(WebI nspector.Color.Format.RGBA); 365 var color = WebInspector.Color.parse(graphColor).setAlpha(0.5).asString(WebI nspector.Color.Format.RGBA);
392 if (color) { 366 if (color) {
393 this._filter.element.backgroundColor = color; 367 this._filter.element.backgroundColor = color;
394 this._filter.element.borderColor = "transparent"; 368 this._filter.element.borderColor = 'transparent';
395 } 369 }
396 this._filter.inputElement.addEventListener("click", this._toggleCounterGraph .bind(this)); 370 this._filter.inputElement.addEventListener('click', this._toggleCounterGraph .bind(this));
397 container.appendChild(this._filter.element); 371 container.appendChild(this._filter.element);
398 this._range = this._filter.element.createChild("span", "range"); 372 this._range = this._filter.element.createChild('span', 'range');
399 373
400 this._value = memoryCountersPane._currentValuesBar.createChild("span", "memo ry-counter-value"); 374 this._value = memoryCountersPane._currentValuesBar.createChild('span', 'memo ry-counter-value');
401 this._value.style.color = graphColor; 375 this._value.style.color = graphColor;
402 this.graphColor = graphColor; 376 this.graphColor = graphColor;
403 this.limitColor = WebInspector.Color.parse(graphColor).setAlpha(0.3).asStrin g(WebInspector.Color.Format.RGBA); 377 this.limitColor = WebInspector.Color.parse(graphColor).setAlpha(0.3).asStrin g(WebInspector.Color.Format.RGBA);
404 this.graphYValues = []; 378 this.graphYValues = [];
405 this._verticalPadding = 10; 379 this._verticalPadding = 10;
406 380
407 this._currentValueLabel = currentValueLabel; 381 this._currentValueLabel = currentValueLabel;
408 this._marker = memoryCountersPane._canvasContainer.createChild("div", "memor y-counter-marker"); 382 this._marker = memoryCountersPane._canvasContainer.createChild('div', 'memor y-counter-marker');
409 this._marker.style.backgroundColor = graphColor; 383 this._marker.style.backgroundColor = graphColor;
410 this._clearCurrentValueAndMarker(); 384 this._clearCurrentValueAndMarker();
385 }
386
387 reset() {
388 this._range.textContent = '';
389 }
390
391 /**
392 * @param {number} minValue
393 * @param {number} maxValue
394 */
395 setRange(minValue, maxValue) {
396 var min = this._formatter(minValue);
397 var max = this._formatter(maxValue);
398 this._range.textContent = WebInspector.UIString('[%s\u2009\u2013\u2009%s]', min, max);
399 }
400
401 /**
402 * @param {!WebInspector.Event} event
403 */
404 _toggleCounterGraph(event) {
405 this._value.classList.toggle('hidden', !this._filter.checked());
406 this._memoryCountersPane.refresh();
407 }
408
409 /**
410 * @param {number} x
411 * @return {number}
412 */
413 _recordIndexAt(x) {
414 return this.counter.x.upperBound(
415 x * window.devicePixelRatio, null, this.counter._minimumIndex + 1 , this.counter._maximumIndex + 1) -
416 1;
417 }
418
419 /**
420 * @param {number} x
421 */
422 updateCurrentValue(x) {
423 if (!this.visible() || !this.counter.values.length || !this.counter.x)
424 return;
425 var index = this._recordIndexAt(x);
426 var value = Number.withThousandsSeparator(this.counter.values[index]);
427 this._value.textContent = WebInspector.UIString(this._currentValueLabel, val ue);
428 var y = this.graphYValues[index] / window.devicePixelRatio;
429 this._marker.style.left = x + 'px';
430 this._marker.style.top = y + 'px';
431 this._marker.classList.remove('hidden');
432 }
433
434 _clearCurrentValueAndMarker() {
435 this._value.textContent = '';
436 this._marker.classList.add('hidden');
437 }
438
439 /**
440 * @param {!HTMLCanvasElement} canvas
441 */
442 _drawGraph(canvas) {
443 var ctx = canvas.getContext('2d');
444 var width = canvas.width;
445 var height = canvas.height - 2 * this._verticalPadding;
446 if (height <= 0) {
447 this.graphYValues = [];
448 return;
449 }
450 var originY = this._verticalPadding;
451 var counter = this.counter;
452 var values = counter.values;
453
454 if (!values.length)
455 return;
456
457 var bounds = counter._calculateBounds();
458 var minValue = bounds.min;
459 var maxValue = bounds.max;
460 this.setRange(minValue, maxValue);
461
462 if (!this.visible())
463 return;
464
465 var yValues = this.graphYValues;
466 var maxYRange = maxValue - minValue;
467 var yFactor = maxYRange ? height / (maxYRange) : 1;
468
469 ctx.save();
470 ctx.lineWidth = window.devicePixelRatio;
471 if (ctx.lineWidth % 2)
472 ctx.translate(0.5, 0.5);
473 ctx.beginPath();
474 var value = values[counter._minimumIndex];
475 var currentY = Math.round(originY + height - (value - minValue) * yFactor);
476 ctx.moveTo(0, currentY);
477 for (var i = counter._minimumIndex; i <= counter._maximumIndex; i++) {
478 var x = Math.round(counter.x[i]);
479 ctx.lineTo(x, currentY);
480 var currentValue = values[i];
481 if (typeof currentValue !== 'undefined')
482 value = currentValue;
483 currentY = Math.round(originY + height - (value - minValue) * yFactor);
484 ctx.lineTo(x, currentY);
485 yValues[i] = currentY;
486 }
487 yValues.length = i;
488 ctx.lineTo(width, currentY);
489 ctx.strokeStyle = this.graphColor;
490 ctx.stroke();
491 if (counter._limitValue) {
492 var limitLineY = Math.round(originY + height - (counter._limitValue - minV alue) * yFactor);
493 ctx.moveTo(0, limitLineY);
494 ctx.lineTo(width, limitLineY);
495 ctx.strokeStyle = this.limitColor;
496 ctx.stroke();
497 }
498 ctx.closePath();
499 ctx.restore();
500 }
501
502 /**
503 * @return {boolean}
504 */
505 visible() {
506 return this._filter.checked();
507 }
411 }; 508 };
412 509
413 WebInspector.CountersGraph.CounterUI.prototype = { 510 /**
414 reset: function() 511 * @implements {WebInspector.TimelineGrid.Calculator}
415 { 512 * @unrestricted
416 this._range.textContent = ""; 513 */
417 }, 514 WebInspector.CounterGraphCalculator = class {
418 515 /**
419 /** 516 * @param {!WebInspector.TimelineModel} model
420 * @param {number} minValue 517 */
421 * @param {number} maxValue 518 constructor(model) {
422 */ 519 this._model = model;
423 setRange: function(minValue, maxValue) 520 }
424 { 521
425 var min = this._formatter(minValue); 522 /**
426 var max = this._formatter(maxValue); 523 * @override
427 this._range.textContent = WebInspector.UIString("[%s\u2009\u2013\u2009%s ]", min, max); 524 * @return {number}
428 }, 525 */
429 526 paddingLeft() {
430 /** 527 return this._paddingLeft;
431 * @param {!WebInspector.Event} event 528 }
432 */ 529
433 _toggleCounterGraph: function(event) 530 /**
434 { 531 * @override
435 this._value.classList.toggle("hidden", !this._filter.checked()); 532 * @param {number} time
436 this._memoryCountersPane.refresh(); 533 * @return {number}
437 }, 534 */
438 535 computePosition(time) {
439 /** 536 return (time - this._minimumBoundary) / this.boundarySpan() * this._workingA rea + this._paddingLeft;
440 * @param {number} x 537 }
441 * @return {number} 538
442 */ 539 setWindow(minimumBoundary, maximumBoundary) {
443 _recordIndexAt: function(x) 540 this._minimumBoundary = minimumBoundary;
444 { 541 this._maximumBoundary = maximumBoundary;
445 return this.counter.x.upperBound(x * window.devicePixelRatio, null, this .counter._minimumIndex + 1, this.counter._maximumIndex + 1) - 1; 542 }
446 }, 543
447 544 /**
448 /** 545 * @param {number} clientWidth
449 * @param {number} x 546 * @param {number=} paddingLeft
450 */ 547 */
451 updateCurrentValue: function(x) 548 setDisplayWindow(clientWidth, paddingLeft) {
452 { 549 this._paddingLeft = paddingLeft || 0;
453 if (!this.visible() || !this.counter.values.length || !this.counter.x) 550 this._workingArea = clientWidth - WebInspector.CounterGraphCalculator._minWi dth - this._paddingLeft;
454 return; 551 }
455 var index = this._recordIndexAt(x); 552
456 var value = Number.withThousandsSeparator(this.counter.values[index]); 553 /**
457 this._value.textContent = WebInspector.UIString(this._currentValueLabel, value); 554 * @override
458 var y = this.graphYValues[index] / window.devicePixelRatio; 555 * @param {number} value
459 this._marker.style.left = x + "px"; 556 * @param {number=} precision
460 this._marker.style.top = y + "px"; 557 * @return {string}
461 this._marker.classList.remove("hidden"); 558 */
462 }, 559 formatValue(value, precision) {
463 560 return Number.preciseMillisToString(value - this.zeroTime(), precision);
464 _clearCurrentValueAndMarker: function() 561 }
465 { 562
466 this._value.textContent = ""; 563 /**
467 this._marker.classList.add("hidden"); 564 * @override
468 }, 565 * @return {number}
469 566 */
470 /** 567 maximumBoundary() {
471 * @param {!HTMLCanvasElement} canvas 568 return this._maximumBoundary;
472 */ 569 }
473 _drawGraph: function(canvas) 570
474 { 571 /**
475 var ctx = canvas.getContext("2d"); 572 * @override
476 var width = canvas.width; 573 * @return {number}
477 var height = canvas.height - 2 * this._verticalPadding; 574 */
478 if (height <= 0) { 575 minimumBoundary() {
479 this.graphYValues = []; 576 return this._minimumBoundary;
480 return; 577 }
481 } 578
482 var originY = this._verticalPadding; 579 /**
483 var counter = this.counter; 580 * @override
484 var values = counter.values; 581 * @return {number}
485 582 */
486 if (!values.length) 583 zeroTime() {
487 return; 584 return this._model.minimumRecordTime();
488 585 }
489 var bounds = counter._calculateBounds(); 586
490 var minValue = bounds.min; 587 /**
491 var maxValue = bounds.max; 588 * @override
492 this.setRange(minValue, maxValue); 589 * @return {number}
493 590 */
494 if (!this.visible()) 591 boundarySpan() {
495 return; 592 return this._maximumBoundary - this._minimumBoundary;
496 593 }
497 var yValues = this.graphYValues;
498 var maxYRange = maxValue - minValue;
499 var yFactor = maxYRange ? height / (maxYRange) : 1;
500
501 ctx.save();
502 ctx.lineWidth = window.devicePixelRatio;
503 if (ctx.lineWidth % 2)
504 ctx.translate(0.5, 0.5);
505 ctx.beginPath();
506 var value = values[counter._minimumIndex];
507 var currentY = Math.round(originY + height - (value - minValue) * yFacto r);
508 ctx.moveTo(0, currentY);
509 for (var i = counter._minimumIndex; i <= counter._maximumIndex; i++) {
510 var x = Math.round(counter.x[i]);
511 ctx.lineTo(x, currentY);
512 var currentValue = values[i];
513 if (typeof currentValue !== "undefined")
514 value = currentValue;
515 currentY = Math.round(originY + height - (value - minValue) * yFacto r);
516 ctx.lineTo(x, currentY);
517 yValues[i] = currentY;
518 }
519 yValues.length = i;
520 ctx.lineTo(width, currentY);
521 ctx.strokeStyle = this.graphColor;
522 ctx.stroke();
523 if (counter._limitValue) {
524 var limitLineY = Math.round(originY + height - (counter._limitValue - minValue) * yFactor);
525 ctx.moveTo(0, limitLineY);
526 ctx.lineTo(width, limitLineY);
527 ctx.strokeStyle = this.limitColor;
528 ctx.stroke();
529 }
530 ctx.closePath();
531 ctx.restore();
532 },
533
534 /**
535 * @return {boolean}
536 */
537 visible: function()
538 {
539 return this._filter.checked();
540 }
541 }; 594 };
542 595
543 /**
544 * @constructor
545 * @param {!WebInspector.TimelineModel} model
546 * @implements {WebInspector.TimelineGrid.Calculator}
547 */
548 WebInspector.CounterGraphCalculator = function(model)
549 {
550 this._model = model;
551 };
552
553 WebInspector.CounterGraphCalculator._minWidth = 5; 596 WebInspector.CounterGraphCalculator._minWidth = 5;
554
555 WebInspector.CounterGraphCalculator.prototype = {
556 /**
557 * @override
558 * @return {number}
559 */
560 paddingLeft: function()
561 {
562 return this._paddingLeft;
563 },
564
565 /**
566 * @override
567 * @param {number} time
568 * @return {number}
569 */
570 computePosition: function(time)
571 {
572 return (time - this._minimumBoundary) / this.boundarySpan() * this._work ingArea + this._paddingLeft;
573 },
574
575 setWindow: function(minimumBoundary, maximumBoundary)
576 {
577 this._minimumBoundary = minimumBoundary;
578 this._maximumBoundary = maximumBoundary;
579 },
580
581 /**
582 * @param {number} clientWidth
583 * @param {number=} paddingLeft
584 */
585 setDisplayWindow: function(clientWidth, paddingLeft)
586 {
587 this._paddingLeft = paddingLeft || 0;
588 this._workingArea = clientWidth - WebInspector.CounterGraphCalculator._m inWidth - this._paddingLeft;
589 },
590
591 /**
592 * @override
593 * @param {number} value
594 * @param {number=} precision
595 * @return {string}
596 */
597 formatValue: function(value, precision)
598 {
599 return Number.preciseMillisToString(value - this.zeroTime(), precision);
600 },
601
602 /**
603 * @override
604 * @return {number}
605 */
606 maximumBoundary: function()
607 {
608 return this._maximumBoundary;
609 },
610
611 /**
612 * @override
613 * @return {number}
614 */
615 minimumBoundary: function()
616 {
617 return this._minimumBoundary;
618 },
619
620 /**
621 * @override
622 * @return {number}
623 */
624 zeroTime: function()
625 {
626 return this._model.minimumRecordTime();
627 },
628
629 /**
630 * @override
631 * @return {number}
632 */
633 boundarySpan: function()
634 {
635 return this._maximumBoundary - this._minimumBoundary;
636 }
637 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698