SummaryBar.js revision 231d4e3152a9c27a73b6ac7badbe6be673aa3ddf
1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block/*
2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2008, 2009 Anthony Ricaud <rik@webkit.org>
4231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Redistribution and use in source and binary forms, with or without
6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * modification, are permitted provided that the following conditions
7231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * are met:
8231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
9231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 1.  Redistributions of source code must retain the above copyright
10231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     notice, this list of conditions and the following disclaimer.
11231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 2.  Redistributions in binary form must reproduce the above copyright
12231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     notice, this list of conditions and the following disclaimer in the
13231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     documentation and/or other materials provided with the distribution.
14231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     its contributors may be used to endorse or promote products derived
16231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *     from this software without specific prior written permission.
17231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block *
18231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */
29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockWebInspector.SummaryBar = function(categories)
31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{
32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.categories = categories;
33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.element = document.createElement("div");
35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.element.className = "summary-bar";
36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.graphElement = document.createElement("canvas");
38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.graphElement.setAttribute("width", "450");
39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.graphElement.setAttribute("height", "38");
40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.graphElement.className = "summary-graph";
41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.element.appendChild(this.graphElement);
42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.legendElement = document.createElement("div");
44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.legendElement.className = "summary-graph-legend";
45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    this.element.appendChild(this.legendElement);
46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockWebInspector.SummaryBar.prototype = {
49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    get calculator() {
51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return this._calculator;
52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    set calculator(x) {
55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this._calculator = x;
56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    reset: function()
59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
60231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this.legendElement.removeChildren();
61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this._drawSummaryGraph();
62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
64231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    update: function(data)
65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
66231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var graphInfo = this.calculator.computeSummaryValues(data);
67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
68231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var fillSegments = [];
69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this.legendElement.removeChildren();
71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (var category in this.categories) {
73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var size = graphInfo.categoryValues[category];
74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            if (!size)
75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                continue;
76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
77231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var color = this.categories[category].color;
78231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var colorString = "rgb(" + color.r + ", " + color.g + ", " + color.b + ")";
79231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var fillSegment = {color: colorString, value: size};
81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            fillSegments.push(fillSegment);
82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var legendLabel = this._makeLegendElement(this.categories[category].title, this.calculator.formatValue(size), colorString);
84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            this.legendElement.appendChild(legendLabel);
85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
86231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (graphInfo.total) {
88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var totalLegendLabel = this._makeLegendElement(WebInspector.UIString("Total"), this.calculator.formatValue(graphInfo.total));
89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            totalLegendLabel.addStyleClass("total");
90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            this.legendElement.appendChild(totalLegendLabel);
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this._drawSummaryGraph(fillSegments);
94231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
95231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    _drawSwatch: function(canvas, color)
97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var ctx = canvas.getContext("2d");
99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        function drawSwatchSquare() {
101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = color;
102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(0, 0, 13, 13);
103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var gradient = ctx.createLinearGradient(0, 0, 13, 13);
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient.addColorStop(0.0, "rgba(255, 255, 255, 0.2)");
106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = gradient;
109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(0, 0, 13, 13);
110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient = ctx.createLinearGradient(13, 13, 0, 0);
112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient.addColorStop(0.0, "rgba(0, 0, 0, 0.2)");
113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.0)");
114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = gradient;
116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(0, 0, 13, 13);
117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.strokeRect(0.5, 0.5, 12, 12);
120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.clearRect(0, 0, 13, 24);
123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawSwatchSquare();
125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.save();
127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.translate(0, 25);
129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.scale(1, -1);
130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawSwatchSquare();
132231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
133231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.restore();
134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this._fadeOutRect(ctx, 0, 13, 13, 13, 0.5, 0.0);
136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    _drawSummaryGraph: function(segments)
139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!segments || !segments.length) {
141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            segments = [{color: "white", value: 1}];
142231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            this._showingEmptySummaryGraph = true;
143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else
144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            delete this._showingEmptySummaryGraph;
145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Calculate the total of all segments.
147231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var total = 0;
148231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (var i = 0; i < segments.length; ++i)
149231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            total += segments[i].value;
150231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
151231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Calculate the percentage of each segment, rounded to the nearest percent.
152231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var percents = segments.map(function(s) { return Math.max(Math.round(100 * s.value / total), 1) });
153231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Calculate the total percentage.
155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var percentTotal = 0;
156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (var i = 0; i < percents.length; ++i)
157231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            percentTotal += percents[i];
158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
159231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Make sure our percentage total is not greater-than 100, it can be greater
160231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // if we rounded up for a few segments.
161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        while (percentTotal > 100) {
162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (var i = 0; i < percents.length && percentTotal > 100; ++i) {
163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (percents[i] > 1) {
164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    --percents[i];
165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    --percentTotal;
166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                }
167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
169231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Make sure our percentage total is not less-than 100, it can be less
171231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // if we rounded down for a few segments.
172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        while (percentTotal < 100) {
173231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (var i = 0; i < percents.length && percentTotal < 100; ++i) {
174231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ++percents[i];
175231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ++percentTotal;
176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var ctx = this.graphElement.getContext("2d");
180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var x = 0;
182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var y = 0;
183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var w = 450;
184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var h = 19;
185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var r = (h / 2);
186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        function drawPillShadow()
188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        {
189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // This draws a line with a shadow that is offset away from the line. The line is stroked
190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // twice with different X shadow offsets to give more feathered edges. Later we erase the
191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // line with destination-out 100% transparent black, leaving only the shadow. This only
192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // works if nothing has been drawn into the canvas yet.
193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.beginPath();
195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.moveTo(x + 4, y + h - 3 - 0.5);
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x + w - 4, y + h - 3 - 0.5);
197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.closePath();
198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.save();
200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowBlur = 2;
202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowOffsetX = 3;
204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowOffsetY = 5;
205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.strokeStyle = "white";
207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineWidth = 1;
208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.stroke();
210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
211231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowOffsetX = -3;
212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.stroke();
214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.restore();
216231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
217231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.save();
218231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
219231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.globalCompositeOperation = "destination-out";
220231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.strokeStyle = "rgba(0, 0, 0, 1)";
221231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineWidth = 1;
222231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
223231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.stroke();
224231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
225231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.restore();
226231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
227231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
228231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        function drawPill()
229231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        {
230231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Make a rounded rect path.
231231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.beginPath();
232231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.moveTo(x, y + r);
233231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x, y + h - r);
234231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.quadraticCurveTo(x, y + h, x + r, y + h);
235231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x + w - r, y + h);
236231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.quadraticCurveTo(x + w, y + h, x + w, y + h - r);
237231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x + w, y + r);
238231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.quadraticCurveTo(x + w, y, x + w - r, y);
239231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x + r, y);
240231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.quadraticCurveTo(x, y, x, y + r);
241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.closePath();
242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
243231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Clip to the rounded rect path.
244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.save();
245231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.clip();
246231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
247231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Fill the segments with the associated color.
248231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var previousSegmentsWidth = 0;
249231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (var i = 0; i < segments.length; ++i) {
250231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                var segmentWidth = Math.round(w * percents[i] / 100);
251231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.fillStyle = segments[i].color;
252231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.fillRect(x + previousSegmentsWidth, y, segmentWidth, h);
253231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                previousSegmentsWidth += segmentWidth;
254231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
255231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Draw the segment divider lines.
257231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineWidth = 1;
258231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (var i = 1; i < 20; ++i) {
259231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.beginPath();
260231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
262231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.closePath();
263231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
265231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.stroke();
266231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
267231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.beginPath();
268231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
269231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
270231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.closePath();
271231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
272231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.strokeStyle = "rgba(255, 255, 255, 0.2)";
273231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.stroke();
274231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
275231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
276231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Draw the pill shading.
277231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5));
278231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lightGradient.addColorStop(0.0, "rgba(220, 220, 220, 0.6)");
279231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lightGradient.addColorStop(0.4, "rgba(220, 220, 220, 0.2)");
280231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lightGradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
281231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h);
283231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            darkGradient.addColorStop(0.0, "rgba(0, 0, 0, 0.0)");
284231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            darkGradient.addColorStop(0.8, "rgba(0, 0, 0, 0.2)");
285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            darkGradient.addColorStop(1.0, "rgba(0, 0, 0, 0.5)");
286231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = darkGradient;
288231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(x, y, w, h);
289231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
290231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = lightGradient;
291231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(x, y, w, h);
292231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
293231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.restore();
294231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
295231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
296231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.clearRect(x, y, w, (h * 2));
297231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
298231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawPillShadow();
299231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawPill();
300231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
301231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.save();
302231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
303231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.translate(0, (h * 2) + 1);
304231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.scale(1, -1);
305231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawPill();
307231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
308231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.restore();
309231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
310231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this._fadeOutRect(ctx, x, y + h + 1, w, h, 0.5, 0.0);
311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
312231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
313231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    _fadeOutRect: function(ctx, x, y, w, h, a1, a2)
314231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
315231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.save();
316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
317231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var gradient = ctx.createLinearGradient(x, y, x, y + h);
318231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        gradient.addColorStop(0.0, "rgba(0, 0, 0, " + (1.0 - a1) + ")");
319231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        gradient.addColorStop(0.8, "rgba(0, 0, 0, " + (1.0 - a2) + ")");
320231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        gradient.addColorStop(1.0, "rgba(0, 0, 0, 1.0)");
321231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
322231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.globalCompositeOperation = "destination-out";
323231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
324231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.fillStyle = gradient;
325231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.fillRect(x, y, w, h);
326231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
327231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.restore();
328231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
329231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
330231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    _makeLegendElement: function(label, value, color)
331231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
332231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var legendElement = document.createElement("label");
333231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        legendElement.className = "summary-graph-legend-item";
334231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (color) {
336231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var swatch = document.createElement("canvas");
337231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            swatch.className = "summary-graph-legend-swatch";
338231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            swatch.setAttribute("width", "13");
339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            swatch.setAttribute("height", "24");
340231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
341231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            legendElement.appendChild(swatch);
342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            this._drawSwatch(swatch, color);
344231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
345231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
346231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var labelElement = document.createElement("div");
347231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        labelElement.className = "summary-graph-legend-label";
348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        legendElement.appendChild(labelElement);
349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
350231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var headerElement = document.createElement("div");
351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        headerElement.className = "summary-graph-legend-header";
352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        headerElement.textContent = label;
353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        labelElement.appendChild(headerElement);
354231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var valueElement = document.createElement("div");
356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        valueElement.className = "summary-graph-legend-value";
357231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        valueElement.textContent = value;
358231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        labelElement.appendChild(valueElement);
359231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
360231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return legendElement;
361231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
362231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
363231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
364231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockWebInspector.SummaryBar.prototype.__proto__ = WebInspector.Object.prototype;
365