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

Unified Diff: Source/devtools/front_end/CountersGraph.js

Issue 210053002: DevTools: merge MemoryStatistics.js and CountersGraph.js, extract DOMCountersGraph.js (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/DOMCountersGraph.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/devtools/front_end/CountersGraph.js
diff --git a/Source/devtools/front_end/CountersGraph.js b/Source/devtools/front_end/CountersGraph.js
index 02e96d2c719e3b832cc1e8573aeaf7aae8941dea..a36aeaf6a3a9573e1de5277eaa3d305822e5482c 100644
--- a/Source/devtools/front_end/CountersGraph.js
+++ b/Source/devtools/front_end/CountersGraph.js
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -30,123 +30,240 @@
/**
* @constructor
- * @extends {WebInspector.MemoryStatistics}
- * @implements {WebInspector.TimelineModeView}
+ * @extends {WebInspector.SplitView}
* @param {!WebInspector.TimelineModeViewDelegate} delegate
* @param {!WebInspector.TimelineModel} model
*/
WebInspector.CountersGraph = function(delegate, model)
{
- WebInspector.MemoryStatistics.call(this, delegate, model);
-}
+ WebInspector.SplitView.call(this, true, false);
-/**
- * @constructor
- * @extends {WebInspector.CounterUIBase}
- * @param {!WebInspector.CountersGraph} memoryCountersPane
- * @param {string} title
- * @param {string} currentValueLabel
- * @param {!string} color
- * @param {!WebInspector.MemoryStatistics.Counter} counter
- */
-WebInspector.CounterUI = function(memoryCountersPane, title, currentValueLabel, color, counter)
-{
- WebInspector.CounterUIBase.call(this, memoryCountersPane, title, color, counter)
- this._range = this._swatch.element.createChild("span");
+ this.element.id = "memory-graphs-container";
- this._value = memoryCountersPane._currentValuesBar.createChild("span", "memory-counter-value");
- this._value.style.color = color;
- this._currentValueLabel = currentValueLabel;
- this._marker = memoryCountersPane._canvasContainer.createChild("div", "memory-counter-marker");
- this._marker.style.backgroundColor = color;
- this.clearCurrentValueAndMarker();
+ this._delegate = delegate;
+ this._model = model;
+ this._calculator = new WebInspector.TimelineCalculator(this._model);
- this.graphColor = color;
- this.graphYValues = [];
+ this._graphsContainer = this.mainElement();
+ this._createCurrentValuesBar();
+ this._canvasView = new WebInspector.VBoxWithResizeCallback(this._resize.bind(this));
+ this._canvasView.show(this._graphsContainer);
+ this._canvasContainer = this._canvasView.element;
+ this._canvasContainer.id = "memory-graphs-canvas-container";
+ this._canvas = this._canvasContainer.createChild("canvas");
+ this._canvas.id = "memory-counters-graph";
+
+ this._canvasContainer.addEventListener("mouseover", this._onMouseMove.bind(this), true);
+ this._canvasContainer.addEventListener("mousemove", this._onMouseMove.bind(this), true);
+ this._canvasContainer.addEventListener("mouseout", this._onMouseOut.bind(this), true);
+ this._canvasContainer.addEventListener("click", this._onClick.bind(this), true);
+ // We create extra timeline grid here to reuse its event dividers.
+ this._timelineGrid = new WebInspector.TimelineGrid();
+ this._canvasContainer.appendChild(this._timelineGrid.dividersElement);
+
+ // Populate sidebar
+ this.sidebarElement().createChild("div", "sidebar-tree sidebar-tree-section").textContent = WebInspector.UIString("COUNTERS");
+ this._counters = [];
+ this._counterUI = [];
}
-WebInspector.CounterUI.prototype = {
- reset: function()
+WebInspector.CountersGraph.prototype = {
+ _createCurrentValuesBar: function()
{
- this._range.textContent = "";
+ this._currentValuesBar = this._graphsContainer.createChild("div");
+ this._currentValuesBar.id = "counter-values-bar";
},
/**
- * @param {number} minValue
- * @param {number} maxValue
+ * @param {string} uiName
+ * @param {string} uiValueTemplate
+ * @param {string} color
+ * @return {!WebInspector.CountersGraph.Counter}
*/
- setRange: function(minValue, maxValue)
+ createCounter: function(uiName, uiValueTemplate, color)
{
- this._range.textContent = WebInspector.UIString("[%d:%d]", minValue, maxValue);
+ var counter = new WebInspector.CountersGraph.Counter();
+ this._counters.push(counter);
+ this._counterUI.push(new WebInspector.CountersGraph.CounterUI(this, uiName, uiValueTemplate, color, counter));
+ return counter;
},
- __proto__: WebInspector.CounterUIBase.prototype
-}
+ reset: function()
+ {
+ for (var i = 0; i < this._counters.length; ++i) {
+ this._counters[i].reset();
+ this._counterUI[i].reset();
+ }
+ this.refresh();
+ },
+ _resize: function()
+ {
+ var parentElement = this._canvas.parentElement;
+ this._canvas.width = parentElement.clientWidth;
+ this._canvas.height = parentElement.clientHeight;
+ var timelinePaddingLeft = 15;
+ this._calculator.setDisplayWindow(timelinePaddingLeft, this._canvas.width);
+ this.refresh();
+ },
-WebInspector.CountersGraph.prototype = {
- _createCurrentValuesBar: function()
+ /**
+ * @param {number} startTime
+ * @param {number} endTime
+ */
+ setWindowTimes: function(startTime, endTime)
{
- this._currentValuesBar = this._graphsContainer.createChild("div");
- this._currentValuesBar.id = "counter-values-bar";
- this._graphsContainer.classList.add("dom-counters");
+ this._calculator.setWindow(startTime, endTime);
+ this.scheduleRefresh();
},
- createAllCounters: function()
+ scheduleRefresh: function()
{
- this._counters = [];
- this._counterUI = [];
- this._createCounter(WebInspector.UIString("Documents"), WebInspector.UIString("Documents: %d"), "#d00", "documents");
- this._createCounter(WebInspector.UIString("Nodes"), WebInspector.UIString("Nodes: %d"), "#0a0", "nodes");
- this._createCounter(WebInspector.UIString("Listeners"), WebInspector.UIString("Listeners: %d"), "#00d", "jsEventListeners");
- if (WebInspector.experimentsSettings.gpuTimeline.isEnabled())
- this._createCounter(WebInspector.UIString("GPU Memory"), WebInspector.UIString("GPU Memory [KB]: %d"), "#c0c", "gpuMemoryUsedKB");
+ if (this._refreshTimer)
+ return;
+ this._refreshTimer = setTimeout(this.refresh.bind(this), 300);
+ },
+
+ draw: function()
+ {
+ for (var i = 0; i < this._counters.length; ++i) {
+ this._counters[i]._calculateVisibleIndexes(this._calculator);
+ this._counters[i]._calculateXValues(this._canvas.width);
+ }
+ this._clear();
+ this._setVerticalClip(10, this._canvas.height - 20);
+
+ for (var i = 0; i < this._counterUI.length; i++)
+ this._drawGraph(this._counterUI[i]);
},
/**
- * @param {string} uiName
- * @param {string} uiValueTemplate
- * @param {string} color
- * @param {string} protocolName
+ * @param {?Event} event
*/
- _createCounter: function(uiName, uiValueTemplate, color, protocolName)
+ _onClick: function(event)
{
- var counter = new WebInspector.MemoryStatistics.Counter(protocolName);
- this._counters.push(counter);
- this._counterUI.push(new WebInspector.CounterUI(this, uiName, uiValueTemplate, color, counter));
+ var x = event.x - this._canvasContainer.totalOffsetLeft();
+ var minDistance = Infinity;
+ var bestTime;
+ for (var i = 0; i < this._counterUI.length; ++i) {
+ var counterUI = this._counterUI[i];
+ if (!counterUI.counter.times.length)
+ continue;
+ var index = counterUI._recordIndexAt(x);
+ var distance = Math.abs(x - counterUI.counter.x[index]);
+ if (distance < minDistance) {
+ minDistance = distance;
+ bestTime = counterUI.counter.times[index];
+ }
+ }
+ if (bestTime !== undefined)
+ this._revealRecordAt(bestTime);
},
/**
- * @param {!WebInspector.TimelineModel.Record} record
+ * @param {number} time
*/
- addRecord: function(record)
+ _revealRecordAt: function(time)
{
- /**
- * @param {!WebInspector.TimelineModel.Record} record
- * @this {!WebInspector.CountersGraph}
- */
- function addStatistics(record)
+ var recordToReveal;
+ function findRecordToReveal(record)
{
- var counters = record.counters;
- if (!counters)
- return;
- var time = record.endTime || record.startTime;
- for (var i = 0; i < this._counters.length; ++i)
- this._counters[i].appendSample(time, counters);
+ if (record.startTime <= time && time <= record.endTime) {
+ recordToReveal = record;
+ return true;
+ }
+ // If there is no record containing the time than use the latest one before that time.
+ if (!recordToReveal || record.endTime < time && recordToReveal.endTime < record.endTime)
+ recordToReveal = record;
+ return false;
}
- WebInspector.TimelineModel.forAllRecords([record], null, addStatistics.bind(this));
- this.scheduleRefresh();
+ this._model.forAllRecords(null, findRecordToReveal);
+ this._delegate.selectRecord(recordToReveal);
},
- draw: function()
+ /**
+ * @param {?Event} event
+ */
+ _onMouseOut: function(event)
+ {
+ delete this._markerXPosition;
+ this._clearCurrentValueAndMarker();
+ },
+
+ _clearCurrentValueAndMarker: function()
{
- WebInspector.MemoryStatistics.prototype.draw.call(this);
for (var i = 0; i < this._counterUI.length; i++)
- this._drawGraph(this._counterUI[i]);
+ this._counterUI[i]._clearCurrentValueAndMarker();
+ },
+
+ /**
+ * @param {?Event} event
+ */
+ _onMouseMove: function(event)
+ {
+ var x = event.x - this._canvasContainer.totalOffsetLeft();
+ this._markerXPosition = x;
+ this._refreshCurrentValues();
+ },
+
+ _refreshCurrentValues: function()
+ {
+ if (this._markerXPosition === undefined)
+ return;
+ for (var i = 0; i < this._counterUI.length; ++i)
+ this._counterUI[i].updateCurrentValue(this._markerXPosition);
+ },
+
+ refresh: function()
+ {
+ delete this._refreshTimer;
+ this._timelineGrid.updateDividers(this._calculator);
+ this.draw();
+ this._refreshCurrentValues();
+ },
+
+ refreshRecords: function()
+ {
+ this.reset();
+ var records = this._model.records();
+ for (var i = 0; i < records.length; ++i)
+ this.addRecord(records[i]);
},
/**
- * @param {!WebInspector.CounterUIBase} counterUI
+ * @param {number} originY
+ * @param {number} height
+ */
+ _setVerticalClip: function(originY, height)
+ {
+ this._originY = originY;
+ this._clippedHeight = height;
+ },
+
+ _clear: function()
+ {
+ var ctx = this._canvas.getContext("2d");
+ ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ },
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} record
+ * @param {string=} regex
+ * @param {boolean=} selectRecord
+ */
+ highlightSearchResult: function(record, regex, selectRecord)
+ {
+ },
+
+ /**
+ * @param {?WebInspector.TimelineModel.Record} record
+ */
+ setSelectedRecord: function(record)
+ {
+ },
+
+ /**
+ * @param {!WebInspector.CountersGraph.CounterUI} counterUI
*/
_drawGraph: function(counterUI)
{
@@ -175,7 +292,7 @@ WebInspector.CountersGraph.prototype = {
counterUI.setRange(minValue, maxValue);
- if (!counterUI.visible)
+ if (!counterUI.visible())
return;
var yValues = counterUI.graphYValues;
@@ -208,6 +325,205 @@ WebInspector.CountersGraph.prototype = {
ctx.restore();
},
- __proto__: WebInspector.MemoryStatistics.prototype
+ __proto__: WebInspector.SplitView.prototype
+}
+
+/**
+ * @constructor
+ */
+WebInspector.CountersGraph.Counter = function()
+{
+ this.times = [];
+ this.values = [];
+}
+
+WebInspector.CountersGraph.Counter.prototype = {
+ /**
+ * @param {number} time
+ * @param {number} value
+ */
+ appendSample: function(time, value)
+ {
+ if (this.values.length && this.values.peekLast() === value)
+ return;
+ this.times.push(time);
+ this.values.push(value);
+ },
+
+ reset: function()
+ {
+ this.times = [];
+ this.values = [];
+ },
+
+ /**
+ * @param {!WebInspector.TimelineCalculator} calculator
+ */
+ _calculateVisibleIndexes: function(calculator)
+ {
+ var start = calculator.minimumBoundary();
+ var end = calculator.maximumBoundary();
+
+ // Maximum index of element whose time <= start.
+ this._minimumIndex = Number.constrain(this.times.upperBound(start) - 1, 0, this.times.length - 1);
+
+ // Minimum index of element whose time >= end.
+ this._maximumIndex = Number.constrain(this.times.lowerBound(end), 0, this.times.length - 1);
+
+ // Current window bounds.
+ this._minTime = start;
+ this._maxTime = end;
+ },
+
+ /**
+ * @param {number} width
+ */
+ _calculateXValues: function(width)
+ {
+ if (!this.values.length)
+ return;
+
+ var xFactor = width / (this._maxTime - this._minTime);
+
+ this.x = new Array(this.values.length);
+ this.x[this._minimumIndex] = 0;
+ for (var i = this._minimumIndex + 1; i < this._maximumIndex; i++)
+ this.x[i] = xFactor * (this.times[i] - this._minTime);
+ this.x[this._maximumIndex] = width;
+ }
}
+/**
+ * @constructor
+ * @param {!WebInspector.CountersGraph} memoryCountersPane
+ * @param {string} title
+ * @param {string} currentValueLabel
+ * @param {string} graphColor
+ * @param {!WebInspector.CountersGraph.Counter} counter
+ */
+WebInspector.CountersGraph.CounterUI = function(memoryCountersPane, title, currentValueLabel, graphColor, counter)
+{
+ this._memoryCountersPane = memoryCountersPane;
+ this.counter = counter;
+ var container = memoryCountersPane.sidebarElement().createChild("div", "memory-counter-sidebar-info");
+ var swatchColor = graphColor;
+ this._swatch = new WebInspector.SwatchCheckbox(WebInspector.UIString(title), swatchColor);
+ this._swatch.addEventListener(WebInspector.SwatchCheckbox.Events.Changed, this._toggleCounterGraph.bind(this));
+ container.appendChild(this._swatch.element);
+ this._range = this._swatch.element.createChild("span");
+
+ this._value = memoryCountersPane._currentValuesBar.createChild("span", "memory-counter-value");
+ this._value.style.color = graphColor;
+ this.graphColor = graphColor;
+ this.strokeColor = graphColor;
+ this.graphYValues = [];
+
+ this._currentValueLabel = currentValueLabel;
+ this._marker = memoryCountersPane._canvasContainer.createChild("div", "memory-counter-marker");
+ this._marker.style.backgroundColor = graphColor;
+ this._clearCurrentValueAndMarker();
+}
+
+WebInspector.CountersGraph.CounterUI.prototype = {
+ reset: function()
+ {
+ this._range.textContent = "";
+ },
+
+ /**
+ * @param {number} minValue
+ * @param {number} maxValue
+ */
+ setRange: function(minValue, maxValue)
+ {
+ this._range.textContent = WebInspector.UIString("[%d:%d]", minValue, maxValue);
+ },
+
+ _toggleCounterGraph: function(event)
+ {
+ this._value.classList.toggle("hidden", !this._swatch.checked);
+ this._memoryCountersPane.refresh();
+ },
+
+ /**
+ * @param {number} x
+ * @return {number}
+ */
+ _recordIndexAt: function(x)
+ {
+ return this.counter.x.upperBound(x, null, this.counter._minimumIndex + 1, this.counter._maximumIndex + 1) - 1;
+ },
+
+ /**
+ * @param {number} x
+ */
+ updateCurrentValue: function(x)
+ {
+ if (!this.visible() || !this.counter.values.length)
+ return;
+ var index = this._recordIndexAt(x);
+ this._value.textContent = WebInspector.UIString(this._currentValueLabel, this.counter.values[index]);
+ var y = this.graphYValues[index];
+ this._marker.style.left = x + "px";
+ this._marker.style.top = y + "px";
+ this._marker.classList.remove("hidden");
+ },
+
+ _clearCurrentValueAndMarker: function()
+ {
+ this._value.textContent = "";
+ this._marker.classList.add("hidden");
+ },
+
+ /**
+ * @return {boolean}
+ */
+ visible: function()
+ {
+ return this._swatch.checked;
+ }
+}
+
+
+/**
+ * @constructor
+ * @extends {WebInspector.Object}
+ */
+WebInspector.SwatchCheckbox = function(title, color)
+{
+ this.element = document.createElement("div");
+ this._swatch = this.element.createChild("div", "swatch");
+ this.element.createChild("span", "title").textContent = title;
+ this._color = color;
+ this.checked = true;
+
+ this.element.addEventListener("click", this._toggleCheckbox.bind(this), true);
+}
+
+WebInspector.SwatchCheckbox.Events = {
+ Changed: "Changed"
+}
+
+WebInspector.SwatchCheckbox.prototype = {
+ get checked()
+ {
+ return this._checked;
+ },
+
+ set checked(v)
+ {
+ this._checked = v;
+ if (this._checked)
+ this._swatch.style.backgroundColor = this._color;
+ else
+ this._swatch.style.backgroundColor = "";
+ },
+
+ _toggleCheckbox: function(event)
+ {
+ this.checked = !this.checked;
+ this.dispatchEventToListeners(WebInspector.SwatchCheckbox.Events.Changed);
+ },
+
+ __proto__: WebInspector.Object.prototype
+}
« no previous file with comments | « Source/devtools/devtools.gypi ('k') | Source/devtools/front_end/DOMCountersGraph.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698