~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/contrib/PlotKit/SweetCanvas.js

  • Committer: Guilherme Salgado
  • Date: 2010-04-28 15:11:56 UTC
  • mfrom: (10795 launchpad)
  • mto: This revision was merged to the branch mainline in revision 10969.
  • Revision ID: salgado@canonical.com-20100428151156-5cedwvi9b0f478mj
mergeĀ fromĀ mainline

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
    PlotKit Sweet Canvas Renderer
3
 
    =============================
4
 
    Canvas Renderer for PlotKit which looks pretty!
5
 
 
6
 
    Copyright
7
 
    ---------
8
 
    Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
9
 
    For use under the BSD license. <http://www.liquidx.net/plotkit>
10
 
*/
11
 
 
12
 
// -------------------------------------------------------------------------
13
 
// Check required components
14
 
// -------------------------------------------------------------------------
15
 
 
16
 
try {    
17
 
    if (typeof(PlotKit.CanvasRenderer) == 'undefined')
18
 
    {
19
 
        throw "";    
20
 
    }
21
 
22
 
catch (e) {    
23
 
    throw "SweetCanvas depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Layout, Canvas}"
24
 
}
25
 
 
26
 
 
27
 
if (typeof(PlotKit.SweetCanvasRenderer) == 'undefined') {
28
 
    PlotKit.SweetCanvasRenderer = {};
29
 
}
30
 
 
31
 
PlotKit.SweetCanvasRenderer = function(element, layout, options) {
32
 
    if (arguments.length > 0) {
33
 
        this.__init__(element, layout, options);
34
 
    }
35
 
};
36
 
 
37
 
PlotKit.SweetCanvasRenderer.NAME = "PlotKit.SweetCanvasRenderer";
38
 
PlotKit.SweetCanvasRenderer.VERSION = PlotKit.VERSION;
39
 
 
40
 
PlotKit.SweetCanvasRenderer.__repr__ = function() {
41
 
    return "[" + this.NAME + " " + this.VERSION + "]";
42
 
};
43
 
 
44
 
PlotKit.SweetCanvasRenderer.toString = function() {
45
 
    return this.__repr__();
46
 
};
47
 
 
48
 
// ---------------------------------------------------------------------
49
 
// Subclassing Magic
50
 
// ---------------------------------------------------------------------
51
 
 
52
 
PlotKit.SweetCanvasRenderer.prototype = new PlotKit.CanvasRenderer();
53
 
PlotKit.SweetCanvasRenderer.prototype.constructor = PlotKit.SweetCanvasRenderer;
54
 
PlotKit.SweetCanvasRenderer.__super__ = PlotKit.CanvasRenderer.prototype;
55
 
 
56
 
// ---------------------------------------------------------------------
57
 
// Constructor
58
 
// ---------------------------------------------------------------------
59
 
 
60
 
PlotKit.SweetCanvasRenderer.prototype.__init__ = function(el, layout, opts) { 
61
 
    var moreOpts = PlotKit.Base.officeBlue();
62
 
    MochiKit.Base.update(moreOpts, opts);
63
 
    PlotKit.SweetCanvasRenderer.__super__.__init__.call(this, el, layout, moreOpts);
64
 
};
65
 
 
66
 
// ---------------------------------------------------------------------
67
 
// Extended Plotting Functions
68
 
// ---------------------------------------------------------------------
69
 
 
70
 
PlotKit.SweetCanvasRenderer.prototype._renderBarChart = function() {
71
 
    var bind = MochiKit.Base.bind;
72
 
    var shadowColor = Color.blackColor().colorWithAlpha(0.1).toRGBString();
73
 
 
74
 
    var prepareFakeShadow = function(context, x, y, w, h) {
75
 
        context.fillStyle = shadowColor;
76
 
        context.fillRect(x-2, y-2, w+4, h+2); 
77
 
        context.fillStyle = shadowColor;
78
 
        context.fillRect(x-1, y-1, w+2, h+1); 
79
 
    };
80
 
 
81
 
    var colorCount = this.options.colorScheme.length;
82
 
    var colorScheme =  this.options.colorScheme;
83
 
    var setNames = PlotKit.Base.keys(this.layout.datasets);
84
 
    var setCount = setNames.length;
85
 
 
86
 
    var chooseColor = function(name) {
87
 
        for (var i = 0; i < setCount; i++) {
88
 
            if (name == setNames[i])
89
 
                return colorScheme[i%colorCount];
90
 
        }
91
 
        return colorScheme[0];
92
 
    };
93
 
 
94
 
    var drawRect = function(context, bar) {
95
 
        var x = this.area.w * bar.x + this.area.x;
96
 
        var y = this.area.h * bar.y + this.area.y;
97
 
        var w = this.area.w * bar.w;
98
 
        var h = this.area.h * bar.h;
99
 
 
100
 
        if ((w < 1) || (h < 1))
101
 
            return;        
102
 
 
103
 
        context.save();
104
 
 
105
 
        context.shadowBlur = 5.0;
106
 
        context.shadowColor = Color.fromHexString("#888888").toRGBString();
107
 
 
108
 
        if (this.isIE) {
109
 
            context.save();
110
 
            context.fillStyle = "#cccccc";
111
 
            context.fillRect(x-2, y-2, w+4, h+2); 
112
 
            context.restore();
113
 
        }
114
 
        else {
115
 
            prepareFakeShadow(context, x, y, w, h);
116
 
        }
117
 
 
118
 
        if (this.options.shouldFill) {
119
 
            context.fillStyle = chooseColor(bar.name).toRGBString();
120
 
            context.fillRect(x, y, w, h);
121
 
        }
122
 
 
123
 
        context.shadowBlur = 0;
124
 
        context.strokeStyle = Color.whiteColor().toRGBString();
125
 
        context.lineWidth = 2.0;
126
 
        
127
 
        if (this.options.shouldStroke) {
128
 
            context.strokeRect(x, y, w, h);                
129
 
        }
130
 
 
131
 
        context.restore();
132
 
 
133
 
    };
134
 
    this._renderBarChartWrap(this.layout.bars, bind(drawRect, this));
135
 
};
136
 
 
137
 
PlotKit.SweetCanvasRenderer.prototype._renderLineChart = function() {
138
 
    var context = this.element.getContext("2d");
139
 
    var colorCount = this.options.colorScheme.length;
140
 
    var colorScheme = this.options.colorScheme;
141
 
    var setNames = PlotKit.Base.keys(this.layout.datasets);
142
 
    var setCount = setNames.length;
143
 
    var bind = MochiKit.Base.bind;
144
 
 
145
 
 
146
 
    for (var i = 0; i < setCount; i++) {
147
 
        var setName = setNames[i];
148
 
        var color = colorScheme[i%colorCount];
149
 
        var strokeX = this.options.strokeColorTransform;
150
 
 
151
 
        // setup graphics context
152
 
        context.save();
153
 
        
154
 
        // create paths
155
 
        var makePath = function(ctx) {
156
 
            ctx.beginPath();
157
 
            ctx.moveTo(this.area.x, this.area.y + this.area.h);
158
 
            var addPoint = function(ctx_, point) {
159
 
            if (point.name == setName)
160
 
                ctx_.lineTo(this.area.w * point.x + this.area.x,
161
 
                            this.area.h * point.y + this.area.y);
162
 
            };
163
 
            MochiKit.Iter.forEach(this.layout.points, partial(addPoint, ctx), this);
164
 
            ctx.lineTo(this.area.w + this.area.x,
165
 
                           this.area.h + this.area.y);
166
 
            ctx.lineTo(this.area.x, this.area.y + this.area.h);
167
 
            ctx.closePath();
168
 
        };
169
 
 
170
 
        // faux shadow for firefox
171
 
        if (this.options.shouldFill) {
172
 
            context.save();
173
 
            if (this.isIE) {
174
 
                context.fillStyle = "#cccccc";
175
 
            }
176
 
            else {
177
 
                context.fillStyle = Color.blackColor().colorWithAlpha(0.2).toRGBString();
178
 
            }
179
 
            context.translate(-1, -2);
180
 
            bind(makePath, this)(context);
181
 
            if (this.options.shouldFill) {
182
 
                context.fill();
183
 
            }
184
 
            context.restore();
185
 
        }
186
 
 
187
 
        context.shadowBlur = 5.0;
188
 
        context.shadowColor = Color.fromHexString("#888888").toRGBString();
189
 
        context.fillStyle = color.toRGBString();
190
 
        context.lineWidth = 2.0;
191
 
        context.strokeStyle = Color.whiteColor().toRGBString();
192
 
 
193
 
        if (this.options.shouldFill) {
194
 
            bind(makePath, this)(context);
195
 
            context.fill();
196
 
        }
197
 
        if (this.options.shouldStroke) {
198
 
            bind(makePath, this)(context);
199
 
            context.stroke();
200
 
        }
201
 
        context.restore();
202
 
    }
203
 
};
204
 
 
205
 
PlotKit.SweetCanvasRenderer.prototype._renderPieChart = function() {
206
 
    var context = this.element.getContext("2d");
207
 
 
208
 
    var colorCount = this.options.colorScheme.length;
209
 
    var slices = this.layout.slices;
210
 
 
211
 
    var centerx = this.area.x + this.area.w * 0.5;
212
 
    var centery = this.area.y + this.area.h * 0.5;
213
 
    var radius = Math.min(this.area.w * this.options.pieRadius, 
214
 
                          this.area.h * this.options.pieRadius);
215
 
 
216
 
    if (this.isIE) {
217
 
        centerx = parseInt(centerx);
218
 
        centery = parseInt(centery);
219
 
        radius = parseInt(radius);
220
 
    }
221
 
 
222
 
        // NOTE NOTE!! Canvas Tag draws the circle clockwise from the y = 0, x = 1
223
 
        // so we have to subtract 90 degrees to make it start at y = 1, x = 0
224
 
 
225
 
    if (!this.isIE) {
226
 
        context.save();
227
 
        var shadowColor = Color.blackColor().colorWithAlpha(0.2);
228
 
        context.fillStyle = shadowColor.toRGBString();
229
 
        context.shadowBlur = 5.0;
230
 
        context.shadowColor = Color.fromHexString("#888888").toRGBString();
231
 
        context.translate(1, 1);
232
 
        context.beginPath();
233
 
        context.moveTo(centerx, centery);
234
 
        context.arc(centerx, centery, radius + 2, 0, Math.PI*2, false);
235
 
        context.closePath();
236
 
        context.fill();
237
 
        context.restore();
238
 
    }
239
 
 
240
 
    context.save();
241
 
    context.strokeStyle = Color.whiteColor().toRGBString();
242
 
    context.lineWidth = 2.0;    
243
 
    for (var i = 0; i < slices.length; i++) {
244
 
        var color = this.options.colorScheme[i%colorCount];
245
 
        context.fillStyle = color.toRGBString();
246
 
 
247
 
        var makePath = function() {
248
 
            context.beginPath();
249
 
            context.moveTo(centerx, centery);
250
 
            context.arc(centerx, centery, radius, 
251
 
                        slices[i].startAngle - Math.PI/2,
252
 
                        slices[i].endAngle - Math.PI/2,
253
 
                        false);
254
 
            context.lineTo(centerx, centery);
255
 
            context.closePath();
256
 
        };
257
 
 
258
 
        if (Math.abs(slices[i].startAngle - slices[i].endAngle) > 0.0001) {
259
 
            if (this.options.shouldFill) {
260
 
                makePath();
261
 
                context.fill();
262
 
            }
263
 
            if (this.options.shouldStroke) {
264
 
                makePath();
265
 
                context.stroke();
266
 
            }
267
 
        }
268
 
    }
269
 
    context.restore();
270
 
};
271
 
 
272
 
PlotKit.SweetCanvasRenderer.prototype._renderBackground = function() {
273
 
    var context = this.element.getContext("2d");
274
 
   
275
 
    if (this.layout.style == "bar" || this.layout.style == "line") {
276
 
        context.save();
277
 
        context.fillStyle = this.options.backgroundColor.toRGBString();
278
 
        context.fillRect(this.area.x, this.area.y, this.area.w, this.area.h);
279
 
        context.strokeStyle = this.options.axisLineColor.toRGBString();
280
 
        context.lineWidth = 1.0;
281
 
        
282
 
        var ticks = this.layout.yticks;
283
 
        var horiz = false;
284
 
        if (this.layout.style == "bar" && 
285
 
            this.layout.options.barOrientation == "horizontal") {
286
 
                ticks = this.layout.xticks;
287
 
                horiz = true;
288
 
        }
289
 
        
290
 
        for (var i = 0; i < ticks.length; i++) {
291
 
            var x1 = 0;
292
 
            var y1 = 0;
293
 
            var x2 = 0;
294
 
            var y2 = 0;
295
 
            
296
 
            if (horiz) {
297
 
                x1 = ticks[i][0] * this.area.w + this.area.x;
298
 
                y1 = this.area.y;
299
 
                x2 = x1;
300
 
                y2 = y1 + this.area.h;
301
 
            }
302
 
            else {
303
 
                x1 = this.area.x;
304
 
                y1 = ticks[i][0] * this.area.h + this.area.y;
305
 
                x2 = x1 + this.area.w;
306
 
                y2 = y1;
307
 
            }
308
 
            
309
 
            context.beginPath();
310
 
            context.moveTo(x1, y1);
311
 
            context.lineTo(x2, y2);
312
 
            context.closePath();
313
 
            context.stroke();
314
 
        }
315
 
        context.restore();
316
 
    }
317
 
    else {
318
 
        PlotKit.SweetCanvasRenderer.__super__._renderBackground.call(this);
319
 
    }
320
 
};
321
 
 
322
 
// Namespace Iniitialisation
323
 
 
324
 
PlotKit.SweetCanvas = {}
325
 
PlotKit.SweetCanvas.SweetCanvasRenderer = PlotKit.SweetCanvasRenderer;
326
 
 
327
 
PlotKit.SweetCanvas.EXPORT = [
328
 
    "SweetCanvasRenderer"
329
 
];
330
 
 
331
 
PlotKit.SweetCanvas.EXPORT_OK = [
332
 
    "SweetCanvasRenderer"
333
 
];
334
 
 
335
 
PlotKit.SweetCanvas.__new__ = function() {
336
 
    var m = MochiKit.Base;
337
 
    
338
 
    m.nameFunctions(this);
339
 
    
340
 
    this.EXPORT_TAGS = {
341
 
        ":common": this.EXPORT,
342
 
        ":all": m.concat(this.EXPORT, this.EXPORT_OK)
343
 
    };
344
 
};
345
 
 
346
 
PlotKit.SweetCanvas.__new__();
347
 
MochiKit.Base._exportSymbols(this, PlotKit.SweetCanvas);
348