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
77cac0f67c402d107cdb10971b95719e2ff9c7c76bSteve Block            var colorString = this.categories[category].color;
78231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
79231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var fillSegment = {color: colorString, value: size};
80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            fillSegments.push(fillSegment);
81231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
82231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var legendLabel = this._makeLegendElement(this.categories[category].title, this.calculator.formatValue(size), colorString);
83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            this.legendElement.appendChild(legendLabel);
84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
86231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (graphInfo.total) {
87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var totalLegendLabel = this._makeLegendElement(WebInspector.UIString("Total"), this.calculator.formatValue(graphInfo.total));
88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            totalLegendLabel.addStyleClass("total");
89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            this.legendElement.appendChild(totalLegendLabel);
90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this._drawSummaryGraph(fillSegments);
93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
94231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
95231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    _drawSwatch: function(canvas, color)
96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var ctx = canvas.getContext("2d");
98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        function drawSwatchSquare() {
100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = color;
101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(0, 0, 13, 13);
102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var gradient = ctx.createLinearGradient(0, 0, 13, 13);
104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient.addColorStop(0.0, "rgba(255, 255, 255, 0.2)");
105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = gradient;
108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(0, 0, 13, 13);
109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
110231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient = ctx.createLinearGradient(13, 13, 0, 0);
111231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient.addColorStop(0.0, "rgba(0, 0, 0, 0.2)");
112231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            gradient.addColorStop(1.0, "rgba(0, 0, 0, 0.0)");
113231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
114231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = gradient;
115231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(0, 0, 13, 13);
116231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
117231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.strokeStyle = "rgba(0, 0, 0, 0.6)";
118231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.strokeRect(0.5, 0.5, 12, 12);
119231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
120231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
121231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.clearRect(0, 0, 13, 24);
122231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
123231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawSwatchSquare();
124231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
125231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.save();
126231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
127231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.translate(0, 25);
128231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.scale(1, -1);
129231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
130231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawSwatchSquare();
131231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
132231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.restore();
133231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
134231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this._fadeOutRect(ctx, 0, 13, 13, 13, 0.5, 0.0);
135231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
136231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
137231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    _drawSummaryGraph: function(segments)
138231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
139231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (!segments || !segments.length) {
140231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            segments = [{color: "white", value: 1}];
141231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            this._showingEmptySummaryGraph = true;
142231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        } else
143231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            delete this._showingEmptySummaryGraph;
144231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
145231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Calculate the total of all segments.
146231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var total = 0;
147231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (var i = 0; i < segments.length; ++i)
148231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            total += segments[i].value;
149231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
150231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Calculate the percentage of each segment, rounded to the nearest percent.
151231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var percents = segments.map(function(s) { return Math.max(Math.round(100 * s.value / total), 1) });
152231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
153231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Calculate the total percentage.
154231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var percentTotal = 0;
155231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        for (var i = 0; i < percents.length; ++i)
156231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            percentTotal += percents[i];
157231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
158231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Make sure our percentage total is not greater-than 100, it can be greater
159231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // if we rounded up for a few segments.
160231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        while (percentTotal > 100) {
161231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (var i = 0; i < percents.length && percentTotal > 100; ++i) {
162231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                if (percents[i] > 1) {
163231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    --percents[i];
164231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                    --percentTotal;
165231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                }
166231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
167231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
168231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
169231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // Make sure our percentage total is not less-than 100, it can be less
170231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        // if we rounded down for a few segments.
171231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        while (percentTotal < 100) {
172231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (var i = 0; i < percents.length && percentTotal < 100; ++i) {
173231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ++percents[i];
174231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ++percentTotal;
175231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
176231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
177231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
178231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var ctx = this.graphElement.getContext("2d");
179231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
180231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var x = 0;
181231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var y = 0;
182231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var w = 450;
183231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var h = 19;
184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var r = (h / 2);
185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        function drawPillShadow()
187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        {
188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // This draws a line with a shadow that is offset away from the line. The line is stroked
189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // twice with different X shadow offsets to give more feathered edges. Later we erase the
190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // line with destination-out 100% transparent black, leaving only the shadow. This only
191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // works if nothing has been drawn into the canvas yet.
192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.beginPath();
194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.moveTo(x + 4, y + h - 3 - 0.5);
195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x + w - 4, y + h - 3 - 0.5);
196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.closePath();
197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.save();
199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowBlur = 2;
201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowOffsetX = 3;
203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowOffsetY = 5;
204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.strokeStyle = "white";
206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineWidth = 1;
207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.stroke();
209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.shadowOffsetX = -3;
211231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.stroke();
213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
214231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.restore();
215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
216231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.save();
217231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
218231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.globalCompositeOperation = "destination-out";
219231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.strokeStyle = "rgba(0, 0, 0, 1)";
220231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineWidth = 1;
221231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
222231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.stroke();
223231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
224231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.restore();
225231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
226231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
227231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        function drawPill()
228231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        {
229231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Make a rounded rect path.
230231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.beginPath();
231231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.moveTo(x, y + r);
232231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x, y + h - r);
23321939df44de1705786c545cd1bf519d47250322dBen Murdoch            ctx.arc(x + r, y + h - r, r, Math.PI, Math.PI / 2, true);
234231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x + w - r, y + h);
23521939df44de1705786c545cd1bf519d47250322dBen Murdoch            ctx.arc(x + w - r, y + h - r, r, Math.PI / 2, 0, true);
236231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x + w, y + r);
23721939df44de1705786c545cd1bf519d47250322dBen Murdoch            ctx.arc(x + w - r, y + r, r, 0, 3 * Math.PI / 2, true);
238231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineTo(x + r, y);
23921939df44de1705786c545cd1bf519d47250322dBen Murdoch            ctx.arc(x + r, y + r, r, Math.PI / 2, Math.PI, true);
240231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.closePath();
241231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
242231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Clip to the rounded rect path.
243231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.save();
244231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.clip();
245231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
246231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Fill the segments with the associated color.
247231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var previousSegmentsWidth = 0;
248231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (var i = 0; i < segments.length; ++i) {
249231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                var segmentWidth = Math.round(w * percents[i] / 100);
250231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.fillStyle = segments[i].color;
251231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.fillRect(x + previousSegmentsWidth, y, segmentWidth, h);
252231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                previousSegmentsWidth += segmentWidth;
253231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
254231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
255231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Draw the segment divider lines.
256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.lineWidth = 1;
257231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            for (var i = 1; i < 20; ++i) {
258231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.beginPath();
259231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.moveTo(x + (i * Math.round(w / 20)) + 0.5, y);
260231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.lineTo(x + (i * Math.round(w / 20)) + 0.5, y + h);
261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.closePath();
262231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
263231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.strokeStyle = "rgba(0, 0, 0, 0.2)";
264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.stroke();
265231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
266231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.beginPath();
267231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.moveTo(x + (i * Math.round(w / 20)) + 1.5, y);
268231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.lineTo(x + (i * Math.round(w / 20)) + 1.5, y + h);
269231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.closePath();
270231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
271231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.strokeStyle = "rgba(255, 255, 255, 0.2)";
272231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block                ctx.stroke();
273231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            }
274231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
275231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            // Draw the pill shading.
276231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var lightGradient = ctx.createLinearGradient(x, y, x, y + (h / 1.5));
277231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lightGradient.addColorStop(0.0, "rgba(220, 220, 220, 0.6)");
278231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lightGradient.addColorStop(0.4, "rgba(220, 220, 220, 0.2)");
279231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            lightGradient.addColorStop(1.0, "rgba(255, 255, 255, 0.0)");
280231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
281231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var darkGradient = ctx.createLinearGradient(x, y + (h / 3), x, y + h);
282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            darkGradient.addColorStop(0.0, "rgba(0, 0, 0, 0.0)");
283231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            darkGradient.addColorStop(0.8, "rgba(0, 0, 0, 0.2)");
284231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            darkGradient.addColorStop(1.0, "rgba(0, 0, 0, 0.5)");
285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
286231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = darkGradient;
287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(x, y, w, h);
288231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
289231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillStyle = lightGradient;
290231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.fillRect(x, y, w, h);
291231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
292231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            ctx.restore();
293231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
294231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
295231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.clearRect(x, y, w, (h * 2));
296231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
297231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawPillShadow();
298231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawPill();
299231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
300231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.save();
301231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
302231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.translate(0, (h * 2) + 1);
303231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.scale(1, -1);
304231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
305231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        drawPill();
306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
307231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.restore();
308231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
309231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        this._fadeOutRect(ctx, x, y + h + 1, w, h, 0.5, 0.0);
310231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
312231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    _fadeOutRect: function(ctx, x, y, w, h, a1, a2)
313231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
314231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.save();
315231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var gradient = ctx.createLinearGradient(x, y, x, y + h);
317231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        gradient.addColorStop(0.0, "rgba(0, 0, 0, " + (1.0 - a1) + ")");
318231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        gradient.addColorStop(0.8, "rgba(0, 0, 0, " + (1.0 - a2) + ")");
319231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        gradient.addColorStop(1.0, "rgba(0, 0, 0, 1.0)");
320231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
321231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.globalCompositeOperation = "destination-out";
322231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
323231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.fillStyle = gradient;
324231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.fillRect(x, y, w, h);
325231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
326231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        ctx.restore();
327231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    },
328231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
329231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    _makeLegendElement: function(label, value, color)
330231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    {
331231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var legendElement = document.createElement("label");
332231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        legendElement.className = "summary-graph-legend-item";
333231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
334231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        if (color) {
335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            var swatch = document.createElement("canvas");
336231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            swatch.className = "summary-graph-legend-swatch";
337231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            swatch.setAttribute("width", "13");
338231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            swatch.setAttribute("height", "24");
339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
340231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            legendElement.appendChild(swatch);
341231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block            this._drawSwatch(swatch, color);
343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        }
344231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
345231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var labelElement = document.createElement("div");
346231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        labelElement.className = "summary-graph-legend-label";
347231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        legendElement.appendChild(labelElement);
348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var headerElement = document.createElement("div");
350231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        headerElement.className = "summary-graph-legend-header";
351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        headerElement.textContent = label;
352231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        labelElement.appendChild(headerElement);
353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
354231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        var valueElement = document.createElement("div");
355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        valueElement.className = "summary-graph-legend-value";
356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        valueElement.textContent = value;
357231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        labelElement.appendChild(valueElement);
358231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
359231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block        return legendElement;
360231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block    }
361231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}
362231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block
363231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockWebInspector.SummaryBar.prototype.__proto__ = WebInspector.Object.prototype;
364