| Index: chrome_frame/tools/test/reference_build/chrome/resources/inspector/SummaryBar.js
|
| ===================================================================
|
| --- chrome_frame/tools/test/reference_build/chrome/resources/inspector/SummaryBar.js (revision 0)
|
| +++ chrome_frame/tools/test/reference_build/chrome/resources/inspector/SummaryBar.js (revision 0)
|
| @@ -0,0 +1,364 @@
|
| +/*
|
| + * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
|
| + * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
|
| + *
|
| + * Redistribution and use in source and binary forms, with or without
|
| + * modification, are permitted provided that the following conditions
|
| + * are met:
|
| + *
|
| + * 1. Redistributions of source code must retain the above copyright
|
| + * notice, this list of conditions and the following disclaimer.
|
| + * 2. Redistributions in binary form must reproduce the above copyright
|
| + * notice, this list of conditions and the following disclaimer in the
|
| + * documentation and/or other materials provided with the distribution.
|
| + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
|
| + * its contributors may be used to endorse or promote products derived
|
| + * from this software without specific prior written permission.
|
| + *
|
| + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
|
| + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
| + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
| + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
|
| + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
| + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
| + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
| + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
| + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
| + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
| + */
|
| +
|
| +WebInspector.SummaryBar = function(categories)
|
| +{
|
| + this.categories = categories;
|
| +
|
| + this.element = document.createElement("div");
|
| + this.element.className = "summary-bar";
|
| +
|
| + this.graphElement = document.createElement("canvas");
|
| + this.graphElement.setAttribute("width", "450");
|
| + this.graphElement.setAttribute("height", "38");
|
| + this.graphElement.className = "summary-graph";
|
| + this.element.appendChild(this.graphElement);
|
| +
|
| + this.legendElement = document.createElement("div");
|
| + this.legendElement.className = "summary-graph-legend";
|
| + this.element.appendChild(this.legendElement);
|
| +}
|
| +
|
| +WebInspector.SummaryBar.prototype = {
|
| +
|
| + get calculator() {
|
| + return this._calculator;
|
| + },
|
| +
|
| + set calculator(x) {
|
| + this._calculator = x;
|
| + },
|
| +
|
| + reset: function()
|
| + {
|
| + this.legendElement.removeChildren();
|
| + this._drawSummaryGraph();
|
| + },
|
| +
|
| + update: function(data)
|
| + {
|
| + var graphInfo = this.calculator.computeSummaryValues(data);
|
| +
|
| + var fillSegments = [];
|
| +
|
| + this.legendElement.removeChildren();
|
| +
|
| + for (var category in this.categories) {
|
| + var size = graphInfo.categoryValues[category];
|
| + if (!size)
|
| + continue;
|
| +
|
| + var color = this.categories[category].color;
|
| + var colorString = "rgb(" + color.r + ", " + color.g + ", " + color.b + ")";
|
| +
|
| + var fillSegment = {color: colorString, value: size};
|
| + fillSegments.push(fillSegment);
|
| +
|
| + var legendLabel = this._makeLegendElement(this.categories[category].title, this.calculator.formatValue(size), colorString);
|
| + this.legendElement.appendChild(legendLabel);
|
| + }
|
| +
|
| + if (graphInfo.total) {
|
| + var totalLegendLabel = this._makeLegendElement(WebInspector.UIString("Total"), this.calculator.formatValue(graphInfo.total));
|
| + totalLegendLabel.addStyleClass("total");
|
| + this.legendElement.appendChild(totalLegendLabel);
|
| + }
|
| +
|
| + this._drawSummaryGraph(fillSegments);
|
| + },
|
| +
|
| + _drawSwatch: function(canvas, color)
|
| + {
|
| + var ctx = canvas.getContext("2d");
|
| +
|
| + function drawSwatchSquare() {
|
| + ctx.fillStyle = color;
|
| + ctx.fillRect(0, 0, 13, 13);
|
| +
|
| + var gradient = ctx.createLinearGradient(0, 0, 13, 13);
|
| + gradient.addColorStop(0.0, "rgba(255, 255, 255, 0.2)");
|
| + gradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
|
| +
|
| + ctx.fillStyle = gradient;
|
| + ctx.fillRect(0, 0, 13, 13);
|
| +
|
| + gradient = ctx.createLinearGradient(13, 13, 0, 0);
|
| + gradient.addColorStop(0.0, "rgba(0, 0, 0, 0.2)");
|
| + gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.0)");
|
| +
|
| + ctx.fillStyle = gradient;
|
| + ctx.fillRect(0, 0, 13, 13);
|
| +
|
| + ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
|
| + ctx.strokeRect(0.5, 0.5, 12, 12);
|
| + }
|
| +
|
| + ctx.clearRect(0, 0, 13, 24);
|
| +
|
| + drawSwatchSquare();
|
| +
|
| + ctx.save();
|
| +
|
| + ctx.translate(0, 25);
|
| + ctx.scale(1, -1);
|
| +
|
| + drawSwatchSquare();
|
| +
|
| + ctx.restore();
|
| +
|
| + this._fadeOutRect(ctx, 0, 13, 13, 13, 0.5, 0.0);
|
| + },
|
| +
|
| + _drawSummaryGraph: function(segments)
|
| + {
|
| + if (!segments || !segments.length) {
|
| + segments = [{color: "white", value: 1}];
|
| + this._showingEmptySummaryGraph = true;
|
| + } else
|
| + delete this._showingEmptySummaryGraph;
|
| +
|
| + // Calculate the total of all segments.
|
| + var total = 0;
|
| + for (var i = 0; i < segments.length; ++i)
|
| + total += segments[i].value;
|
| +
|
| + // Calculate the percentage of each segment, rounded to the nearest percent.
|
| + var percents = segments.map(function(s) { return Math.max(Math.round(100 * s.value / total), 1) });
|
| +
|
| + // Calculate the total percentage.
|
| + var percentTotal = 0;
|
| + for (var i = 0; i < percents.length; ++i)
|
| + percentTotal += percents[i];
|
| +
|
| + // Make sure our percentage total is not greater-than 100, it can be greater
|
| + // if we rounded up for a few segments.
|
| + while (percentTotal > 100) {
|
| + for (var i = 0; i < percents.length && percentTotal > 100; ++i) {
|
| + if (percents[i] > 1) {
|
| + --percents[i];
|
| + --percentTotal;
|
| + }
|
| + }
|
| + }
|
| +
|
| + // Make sure our percentage total is not less-than 100, it can be less
|
| + // if we rounded down for a few segments.
|
| + while (percentTotal < 100) {
|
| + for (var i = 0; i < percents.length && percentTotal < 100; ++i) {
|
| + ++percents[i];
|
| + ++percentTotal;
|
| + }
|
| + }
|
| +
|
| + var ctx = this.graphElement.getContext("2d");
|
| +
|
| + var x = 0;
|
| + var y = 0;
|
| + var w = 450;
|
| + var h = 19;
|
| + var r = (h / 2);
|
| +
|
| + function drawPillShadow()
|
| + {
|
| + // This draws a line with a shadow that is offset away from the line. The line is stroked
|
| + // twice with different X shadow offsets to give more feathered edges. Later we erase the
|
| + // line with destination-out 100% transparent black, leaving only the shadow. This only
|
| + // works if nothing has been drawn into the canvas yet.
|
| +
|
| + ctx.beginPath();
|
| + ctx.moveTo(x + 4, y + h - 3 - 0.5);
|
| + ctx.lineTo(x + w - 4, y + h - 3 - 0.5);
|
| + ctx.closePath();
|
| +
|
| + ctx.save();
|
| +
|
| + ctx.shadowBlur = 2;
|
| + ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
|
| + ctx.shadowOffsetX = 3;
|
| + ctx.shadowOffsetY = 5;
|
| +
|
| + ctx.strokeStyle = "white";
|
| + ctx.lineWidth = 1;
|
| +
|
| + ctx.stroke();
|
| +
|
| + ctx.shadowOffsetX = -3;
|
| +
|
| + ctx.stroke();
|
| +
|
| + ctx.restore();
|
| +
|
| + ctx.save();
|
| +
|
| + ctx.globalCompositeOperation = "destination-out";
|
| + ctx.strokeStyle = "rgba(0, 0, 0, 1)";
|
| + ctx.lineWidth = 1;
|
| +
|
| + ctx.stroke();
|
| +
|
| + ctx.restore();
|
| + }
|
| +
|
| + function drawPill()
|
| + {
|
| + // Make a rounded rect path.
|
| + ctx.beginPath();
|
| + ctx.moveTo(x, y + r);
|
| + ctx.lineTo(x, y + h - r);
|
| + ctx.quadraticCurveTo(x, y + h, x + r, y + h);
|
| + ctx.lineTo(x + w - r, y + h);
|
| + ctx.quadraticCurveTo(x + w, y + h, x + w, y + h - r);
|
| + ctx.lineTo(x + w, y + r);
|
| + ctx.quadraticCurveTo(x + w, y, x + w - r, y);
|
| + ctx.lineTo(x + r, y);
|
| + ctx.quadraticCurveTo(x, y, x, y + r);
|
| + ctx.closePath();
|
| +
|
| + // Clip to the rounded rect path.
|
| + ctx.save();
|
| + ctx.clip();
|
| +
|
| + // Fill the segments with the associated color.
|
| + var previousSegmentsWidth = 0;
|
| + for (var i = 0; i < segments.length; ++i) {
|
| + var segmentWidth = Math.round(w * percents[i] / 100);
|
| + ctx.fillStyle = segments[i].color;
|
| + ctx.fillRect(x + previousSegmentsWidth, y, segmentWidth, h);
|
| + previousSegmentsWidth += segmentWidth;
|
| + }
|
| +
|
| + // Draw the segment divider lines.
|
| + ctx.lineWidth = 1;
|
| + for (var i = 1; i < 20; ++i) {
|
| + ctx.beginPath();
|
| + ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
|
| + ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
|
| + ctx.closePath();
|
| +
|
| + ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
|
| + ctx.stroke();
|
| +
|
| + ctx.beginPath();
|
| + ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
|
| + ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
|
| + ctx.closePath();
|
| +
|
| + ctx.strokeStyle = "rgba(255, 255, 255, 0.2)";
|
| + ctx.stroke();
|
| + }
|
| +
|
| + // Draw the pill shading.
|
| + var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5));
|
| + lightGradient.addColorStop(0.0, "rgba(220, 220, 220, 0.6)");
|
| + lightGradient.addColorStop(0.4, "rgba(220, 220, 220, 0.2)");
|
| + lightGradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
|
| +
|
| + var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h);
|
| + darkGradient.addColorStop(0.0, "rgba(0, 0, 0, 0.0)");
|
| + darkGradient.addColorStop(0.8, "rgba(0, 0, 0, 0.2)");
|
| + darkGradient.addColorStop(1.0, "rgba(0, 0, 0, 0.5)");
|
| +
|
| + ctx.fillStyle = darkGradient;
|
| + ctx.fillRect(x, y, w, h);
|
| +
|
| + ctx.fillStyle = lightGradient;
|
| + ctx.fillRect(x, y, w, h);
|
| +
|
| + ctx.restore();
|
| + }
|
| +
|
| + ctx.clearRect(x, y, w, (h * 2));
|
| +
|
| + drawPillShadow();
|
| + drawPill();
|
| +
|
| + ctx.save();
|
| +
|
| + ctx.translate(0, (h * 2) + 1);
|
| + ctx.scale(1, -1);
|
| +
|
| + drawPill();
|
| +
|
| + ctx.restore();
|
| +
|
| + this._fadeOutRect(ctx, x, y + h + 1, w, h, 0.5, 0.0);
|
| + },
|
| +
|
| + _fadeOutRect: function(ctx, x, y, w, h, a1, a2)
|
| + {
|
| + ctx.save();
|
| +
|
| + var gradient = ctx.createLinearGradient(x, y, x, y + h);
|
| + gradient.addColorStop(0.0, "rgba(0, 0, 0, " + (1.0 - a1) + ")");
|
| + gradient.addColorStop(0.8, "rgba(0, 0, 0, " + (1.0 - a2) + ")");
|
| + gradient.addColorStop(1.0, "rgba(0, 0, 0, 1.0)");
|
| +
|
| + ctx.globalCompositeOperation = "destination-out";
|
| +
|
| + ctx.fillStyle = gradient;
|
| + ctx.fillRect(x, y, w, h);
|
| +
|
| + ctx.restore();
|
| + },
|
| +
|
| + _makeLegendElement: function(label, value, color)
|
| + {
|
| + var legendElement = document.createElement("label");
|
| + legendElement.className = "summary-graph-legend-item";
|
| +
|
| + if (color) {
|
| + var swatch = document.createElement("canvas");
|
| + swatch.className = "summary-graph-legend-swatch";
|
| + swatch.setAttribute("width", "13");
|
| + swatch.setAttribute("height", "24");
|
| +
|
| + legendElement.appendChild(swatch);
|
| +
|
| + this._drawSwatch(swatch, color);
|
| + }
|
| +
|
| + var labelElement = document.createElement("div");
|
| + labelElement.className = "summary-graph-legend-label";
|
| + legendElement.appendChild(labelElement);
|
| +
|
| + var headerElement = document.createElement("div");
|
| + headerElement.className = "summary-graph-legend-header";
|
| + headerElement.textContent = label;
|
| + labelElement.appendChild(headerElement);
|
| +
|
| + var valueElement = document.createElement("div");
|
| + valueElement.className = "summary-graph-legend-value";
|
| + valueElement.textContent = value;
|
| + labelElement.appendChild(valueElement);
|
| +
|
| + return legendElement;
|
| + }
|
| +}
|
| +
|
| +WebInspector.SummaryBar.prototype.__proto__ = WebInspector.Object.prototype;
|
|
|