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

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

Issue 212593009: FlameChart: move CPUProfiler related part of the FlameChart into a separate file. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: missed file was added. test was fixed. Created 6 years, 9 months 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 | Annotate | Revision Log
« no previous file with comments | « Source/devtools/front_end/CPUProfileView.js ('k') | Source/devtools/front_end/ProfilesPanel.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 27 matching lines...) Expand all
38 * @param {number} startTime 38 * @param {number} startTime
39 * @param {number} endTime 39 * @param {number} endTime
40 */ 40 */
41 requestWindowTimes: function(startTime, endTime) { }, 41 requestWindowTimes: function(startTime, endTime) { },
42 } 42 }
43 43
44 /** 44 /**
45 * @constructor 45 * @constructor
46 * @extends {WebInspector.VBox} 46 * @extends {WebInspector.VBox}
47 * @param {!WebInspector.FlameChartDataProvider} dataProvider 47 * @param {!WebInspector.FlameChartDataProvider} dataProvider
48 * @param {!WebInspector.FlameChartDelegate} flameChartDelegate
49 * @param {boolean} isTopDown
50 * @param {boolean} timeBasedWindow
48 */ 51 */
49 WebInspector.FlameChart = function(dataProvider) 52 WebInspector.FlameChart = function(dataProvider, flameChartDelegate, isTopDown, timeBasedWindow)
50 { 53 {
51 WebInspector.VBox.call(this); 54 WebInspector.VBox.call(this);
52 this.registerRequiredCSS("flameChart.css"); 55 this.element.classList.add("flame-chart-main-pane");
53 this.element.id = "cpu-flame-chart"; 56 this._flameChartDelegate = flameChartDelegate;
57 this._isTopDown = isTopDown;
58 this._timeBasedWindow = timeBasedWindow;
54 59
55 this._overviewPane = new WebInspector.FlameChart.OverviewPane(dataProvider); 60 this._calculator = new WebInspector.FlameChart.Calculator();
56 this._overviewPane.show(this.element);
57 61
58 this._mainPane = new WebInspector.FlameChart.MainPane(dataProvider, this._ov erviewPane, true, false); 62 this._canvas = this.element.createChild("canvas");
59 this._mainPane.show(this.element); 63 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this));
60 this._mainPane.addEventListener(WebInspector.FlameChart.Events.EntrySelected , this._onEntrySelected, this); 64 this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), f alse);
61 this._overviewPane._overviewGrid.addEventListener(WebInspector.OverviewGrid. Events.WindowChanged, this._onWindowChanged, this); 65 this._canvas.addEventListener("click", this._onClick.bind(this), false);
66 WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind( this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "mov e", null);
67
68 this._entryInfo = this.element.createChild("div", "profile-entry-info");
69 this._highlightElement = this.element.createChild("div", "flame-chart-highli ght-element");
70 this._selectedElement = this.element.createChild("div", "flame-chart-selecte d-element");
71
72 this._dataProvider = dataProvider;
73
74 this._windowLeft = 0.0;
75 this._windowRight = 1.0;
76 this._windowWidth = 1.0;
77 this._timeWindowLeft = 0;
78 this._timeWindowRight = Infinity;
79 this._barHeight = dataProvider.barHeight();
80 this._barHeightDelta = this._isTopDown ? -this._barHeight : this._barHeight;
81 this._minWidth = 1;
82 this._paddingLeft = this._dataProvider.paddingLeft();
83 this._highlightedEntryIndex = -1;
84 this._selectedEntryIndex = -1;
85 this._textWidth = {};
62 } 86 }
63 87
64 WebInspector.FlameChart.DividersBarHeight = 20; 88 WebInspector.FlameChart.DividersBarHeight = 20;
65 89
66 WebInspector.FlameChart.prototype = {
67 /**
68 * @param {!WebInspector.Event} event
69 */
70 _onWindowChanged: function(event)
71 {
72 this._mainPane.changeWindow(this._overviewPane._overviewGrid.windowLeft( ), this._overviewPane._overviewGrid.windowRight());
73 },
74
75 /**
76 * @param {!number} timeLeft
77 * @param {!number} timeRight
78 */
79 selectRange: function(timeLeft, timeRight)
80 {
81 this._overviewPane._selectRange(timeLeft, timeRight);
82 },
83
84 /**
85 * @param {!WebInspector.Event} event
86 */
87 _onEntrySelected: function(event)
88 {
89 this.dispatchEventToListeners(WebInspector.FlameChart.Events.EntrySelect ed, event.data);
90 },
91
92 update: function()
93 {
94 this._overviewPane.update();
95 this._mainPane.update();
96 },
97
98 __proto__: WebInspector.VBox.prototype
99 };
100
101 /** 90 /**
102 * @interface 91 * @interface
103 */ 92 */
104 WebInspector.FlameChartDataProvider = function() 93 WebInspector.FlameChartDataProvider = function()
105 { 94 {
106 } 95 }
107 96
108 /** @typedef {!{ 97 /** @typedef {!{
109 entryLevels: !Array.<number>, 98 entryLevels: !Array.<number>,
110 entryTotalTimes: !Array.<number>, 99 entryTotalTimes: !Array.<number>,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 * @return {?{startTimeOffset: number, endTimeOffset: number}} 204 * @return {?{startTimeOffset: number, endTimeOffset: number}}
216 */ 205 */
217 highlightTimeRange: function(entryIndex) { }, 206 highlightTimeRange: function(entryIndex) { },
218 207
219 /** 208 /**
220 * @return {number} 209 * @return {number}
221 */ 210 */
222 paddingLeft: function() { } 211 paddingLeft: function() { }
223 } 212 }
224 213
214 WebInspector.FlameChart.Events = {
215 EntrySelected: "EntrySelected"
216 }
217
225 /** 218 /**
226 * @constructor 219 * @constructor
227 * @implements {WebInspector.TimelineGrid.Calculator} 220 * @implements {WebInspector.TimelineGrid.Calculator}
228 */ 221 */
229 WebInspector.FlameChart.Calculator = function() 222 WebInspector.FlameChart.Calculator = function()
230 { 223 {
231 this._paddingLeft = 0; 224 this._paddingLeft = 0;
232 } 225 }
233 226
234 WebInspector.FlameChart.Calculator.prototype = { 227 WebInspector.FlameChart.Calculator.prototype = {
235 /** 228 /**
236 * @return {number} 229 * @return {number}
237 */ 230 */
238 paddingLeft: function() 231 paddingLeft: function()
239 { 232 {
240 return this._paddingLeft; 233 return this._paddingLeft;
241 }, 234 },
242 235
243 /** 236 /**
244 * @param {!WebInspector.FlameChart.MainPane} mainPane 237 * @param {!WebInspector.FlameChart} mainPane
245 */ 238 */
246 _updateBoundaries: function(mainPane) 239 _updateBoundaries: function(mainPane)
247 { 240 {
248 this._totalTime = mainPane._dataProvider.totalTime(); 241 this._totalTime = mainPane._dataProvider.totalTime();
249 this._zeroTime = mainPane._dataProvider.zeroTime(); 242 this._zeroTime = mainPane._dataProvider.zeroTime();
250 this._minimumBoundaries = this._zeroTime + mainPane._windowLeft * this._ totalTime; 243 this._minimumBoundaries = this._zeroTime + mainPane._windowLeft * this._ totalTime;
251 this._maximumBoundaries = this._zeroTime + mainPane._windowRight * this. _totalTime; 244 this._maximumBoundaries = this._zeroTime + mainPane._windowRight * this. _totalTime;
252 this._paddingLeft = mainPane._paddingLeft; 245 this._paddingLeft = mainPane._paddingLeft;
253 this._width = mainPane._canvas.width / window.devicePixelRatio - this._p addingLeft; 246 this._width = mainPane._canvas.width / window.devicePixelRatio - this._p addingLeft;
254 this._timeToPixel = this._width / this.boundarySpan(); 247 this._timeToPixel = this._width / this.boundarySpan();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 292
300 /** 293 /**
301 * @return {number} 294 * @return {number}
302 */ 295 */
303 boundarySpan: function() 296 boundarySpan: function()
304 { 297 {
305 return this._maximumBoundaries - this._minimumBoundaries; 298 return this._maximumBoundaries - this._minimumBoundaries;
306 } 299 }
307 } 300 }
308 301
309 /** 302 WebInspector.FlameChart.prototype = {
310 * @constructor
311 * @implements {WebInspector.TimelineGrid.Calculator}
312 */
313 WebInspector.FlameChart.OverviewCalculator = function()
314 {
315 }
316
317 WebInspector.FlameChart.OverviewCalculator.prototype = {
318 /**
319 * @return {number}
320 */
321 paddingLeft: function()
322 {
323 return 0;
324 },
325
326 /**
327 * @param {!WebInspector.FlameChart.OverviewPane} overviewPane
328 */
329 _updateBoundaries: function(overviewPane)
330 {
331 this._minimumBoundaries = 0;
332 var totalTime = overviewPane._dataProvider.totalTime();
333 this._maximumBoundaries = totalTime;
334 this._xScaleFactor = overviewPane._overviewCanvas.width / totalTime;
335 },
336
337 /**
338 * @param {number} time
339 * @return {number}
340 */
341 computePosition: function(time)
342 {
343 return (time - this._minimumBoundaries) * this._xScaleFactor;
344 },
345
346 /**
347 * @param {number} value
348 * @param {number=} precision
349 * @return {string}
350 */
351 formatTime: function(value, precision)
352 {
353 return Number.secondsToString((value + this._minimumBoundaries) / 1000);
354 },
355
356 /**
357 * @return {number}
358 */
359 maximumBoundary: function()
360 {
361 return this._maximumBoundaries;
362 },
363
364 /**
365 * @return {number}
366 */
367 minimumBoundary: function()
368 {
369 return this._minimumBoundaries;
370 },
371
372 /**
373 * @return {number}
374 */
375 zeroTime: function()
376 {
377 return this._minimumBoundaries;
378 },
379
380 /**
381 * @return {number}
382 */
383 boundarySpan: function()
384 {
385 return this._maximumBoundaries - this._minimumBoundaries;
386 }
387 }
388
389 WebInspector.FlameChart.Events = {
390 EntrySelected: "EntrySelected"
391 }
392
393 /**
394 * @constructor
395 */
396 WebInspector.FlameChart.ColorGenerator = function()
397 {
398 this._colors = {};
399 this._currentColorIndex = 0;
400 }
401
402 WebInspector.FlameChart.ColorGenerator.prototype = {
403 /**
404 * @param {string} id
405 * @param {string|!CanvasGradient} color
406 */
407 setColorForID: function(id, color)
408 {
409 this._colors[id] = color;
410 },
411
412 /**
413 * @param {!string} id
414 * @param {number=} sat
415 * @return {!string}
416 */
417 colorForID: function(id, sat)
418 {
419 if (typeof sat !== "number")
420 sat = 100;
421 var color = this._colors[id];
422 if (!color) {
423 color = this._createColor(this._currentColorIndex++, sat);
424 this._colors[id] = color;
425 }
426 return color;
427 },
428
429 /**
430 * @param {!number} index
431 * @param {!number} sat
432 */
433 _createColor: function(index, sat)
434 {
435 var hue = (index * 7 + 12 * (index % 2)) % 360;
436 return "hsla(" + hue + ", " + sat + "%, 66%, 0.7)";
437 }
438 }
439
440 /**
441 * @constructor
442 * @extends {WebInspector.VBox}
443 * @implements {WebInspector.FlameChartDelegate}
444 * @param {!WebInspector.FlameChartDataProvider} dataProvider
445 */
446 WebInspector.FlameChart.OverviewPane = function(dataProvider)
447 {
448 WebInspector.VBox.call(this);
449 this.element.classList.add("flame-chart-overview-pane");
450 this._overviewContainer = this.element.createChild("div", "overview-containe r");
451 this._overviewGrid = new WebInspector.OverviewGrid("flame-chart");
452 this._overviewGrid.element.classList.add("fill");
453 this._overviewCanvas = this._overviewContainer.createChild("canvas", "flame- chart-overview-canvas");
454 this._overviewContainer.appendChild(this._overviewGrid.element);
455 this._overviewCalculator = new WebInspector.FlameChart.OverviewCalculator();
456 this._dataProvider = dataProvider;
457 }
458
459 WebInspector.FlameChart.OverviewPane.prototype = {
460 /**
461 * @param {number} windowStartTime
462 * @param {number} windowEndTime
463 */
464 requestWindowTimes: function(windowStartTime, windowEndTime)
465 {
466 this._overviewGrid.setWindow(windowStartTime / this._dataProvider.totalT ime(), windowEndTime / this._dataProvider.totalTime());
467 },
468
469 /**
470 * @param {!number} timeLeft
471 * @param {!number} timeRight
472 */
473 _selectRange: function(timeLeft, timeRight)
474 {
475 this._overviewGrid.setWindow(timeLeft / this._dataProvider.totalTime(), timeRight / this._dataProvider.totalTime());
476 },
477
478 /**
479 * @return {?WebInspector.FlameChart.TimelineData}
480 */
481 _timelineData: function()
482 {
483 return this._dataProvider.timelineData();
484 },
485
486 onResize: function()
487 {
488 this._scheduleUpdate();
489 },
490
491 _scheduleUpdate: function()
492 {
493 if (this._updateTimerId)
494 return;
495 this._updateTimerId = requestAnimationFrame(this.update.bind(this));
496 },
497
498 update: function()
499 {
500 this._updateTimerId = 0;
501 var timelineData = this._timelineData();
502 if (!timelineData)
503 return;
504 this._resetCanvas(this._overviewContainer.clientWidth, this._overviewCon tainer.clientHeight - WebInspector.FlameChart.DividersBarHeight);
505 this._overviewCalculator._updateBoundaries(this);
506 this._overviewGrid.updateDividers(this._overviewCalculator);
507 WebInspector.FlameChart.OverviewPane.drawOverviewCanvas(
508 this._dataProvider,
509 timelineData,
510 this._overviewCanvas.getContext("2d"),
511 this._overviewContainer.clientWidth,
512 this._overviewContainer.clientHeight - WebInspector.FlameChart.Divid ersBarHeight
513 );
514 },
515
516 /**
517 * @param {!number} width
518 * @param {!number} height
519 */
520 _resetCanvas: function(width, height)
521 {
522 var ratio = window.devicePixelRatio;
523 this._overviewCanvas.width = width * ratio;
524 this._overviewCanvas.height = height * ratio;
525 },
526
527 __proto__: WebInspector.VBox.prototype
528 }
529
530 /**
531 * @param {!WebInspector.FlameChartDataProvider} dataProvider
532 * @param {!WebInspector.FlameChart.TimelineData} timelineData
533 * @param {!number} width
534 */
535 WebInspector.FlameChart.OverviewPane.calculateDrawData = function(dataProvider, timelineData, width)
536 {
537 var entryOffsets = timelineData.entryOffsets;
538 var entryTotalTimes = timelineData.entryTotalTimes;
539 var entryLevels = timelineData.entryLevels;
540 var length = entryOffsets.length;
541
542 var drawData = new Uint8Array(width);
543 var scaleFactor = width / dataProvider.totalTime();
544
545 for (var entryIndex = 0; entryIndex < length; ++entryIndex) {
546 var start = Math.floor(entryOffsets[entryIndex] * scaleFactor);
547 var finish = Math.floor((entryOffsets[entryIndex] + entryTotalTimes[entr yIndex]) * scaleFactor);
548 for (var x = start; x <= finish; ++x)
549 drawData[x] = Math.max(drawData[x], entryLevels[entryIndex] + 1);
550 }
551 return drawData;
552 }
553
554 /**
555 * @param {!WebInspector.FlameChartDataProvider} dataProvider
556 * @param {!WebInspector.FlameChart.TimelineData} timelineData
557 * @param {!Object} context
558 * @param {!number} width
559 * @param {!number} height
560 */
561 WebInspector.FlameChart.OverviewPane.drawOverviewCanvas = function(dataProvider, timelineData, context, width, height)
562 {
563 var drawData = WebInspector.FlameChart.OverviewPane.calculateDrawData(dataPr ovider, timelineData, width);
564 if (!drawData)
565 return;
566
567 var ratio = window.devicePixelRatio;
568 var canvasWidth = width * ratio;
569 var canvasHeight = height * ratio;
570
571 var yScaleFactor = canvasHeight / (dataProvider.maxStackDepth() * 1.1);
572 context.lineWidth = 1;
573 context.translate(0.5, 0.5);
574 context.strokeStyle = "rgba(20,0,0,0.4)";
575 context.fillStyle = "rgba(214,225,254,0.8)";
576 context.moveTo(-1, canvasHeight - 1);
577 if (drawData)
578 context.lineTo(-1, Math.round(height - drawData[0] * yScaleFactor - 1));
579 var value;
580 for (var x = 0; x < width; ++x) {
581 value = Math.round(canvasHeight - drawData[x] * yScaleFactor - 1);
582 context.lineTo(x * ratio, value);
583 }
584 context.lineTo(canvasWidth + 1, value);
585 context.lineTo(canvasWidth + 1, canvasHeight - 1);
586 context.fill();
587 context.stroke();
588 context.closePath();
589 }
590
591 /**
592 * @constructor
593 * @extends {WebInspector.VBox}
594 * @param {!WebInspector.FlameChartDataProvider} dataProvider
595 * @param {!WebInspector.FlameChartDelegate} flameChartDelegate
596 * @param {boolean} isTopDown
597 * @param {boolean} timeBasedWindow
598 */
599 WebInspector.FlameChart.MainPane = function(dataProvider, flameChartDelegate, is TopDown, timeBasedWindow)
600 {
601 WebInspector.VBox.call(this);
602 this.element.classList.add("flame-chart-main-pane");
603 this._flameChartDelegate = flameChartDelegate;
604 this._isTopDown = isTopDown;
605 this._timeBasedWindow = timeBasedWindow;
606
607 this._calculator = new WebInspector.FlameChart.Calculator();
608
609 this._canvas = this.element.createChild("canvas");
610 this._canvas.addEventListener("mousemove", this._onMouseMove.bind(this));
611 this._canvas.addEventListener("mousewheel", this._onMouseWheel.bind(this), f alse);
612 this._canvas.addEventListener("click", this._onClick.bind(this), false);
613 WebInspector.installDragHandle(this._canvas, this._startCanvasDragging.bind( this), this._canvasDragging.bind(this), this._endCanvasDragging.bind(this), "mov e", null);
614
615 this._entryInfo = this.element.createChild("div", "profile-entry-info");
616 this._highlightElement = this.element.createChild("div", "flame-chart-highli ght-element");
617 this._selectedElement = this.element.createChild("div", "flame-chart-selecte d-element");
618
619 this._dataProvider = dataProvider;
620
621 this._windowLeft = 0.0;
622 this._windowRight = 1.0;
623 this._windowWidth = 1.0;
624 this._timeWindowLeft = 0;
625 this._timeWindowRight = Infinity;
626 this._barHeight = dataProvider.barHeight();
627 this._barHeightDelta = this._isTopDown ? -this._barHeight : this._barHeight;
628 this._minWidth = 1;
629 this._paddingLeft = this._dataProvider.paddingLeft();
630 this._highlightedEntryIndex = -1;
631 this._selectedEntryIndex = -1;
632 this._textWidth = {};
633 }
634
635 WebInspector.FlameChart.MainPane.prototype = {
636 _resetCanvas: function() 303 _resetCanvas: function()
637 { 304 {
638 var ratio = window.devicePixelRatio; 305 var ratio = window.devicePixelRatio;
639 this._canvas.width = this._offsetWidth * ratio; 306 this._canvas.width = this._offsetWidth * ratio;
640 this._canvas.height = this._offsetHeight * ratio; 307 this._canvas.height = this._offsetHeight * ratio;
641 }, 308 },
642 309
643 /** 310 /**
644 * @return {?WebInspector.FlameChart.TimelineData} 311 * @return {?WebInspector.FlameChart.TimelineData}
645 */ 312 */
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 reset: function() 788 reset: function()
1122 { 789 {
1123 this._highlightedEntryIndex = -1; 790 this._highlightedEntryIndex = -1;
1124 this._selectedEntryIndex = -1; 791 this._selectedEntryIndex = -1;
1125 this._textWidth = {}; 792 this._textWidth = {};
1126 this.update(); 793 this.update();
1127 }, 794 },
1128 795
1129 __proto__: WebInspector.VBox.prototype 796 __proto__: WebInspector.VBox.prototype
1130 } 797 }
OLDNEW
« no previous file with comments | « Source/devtools/front_end/CPUProfileView.js ('k') | Source/devtools/front_end/ProfilesPanel.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698