DOMCountersGraph.js [plain text]
WebInspector.DOMCountersGraph = function(timelinePanel, model, sidebarWidth)
{
WebInspector.MemoryStatistics.call(this, timelinePanel, model, sidebarWidth);
}
WebInspector.DOMCounterUI = function(memoryCountersPane, title, currentValueLabel, rgb, valueGetter)
{
var swatchColor = "rgb(" + rgb.join(",") + ")";
WebInspector.CounterUIBase.call(this, memoryCountersPane, title, swatchColor, valueGetter)
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.DOMCountersGraph.Counter = function(time, documentCount, nodeCount, listenerCount)
{
WebInspector.MemoryStatistics.Counter.call(this, time);
this.documentCount = documentCount;
this.nodeCount = nodeCount;
this.listenerCount = listenerCount;
}
WebInspector.DOMCounterUI.prototype = {
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);
},
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;
},
__proto__: WebInspector.CounterUIBase.prototype
}
WebInspector.DOMCountersGraph.prototype = {
_createCurrentValuesBar: function()
{
this._currentValuesBar = this._canvasContainer.createChild("div");
this._currentValuesBar.id = "counter-values-bar";
this._canvasContainer.addStyleClass("dom-counters");
},
_createCounterUIList: function()
{
function getDocumentCount(entry)
{
return entry.documentCount;
}
function getNodeCount(entry)
{
return entry.nodeCount;
}
function getListenerCount(entry)
{
return entry.listenerCount;
}
return [
new WebInspector.DOMCounterUI(this, "Document Count", "Documents: %d", [100, 0, 0], getDocumentCount),
new WebInspector.DOMCounterUI(this, "DOM Node Count", "Nodes: %d", [0, 100, 0], getNodeCount),
new WebInspector.DOMCounterUI(this, "Event Listener Count", "Listeners: %d", [0, 0, 100], getListenerCount)
];
},
_canvasHeight: function()
{
return this._canvasContainer.offsetHeight - this._currentValuesBar.offsetHeight;
},
_onRecordAdded: function(event)
{
function addStatistics(record)
{
var counters = record["counters"];
if (!counters)
return;
this._counters.push(new WebInspector.DOMCountersGraph.Counter(
record.endTime || record.startTime,
counters["documents"],
counters["nodes"],
counters["jsEventListeners"]
));
}
WebInspector.TimelinePresentationModel.forAllRecords([event.data], null, addStatistics.bind(this));
},
_draw: function()
{
WebInspector.MemoryStatistics.prototype._draw.call(this);
for (var i = 0; i < this._counterUI.length; i++)
this._drawGraph(this._counterUI[i]);
},
_restoreImageUnderMarker: function(ctx)
{
for (var i = 0; i < this._counterUI.length; i++) {
var counterUI = this._counterUI[i];
if (!counterUI.visible)
continue;
counterUI.restoreImageUnderMarker(ctx);
}
},
_saveImageUnderMarker: function(ctx, x, index)
{
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);
}
},
_drawMarker: function(ctx, x, index)
{
this._saveImageUnderMarker(ctx, x, index);
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];
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2, true);
ctx.lineWidth = 1;
ctx.fillStyle = counterUI.graphColor;
ctx.strokeStyle = counterUI.graphColor;
ctx.fill();
ctx.stroke();
ctx.closePath();
}
},
_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;
if (!this._counters.length)
return;
var maxValue;
var minValue;
for (var i = this._minimumIndex; i <= this._maximumIndex; i++) {
var value = valueGetter(this._counters[i]);
if (minValue === undefined || value < minValue)
minValue = value;
if (maxValue === undefined || value > maxValue)
maxValue = value;
}
counterUI.setRange(minValue, maxValue);
if (!counterUI.visible)
return;
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 - (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 - (valueGetter(this._counters[i]) - minValue) * yFactor);
ctx.lineTo(x, currentY);
yValues[i] = currentY;
}
ctx.lineTo(width, currentY);
ctx.lineWidth = 1;
ctx.strokeStyle = counterUI.graphColor;
ctx.stroke();
ctx.closePath();
},
_discardImageUnderMarker: function()
{
for (var i = 0; i < this._counterUI.length; i++)
this._counterUI[i].discardImageUnderMarker();
},
__proto__: WebInspector.MemoryStatistics.prototype
}