Modified: trunk/Source/WebCore/inspector/front-end/MemoryStatistics.js (108794 => 108795)
--- trunk/Source/WebCore/inspector/front-end/MemoryStatistics.js 2012-02-24 15:28:51 UTC (rev 108794)
+++ trunk/Source/WebCore/inspector/front-end/MemoryStatistics.js 2012-02-24 15:32:45 UTC (rev 108795)
@@ -46,7 +46,9 @@
this._memorySplitView.addEventListener(WebInspector.SplitView.EventTypes.Resized, this._sidebarResized.bind(this));
this._canvasContainer = this._memorySplitView.mainElement;
- this._canvas = this._canvasContainer.createChild("canvas", "fill");
+ this._currentValuesBar = this._canvasContainer.createChild("div");
+ this._currentValuesBar.id = "counter-values-bar";
+ this._canvas = this._canvasContainer.createChild("canvas");
this._canvas.id = "memory-counters-graph";
this._lastMarkerXPosition = 0;
@@ -55,17 +57,145 @@
this._canvasContainer.addEventListener("mouseout", this._onMouseOut.bind(this), true);
// Populate sidebar
- this._counterSidebarElements = [];
- this._documents = this._createCounterSidebarElement(WebInspector.UIString("Document count"), true);
- this._domNodes = this._createCounterSidebarElement(WebInspector.UIString("DOM node count"), true);
- this._listeners = this._createCounterSidebarElement(WebInspector.UIString("Event listener count"), false);
+ this._memorySplitView.sidebarElement.createChild("div", "sidebar-tree sidebar-tree-section").textContent = WebInspector.UIString("COUNTERS");
+ function getDocumentCount(entry)
+ {
+ return entry.documentCount;
+ }
+ function getNodeCount(entry)
+ {
+ return entry.nodeCount;
+ }
+ function getListenerCount(entry)
+ {
+ return entry.listenerCount;
+ }
+ this._counterUI = [
+ new WebInspector.CounterUI(this, "Document Count", "Documents: %d", [100,0,0], getDocumentCount),
+ new WebInspector.CounterUI(this, "DOM Node Count", "Nodes: %d", [0,100,0], getNodeCount),
+ new WebInspector.CounterUI(this, "Event Listener Count", "Listeners: %d", [0,0,100], getListenerCount)
+ ];
- this._savedImageData = [];
- this._graphColors = ["rgba(100,0,0,0.8)", "rgba(0,100,0,0.8)", "rgba(0,0,100,0.8)"];
-
TimelineAgent.setIncludeMemoryDetails(true);
}
+
+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);
+ }
+}
+
+WebInspector.SwatchCheckbox.prototype.__proto__ = WebInspector.Object.prototype;
+
+
+WebInspector.CounterUI = function(memoryCountersPane, title, currentValueLabel, rgb, valueGetter)
+{
+ this._memoryCountersPane = memoryCountersPane;
+ this.valueGetter = valueGetter;
+ var container = memoryCountersPane._memorySplitView.sidebarElement.createChild("div", "memory-counter-sidebar-info");
+ var swatchColor = "rgb(" + rgb.join(",") + ")";
+ 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 = swatchColor;
+ this._currentValueLabel = currentValueLabel;
+
+ this.graphColor = "rgba(" + rgb.join(",") + ",0.8)";
+ this.graphYValues = [];
+}
+
+WebInspector.CounterUI.prototype = {
+ _toggleCounterGraph: function(event)
+ {
+ if (this._swatch.checked)
+ this._value.removeStyleClass("hidden");
+ else
+ this._value.addStyleClass("hidden");
+ this._memoryCountersPane.refresh();
+ },
+
+ setRange: function(minValue, maxValue)
+ {
+ this._range.textContent = WebInspector.UIString("[ %d - %d ]", minValue, maxValue);
+ },
+
+ updateCurrentValue: function(countersEntry)
+ {
+ this._value.textContent = WebInspector.UIString(this._currentValueLabel, this.valueGetter(countersEntry));
+ },
+
+ clearCurrentValueAndMarker: function(ctx)
+ {
+ this._value.textContent = "";
+ this.restoreImageUnderMarker(ctx);
+ },
+
+ get visible()
+ {
+ return this._swatch.checked;
+ },
+
+ saveImageUnderMarker: function(ctx, x, y, radius)
+ {
+ const w = radius + 1;
+ var imageData = ctx.getImageData(x - w, y - w, 2 * w, 2 * w);
+ this._imageUnderMarker = {
+ x: x - w,
+ y: y - w,
+ imageData: imageData };
+ },
+
+ restoreImageUnderMarker: function(ctx)
+ {
+ if (!this.visible)
+ return;
+ if (this._imageUnderMarker)
+ ctx.putImageData(this._imageUnderMarker.imageData, this._imageUnderMarker.x, this._imageUnderMarker.y);
+ this.discardImageUnderMarker();
+ },
+
+ discardImageUnderMarker: function()
+ {
+ delete this._imageUnderMarker;
+ }
+}
+
+
WebInspector.MemoryStatistics.prototype = {
setTopPosition: function(top)
{
@@ -93,48 +223,11 @@
_updateSize: function()
{
- var height = this._canvasContainer.offsetHeight;
+ var height = this._canvasContainer.offsetHeight - this._currentValuesBar.offsetHeight;
this._canvas.width = this._canvasContainer.offsetWidth;
this._canvas.height = height;
- this._updateSidebarSize(height);
},
- _updateSidebarSize: function(height)
- {
- var length = this._counterSidebarElements.length;
- var graphHeight = Math.round(height / length);
- var top = 0;
- for (var i = 0; i < length; i++) {
- var element = this._counterSidebarElements[i];
- element.style.top = top + "px";
- element.style.height = graphHeight + "px";
- top += graphHeight;
- }
- },
-
- _createCounterSidebarElement: function(title, showBottomBorder)
- {
- var container = this._memorySplitView.sidebarElement.createChild("div", "memory-counter-sidebar-info");
- container.createChild("div", "title").textContent = title;
-
- var currentValue = container.createChild("div", "counter-value");
- currentValue.createChild("span").textContent = WebInspector.UIString("Current: ");
- container._value = currentValue.createChild("span");
-
- var minValue = container.createChild("div", "counter-value");
- minValue.createChild("span").textContent = WebInspector.UIString("Min: ");
- container._minValue = minValue.createChild("span");
-
- var maxValue = container.createChild("div", "counter-value");
- maxValue.createChild("span").textContent = WebInspector.UIString("Max: ");
- container._maxValue = maxValue.createChild("span");
-
- if (showBottomBorder)
- container.addStyleClass("bottom-border-visible");
- this._counterSidebarElements.push(container);
- return container;
- },
-
addTimlineEvent: function(event)
{
var counters = event.data["counters"];
@@ -151,30 +244,10 @@
this._calculateVisibleIndexes();
this._calculateXValues();
this._clear();
- var graphHeight = Math.round(this._canvas.height / 3);
- function getDocumentCount(entry)
- {
- return entry.documentCount;
- }
- this._setVerticalClip(0 * graphHeight + 2, graphHeight - 4);
- this._drawPolyline(getDocumentCount, this._graphColors[0], this._documents);
- this._drawBottomBound("rgba(20,20,20,0.8)");
-
- function getNodeCount(entry)
- {
- return entry.nodeCount;
- }
- this._setVerticalClip(1 * graphHeight + 2, graphHeight - 4);
- this._drawPolyline(getNodeCount, this._graphColors[1], this._domNodes);
- this._drawBottomBound("rgba(20,20,20,0.8)");
-
- function getListenerCount(entry)
- {
- return entry.listenerCount;
- }
- this._setVerticalClip(2 * graphHeight + 2, graphHeight - 4);
- this._drawPolyline(getListenerCount, this._graphColors[2], this._listeners);
+ this._setVerticalClip(10, this._canvas.height - 20);
+ for (var i = 0; i < this._counterUI.length; i++)
+ this._drawGraph(this._counterUI[i]);
},
_calculateVisibleIndexes: function()
@@ -207,12 +280,11 @@
_onMouseOut: function(event)
{
- this._clearMarkers();
delete this._markerXPosition;
- this._documents._value.textContent = "";
- this._domNodes._value.textContent = "";
- this._listeners._value.textContent = "";
+ var ctx = this._canvas.getContext("2d");
+ for (var i = 0; i < this._counterUI.length; i++)
+ this._counterUI[i].clearCurrentValueAndMarker(ctx);
},
_onMouseOver: function(event)
@@ -235,9 +307,8 @@
return;
var i = this._recordIndexAt(this._markerXPosition);
- this._documents._value.textContent = this._counters[i].documentCount;
- this._domNodes._value.textContent = this._counters[i].nodeCount;
- this._listeners._value.textContent = this._counters[i].listenerCount;
+ for (var j = 0; j < this._counterUI.length; j++)
+ this._counterUI[j].updateCurrentValue(this._counters[i]);
this._highlightCurrentPositionOnGraphs(this._markerXPosition, i);
},
@@ -257,43 +328,38 @@
_highlightCurrentPositionOnGraphs: function(x, index)
{
var ctx = this._canvas.getContext("2d");
- this._clearMarkers();
- var yValues = this._counters[index].yValues;
- for (var i = 0; i < yValues.length; i++) {
- var y = yValues[i];
+ for (var i = 0; i < this._counterUI.length; i++) {
+ var counterUI = this._counterUI[i];
+ if (!counterUI.visible)
+ continue;
+ counterUI.restoreImageUnderMarker(ctx);
+ }
+
+ const radius = 2;
+ for (var i = 0; i < this._counterUI.length; i++) {
+ var counterUI = this._counterUI[i];
+ if (!counterUI.visible)
+ continue;
+ var y = counterUI.graphYValues[index];
+ counterUI.saveImageUnderMarker(ctx, x, y, radius);
+ }
+
+ for (var i = 0; i < this._counterUI.length; i++) {
+ var counterUI = this._counterUI[i];
+ if (!counterUI.visible)
+ continue;
+ var y = counterUI.graphYValues[index];
ctx.beginPath();
- const radius = 2;
- this._saveImageUnderMarker(ctx, x, y, radius);
ctx.arc(x, y, radius, 0, Math.PI*2, true);
ctx.lineWidth = 1;
- ctx.fillStyle = this._graphColors[i];
- ctx.strokeStyle = this._graphColors[i];
+ ctx.fillStyle = counterUI.graphColor;
+ ctx.strokeStyle = counterUI.graphColor;
ctx.fill();
ctx.stroke();
ctx.closePath();
}
},
- _clearMarkers: function()
- {
- var ctx = this._canvas.getContext("2d");
- for (var i = 0; i < this._savedImageData.length; i++) {
- var entry = this._savedImageData[i];
- ctx.putImageData(entry.imageData, entry.x, entry.y);
- }
- this._savedImageData = [];
- },
-
- _saveImageUnderMarker: function(ctx, x, y, radius)
- {
- const w = radius + 1;
- var imageData = ctx.getImageData(x - w, y - w, 2 * w, 2 * w);
- this._savedImageData.push({
- x: x - w,
- y: y - w,
- imageData: imageData });
- },
-
visible: function()
{
return this._memorySplitView.isShowing();
@@ -339,23 +405,15 @@
this._counters[this._maximumIndex].x = width;
},
- _drawPolyline: function(valueGetter, color, section)
+ _drawGraph: function(counterUI)
{
var canvas = this._canvas;
var ctx = canvas.getContext("2d");
var width = canvas.width;
var height = this._clippedHeight;
var originY = this._originY;
+ var valueGetter = counterUI.valueGetter;
- // Draw originalValue level
- ctx.beginPath();
- ctx.moveTo(0, originY + height / 2 + 0.5);
- ctx.lineTo(width, originY + height / 2 + 0.5);
- ctx.lineWidth = 0.1;
- ctx.strokeStyle = "rgb(100, 100, 100)";
- ctx.stroke();
- ctx.closePath();
-
if (!this._counters.length)
return;
@@ -369,54 +427,40 @@
maxValue = value;
}
- section._minValue.textContent = minValue;
- section._maxValue.textContent = maxValue;
+ counterUI.setRange(minValue, maxValue);
- var originalValue = valueGetter(this._counters[this._minimumIndex]);
+ if (!counterUI.visible)
+ return;
- var maxYRange = Math.max(maxValue - originalValue, originalValue - minValue);
- var yFactor = maxYRange ? height / (2 * maxYRange) : 0.5;
+ var yValues = counterUI.graphYValues;
+ yValues.length = this._counters.length;
+ var maxYRange = maxValue - minValue;
+ var yFactor = maxYRange ? height / (maxYRange) : 1;
+
ctx.beginPath();
- var currentY = originY + height / 2;
+ var currentY = originY + (height - (valueGetter(this._counters[this._minimumIndex])- minValue) * yFactor);
ctx.moveTo(0, currentY);
for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
var x = this._counters[i].x;
ctx.lineTo(x, currentY);
- currentY = originY + (height / 2 - (valueGetter(this._counters[i])- originalValue) * yFactor);
+ currentY = originY + (height - (valueGetter(this._counters[i])- minValue) * yFactor);
ctx.lineTo(x, currentY);
- this._counters[i].yValues.push(currentY);
+ yValues[i] = currentY;
}
ctx.lineTo(width, currentY);
ctx.lineWidth = 1;
- ctx.strokeStyle = color;
+ ctx.strokeStyle = counterUI.graphColor;
ctx.stroke();
ctx.closePath();
},
- _drawBottomBound: function(color)
- {
- var canvas = this._canvas;
- var width = canvas.width;
- var y = this._originY + this._clippedHeight + 1.5;
-
- var ctx = canvas.getContext("2d");
- ctx.beginPath();
- ctx.moveTo(0, y);
- ctx.lineTo(width, y);
- ctx.lineWidth = 0.5;
- ctx.strokeStyle = color;
- ctx.stroke();
- ctx.closePath();
- },
-
_clear: function() {
var ctx = this._canvas.getContext("2d");
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
- for (var i = this._minimumIndex; i <= this._maximumIndex; i++)
- this._counters[i].yValues = [];
- this._savedImageData = [];
+ for (var i = 0; i < this._counterUI.length; i++)
+ this._counterUI[i].discardImageUnderMarker();
}
}