jquery_cheats 2.0.1 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/README.md +19 -2
  2. data/app/assets/javascripts/jqueryCheats.js +36 -1
  3. data/jquery_cheats.gemspec +2 -2
  4. data/lib/jquery_cheats.rb +4 -0
  5. data/vendor/assets/excanvas.js +1438 -0
  6. data/vendor/assets/jquery.jqplot.css +259 -0
  7. data/vendor/assets/jquery.jqplot.js +10901 -0
  8. data/vendor/assets/plugins/jqplot.BezierCurveRenderer.js +312 -0
  9. data/vendor/assets/plugins/jqplot.BezierCurveRenderer.min.js +57 -0
  10. data/vendor/assets/plugins/jqplot.barRenderer.js +747 -0
  11. data/vendor/assets/plugins/jqplot.barRenderer.min.js +57 -0
  12. data/vendor/assets/plugins/jqplot.blockRenderer.js +234 -0
  13. data/vendor/assets/plugins/jqplot.blockRenderer.min.js +57 -0
  14. data/vendor/assets/plugins/jqplot.bubbleRenderer.js +754 -0
  15. data/vendor/assets/plugins/jqplot.bubbleRenderer.min.js +57 -0
  16. data/vendor/assets/plugins/jqplot.canvasAxisLabelRenderer.js +202 -0
  17. data/vendor/assets/plugins/jqplot.canvasAxisLabelRenderer.min.js +57 -0
  18. data/vendor/assets/plugins/jqplot.canvasAxisTickRenderer.js +242 -0
  19. data/vendor/assets/plugins/jqplot.canvasAxisTickRenderer.min.js +57 -0
  20. data/vendor/assets/plugins/jqplot.canvasOverlay.js +864 -0
  21. data/vendor/assets/plugins/jqplot.canvasOverlay.min.js +57 -0
  22. data/vendor/assets/plugins/jqplot.canvasTextRenderer.js +448 -0
  23. data/vendor/assets/plugins/jqplot.canvasTextRenderer.min.js +57 -0
  24. data/vendor/assets/plugins/jqplot.categoryAxisRenderer.js +636 -0
  25. data/vendor/assets/plugins/jqplot.categoryAxisRenderer.min.js +57 -0
  26. data/vendor/assets/plugins/jqplot.ciParser.js +115 -0
  27. data/vendor/assets/plugins/jqplot.ciParser.min.js +57 -0
  28. data/vendor/assets/plugins/jqplot.cursor.js +1093 -0
  29. data/vendor/assets/plugins/jqplot.cursor.min.js +57 -0
  30. data/vendor/assets/plugins/jqplot.dateAxisRenderer.js +702 -0
  31. data/vendor/assets/plugins/jqplot.dateAxisRenderer.min.js +57 -0
  32. data/vendor/assets/plugins/jqplot.donutRenderer.js +800 -0
  33. data/vendor/assets/plugins/jqplot.donutRenderer.min.js +57 -0
  34. data/vendor/assets/plugins/jqplot.dragable.js +224 -0
  35. data/vendor/assets/plugins/jqplot.dragable.min.js +57 -0
  36. data/vendor/assets/plugins/jqplot.enhancedLegendRenderer.js +241 -0
  37. data/vendor/assets/plugins/jqplot.enhancedLegendRenderer.min.js +57 -0
  38. data/vendor/assets/plugins/jqplot.funnelRenderer.js +938 -0
  39. data/vendor/assets/plugins/jqplot.funnelRenderer.min.js +57 -0
  40. data/vendor/assets/plugins/jqplot.highlighter.js +454 -0
  41. data/vendor/assets/plugins/jqplot.highlighter.min.js +57 -0
  42. data/vendor/assets/plugins/jqplot.json2.js +475 -0
  43. data/vendor/assets/plugins/jqplot.json2.min.js +57 -0
  44. data/vendor/assets/plugins/jqplot.logAxisRenderer.js +528 -0
  45. data/vendor/assets/plugins/jqplot.logAxisRenderer.min.js +57 -0
  46. data/vendor/assets/plugins/jqplot.mekkoAxisRenderer.js +610 -0
  47. data/vendor/assets/plugins/jqplot.mekkoAxisRenderer.min.js +57 -0
  48. data/vendor/assets/plugins/jqplot.mekkoRenderer.js +436 -0
  49. data/vendor/assets/plugins/jqplot.mekkoRenderer.min.js +57 -0
  50. data/vendor/assets/plugins/jqplot.meterGaugeRenderer.js +1029 -0
  51. data/vendor/assets/plugins/jqplot.meterGaugeRenderer.min.js +57 -0
  52. data/vendor/assets/plugins/jqplot.ohlcRenderer.js +372 -0
  53. data/vendor/assets/plugins/jqplot.ohlcRenderer.min.js +57 -0
  54. data/vendor/assets/plugins/jqplot.pieRenderer.js +899 -0
  55. data/vendor/assets/plugins/jqplot.pieRenderer.min.js +57 -0
  56. data/vendor/assets/plugins/jqplot.pointLabels.js +362 -0
  57. data/vendor/assets/plugins/jqplot.pointLabels.min.js +57 -0
  58. data/vendor/assets/plugins/jqplot.pyramidAxisRenderer.js +730 -0
  59. data/vendor/assets/plugins/jqplot.pyramidAxisRenderer.min.js +57 -0
  60. data/vendor/assets/plugins/jqplot.pyramidGridRenderer.js +423 -0
  61. data/vendor/assets/plugins/jqplot.pyramidGridRenderer.min.js +57 -0
  62. data/vendor/assets/plugins/jqplot.pyramidRenderer.js +490 -0
  63. data/vendor/assets/plugins/jqplot.pyramidRenderer.min.js +57 -0
  64. data/vendor/assets/plugins/jqplot.trendline.js +222 -0
  65. data/vendor/assets/plugins/jqplot.trendline.min.js +57 -0
  66. metadata +64 -3
@@ -0,0 +1,899 @@
1
+ /**
2
+ * jqPlot
3
+ * Pure JavaScript plotting plugin using jQuery
4
+ *
5
+ * Version: 1.0.0b2_r1012
6
+ *
7
+ * Copyright (c) 2009-2011 Chris Leonello
8
+ * jqPlot is currently available for use in all personal or commercial projects
9
+ * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL
10
+ * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can
11
+ * choose the license that best suits your project and use it accordingly.
12
+ *
13
+ * Although not required, the author would appreciate an email letting him
14
+ * know of any substantial use of jqPlot. You can reach the author at:
15
+ * chris at jqplot dot com or see http://www.jqplot.com/info.php .
16
+ *
17
+ * If you are feeling kind and generous, consider supporting the project by
18
+ * making a donation at: http://www.jqplot.com/donate.php .
19
+ *
20
+ * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
21
+ *
22
+ * version 2007.04.27
23
+ * author Ash Searle
24
+ * http://hexmen.com/blog/2007/03/printf-sprintf/
25
+ * http://hexmen.com/js/sprintf.js
26
+ * The author (Ash Searle) has placed this code in the public domain:
27
+ * "This code is unrestricted: you are free to use it however you like."
28
+ *
29
+ */
30
+ (function($) {
31
+ /**
32
+ * Class: $.jqplot.PieRenderer
33
+ * Plugin renderer to draw a pie chart.
34
+ * x values, if present, will be used as slice labels.
35
+ * y values give slice size.
36
+ *
37
+ * To use this renderer, you need to include the
38
+ * pie renderer plugin, for example:
39
+ *
40
+ * > <script type="text/javascript" src="plugins/jqplot.pieRenderer.js"></script>
41
+ *
42
+ * Properties described here are passed into the $.jqplot function
43
+ * as options on the series renderer. For example:
44
+ *
45
+ * > plot2 = $.jqplot('chart2', [s1, s2], {
46
+ * > seriesDefaults: {
47
+ * > renderer:$.jqplot.PieRenderer,
48
+ * > rendererOptions:{
49
+ * > sliceMargin: 2,
50
+ * > startAngle: -90
51
+ * > }
52
+ * > }
53
+ * > });
54
+ *
55
+ * A pie plot will trigger events on the plot target
56
+ * according to user interaction. All events return the event object,
57
+ * the series index, the point (slice) index, and the point data for
58
+ * the appropriate slice.
59
+ *
60
+ * 'jqplotDataMouseOver' - triggered when user mouseing over a slice.
61
+ * 'jqplotDataHighlight' - triggered the first time user mouses over a slice,
62
+ * if highlighting is enabled.
63
+ * 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of
64
+ * a highlighted slice.
65
+ * 'jqplotDataClick' - triggered when the user clicks on a slice.
66
+ * 'jqplotDataRightClick' - tiggered when the user right clicks on a slice if
67
+ * the "captureRightClick" option is set to true on the plot.
68
+ */
69
+ $.jqplot.PieRenderer = function(){
70
+ $.jqplot.LineRenderer.call(this);
71
+ };
72
+
73
+ $.jqplot.PieRenderer.prototype = new $.jqplot.LineRenderer();
74
+ $.jqplot.PieRenderer.prototype.constructor = $.jqplot.PieRenderer;
75
+
76
+ // called with scope of a series
77
+ $.jqplot.PieRenderer.prototype.init = function(options, plot) {
78
+ // Group: Properties
79
+ //
80
+ // prop: diameter
81
+ // Outer diameter of the pie, auto computed by default
82
+ this.diameter = null;
83
+ // prop: padding
84
+ // padding between the pie and plot edges, legend, etc.
85
+ this.padding = 20;
86
+ // prop: sliceMargin
87
+ // angular spacing between pie slices in degrees.
88
+ this.sliceMargin = 0;
89
+ // prop: fill
90
+ // true or false, wether to fil the slices.
91
+ this.fill = true;
92
+ // prop: shadowOffset
93
+ // offset of the shadow from the slice and offset of
94
+ // each succesive stroke of the shadow from the last.
95
+ this.shadowOffset = 2;
96
+ // prop: shadowAlpha
97
+ // transparency of the shadow (0 = transparent, 1 = opaque)
98
+ this.shadowAlpha = 0.07;
99
+ // prop: shadowDepth
100
+ // number of strokes to apply to the shadow,
101
+ // each stroke offset shadowOffset from the last.
102
+ this.shadowDepth = 5;
103
+ // prop: highlightMouseOver
104
+ // True to highlight slice when moused over.
105
+ // This must be false to enable highlightMouseDown to highlight when clicking on a slice.
106
+ this.highlightMouseOver = true;
107
+ // prop: highlightMouseDown
108
+ // True to highlight when a mouse button is pressed over a slice.
109
+ // This will be disabled if highlightMouseOver is true.
110
+ this.highlightMouseDown = false;
111
+ // prop: highlightColors
112
+ // an array of colors to use when highlighting a slice.
113
+ this.highlightColors = [];
114
+ // prop: dataLabels
115
+ // Either 'label', 'value', 'percent' or an array of labels to place on the pie slices.
116
+ // Defaults to percentage of each pie slice.
117
+ this.dataLabels = 'percent';
118
+ // prop: showDataLabels
119
+ // true to show data labels on slices.
120
+ this.showDataLabels = false;
121
+ // prop: dataLabelFormatString
122
+ // Format string for data labels. If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage.
123
+ this.dataLabelFormatString = null;
124
+ // prop: dataLabelThreshold
125
+ // Threshhold in percentage (0-100) of pie area, below which no label will be displayed.
126
+ // This applies to all label types, not just to percentage labels.
127
+ this.dataLabelThreshold = 3;
128
+ // prop: dataLabelPositionFactor
129
+ // A Multiplier (0-1) of the pie radius which controls position of label on slice.
130
+ // Increasing will slide label toward edge of pie, decreasing will slide label toward center of pie.
131
+ this.dataLabelPositionFactor = 0.52;
132
+ // prop: dataLabelNudge
133
+ // Number of pixels to slide the label away from (+) or toward (-) the center of the pie.
134
+ this.dataLabelNudge = 2;
135
+ // prop: dataLabelCenterOn
136
+ // True to center the data label at its position.
137
+ // False to set the inside facing edge of the label at its position.
138
+ this.dataLabelCenterOn = true;
139
+ // prop: startAngle
140
+ // Angle to start drawing pie in degrees.
141
+ // According to orientation of canvas coordinate system:
142
+ // 0 = on the positive x axis
143
+ // -90 = on the positive y axis.
144
+ // 90 = on the negaive y axis.
145
+ // 180 or - 180 = on the negative x axis.
146
+ this.startAngle = 0;
147
+ this.tickRenderer = $.jqplot.PieTickRenderer;
148
+ // Used as check for conditions where pie shouldn't be drawn.
149
+ this._drawData = true;
150
+ this._type = 'pie';
151
+
152
+ // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver
153
+ if (options.highlightMouseDown && options.highlightMouseOver == null) {
154
+ options.highlightMouseOver = false;
155
+ }
156
+
157
+ $.extend(true, this, options);
158
+
159
+ if (this.sliceMargin < 0) {
160
+ this.sliceMargin = 0;
161
+ }
162
+
163
+ this._diameter = null;
164
+ this._radius = null;
165
+ // array of [start,end] angles arrays, one for each slice. In radians.
166
+ this._sliceAngles = [];
167
+ // index of the currenty highlighted point, if any
168
+ this._highlightedPoint = null;
169
+
170
+ // set highlight colors if none provided
171
+ if (this.highlightColors.length == 0) {
172
+ for (var i=0; i<this.seriesColors.length; i++){
173
+ var rgba = $.jqplot.getColorComponents(this.seriesColors[i]);
174
+ var newrgb = [rgba[0], rgba[1], rgba[2]];
175
+ var sum = newrgb[0] + newrgb[1] + newrgb[2];
176
+ for (var j=0; j<3; j++) {
177
+ // when darkening, lowest color component can be is 60.
178
+ newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]);
179
+ newrgb[j] = parseInt(newrgb[j], 10);
180
+ }
181
+ this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')');
182
+ }
183
+ }
184
+
185
+ this.highlightColorGenerator = new $.jqplot.ColorGenerator(this.highlightColors);
186
+
187
+ plot.postParseOptionsHooks.addOnce(postParseOptions);
188
+ plot.postInitHooks.addOnce(postInit);
189
+ plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove);
190
+ plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown);
191
+ plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp);
192
+ plot.eventListenerHooks.addOnce('jqplotClick', handleClick);
193
+ plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick);
194
+ plot.postDrawHooks.addOnce(postPlotDraw);
195
+ };
196
+
197
+ $.jqplot.PieRenderer.prototype.setGridData = function(plot) {
198
+ // set gridData property. This will hold angle in radians of each data point.
199
+ var stack = [];
200
+ var td = [];
201
+ var sa = this.startAngle/180*Math.PI;
202
+ var tot = 0;
203
+ // don't know if we have any valid data yet, so set plot to not draw.
204
+ this._drawData = false;
205
+ for (var i=0; i<this.data.length; i++){
206
+ if (this.data[i][1] != 0) {
207
+ // we have data, O.K. to draw.
208
+ this._drawData = true;
209
+ }
210
+ stack.push(this.data[i][1]);
211
+ td.push([this.data[i][0]]);
212
+ if (i>0) {
213
+ stack[i] += stack[i-1];
214
+ }
215
+ tot += this.data[i][1];
216
+ }
217
+ var fact = Math.PI*2/stack[stack.length - 1];
218
+
219
+ for (var i=0; i<stack.length; i++) {
220
+ td[i][1] = stack[i] * fact;
221
+ td[i][2] = this.data[i][1]/tot;
222
+ }
223
+ this.gridData = td;
224
+ };
225
+
226
+ $.jqplot.PieRenderer.prototype.makeGridData = function(data, plot) {
227
+ var stack = [];
228
+ var td = [];
229
+ var tot = 0;
230
+ var sa = this.startAngle/180*Math.PI;
231
+ // don't know if we have any valid data yet, so set plot to not draw.
232
+ this._drawData = false;
233
+ for (var i=0; i<data.length; i++){
234
+ if (this.data[i][1] != 0) {
235
+ // we have data, O.K. to draw.
236
+ this._drawData = true;
237
+ }
238
+ stack.push(data[i][1]);
239
+ td.push([data[i][0]]);
240
+ if (i>0) {
241
+ stack[i] += stack[i-1];
242
+ }
243
+ tot += data[i][1];
244
+ }
245
+ var fact = Math.PI*2/stack[stack.length - 1];
246
+
247
+ for (var i=0; i<stack.length; i++) {
248
+ td[i][1] = stack[i] * fact;
249
+ td[i][2] = data[i][1]/tot;
250
+ }
251
+ return td;
252
+ };
253
+
254
+ function calcRadiusAdjustment(ang) {
255
+ return Math.sin((ang - (ang-Math.PI) / 8 / Math.PI )/2.0);
256
+ }
257
+
258
+ function calcRPrime(ang1, ang2, sliceMargin, fill, lineWidth) {
259
+ var rprime = 0;
260
+ var ang = ang2 - ang1;
261
+ var absang = Math.abs(ang);
262
+ var sm = sliceMargin;
263
+ if (fill == false) {
264
+ sm += lineWidth;
265
+ }
266
+
267
+ if (sm > 0 && absang > 0.01 && absang < 6.282) {
268
+ rprime = parseFloat(sm) / 2.0 / calcRadiusAdjustment(ang);
269
+ }
270
+
271
+ return rprime;
272
+ }
273
+
274
+ $.jqplot.PieRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) {
275
+ if (this._drawData) {
276
+ var r = this._radius;
277
+ var fill = this.fill;
278
+ var lineWidth = this.lineWidth;
279
+ var sm = this.sliceMargin;
280
+ if (this.fill == false) {
281
+ sm += this.lineWidth;
282
+ }
283
+ ctx.save();
284
+ ctx.translate(this._center[0], this._center[1]);
285
+
286
+ var rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth);
287
+
288
+ var transx = rprime * Math.cos((ang1 + ang2) / 2.0);
289
+ var transy = rprime * Math.sin((ang1 + ang2) / 2.0);
290
+
291
+ if ((ang2 - ang1) <= Math.PI) {
292
+ r -= rprime;
293
+ }
294
+ else {
295
+ r += rprime;
296
+ }
297
+
298
+ ctx.translate(transx, transy);
299
+
300
+ if (isShadow) {
301
+ for (var i=0, l=this.shadowDepth; i<l; i++) {
302
+ ctx.save();
303
+ ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI));
304
+ doDraw(r);
305
+ }
306
+ for (var i=0, l=this.shadowDepth; i<l; i++) {
307
+ ctx.restore();
308
+ }
309
+ }
310
+
311
+ else {
312
+ doDraw(r);
313
+ }
314
+ ctx.restore();
315
+ }
316
+
317
+ function doDraw (rad) {
318
+ // Fix for IE and Chrome that can't seem to draw circles correctly.
319
+ // ang2 should always be <= 2 pi since that is the way the data is converted.
320
+ // 2Pi = 6.2831853, Pi = 3.1415927
321
+ if (ang2 > 6.282 + this.startAngle) {
322
+ ang2 = 6.282 + this.startAngle;
323
+ if (ang1 > ang2) {
324
+ ang1 = 6.281 + this.startAngle;
325
+ }
326
+ }
327
+ // Fix for IE, where it can't seem to handle 0 degree angles. Also avoids
328
+ // ugly line on unfilled pies.
329
+ if (ang1 >= ang2) {
330
+ return;
331
+ }
332
+
333
+ ctx.beginPath();
334
+ ctx.fillStyle = color;
335
+ ctx.strokeStyle = color;
336
+ ctx.lineWidth = lineWidth;
337
+ ctx.arc(0, 0, rad, ang1, ang2, false);
338
+ ctx.lineTo(0,0);
339
+ ctx.closePath();
340
+
341
+ if (fill) {
342
+ ctx.fill();
343
+ }
344
+ else {
345
+ ctx.stroke();
346
+ }
347
+ }
348
+ };
349
+
350
+ // called with scope of series
351
+ $.jqplot.PieRenderer.prototype.draw = function (ctx, gd, options, plot) {
352
+ var i;
353
+ var opts = (options != undefined) ? options : {};
354
+ // offset and direction of offset due to legend placement
355
+ var offx = 0;
356
+ var offy = 0;
357
+ var trans = 1;
358
+ var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors);
359
+ if (options.legendInfo && options.legendInfo.placement == 'insideGrid') {
360
+ var li = options.legendInfo;
361
+ switch (li.location) {
362
+ case 'nw':
363
+ offx = li.width + li.xoffset;
364
+ break;
365
+ case 'w':
366
+ offx = li.width + li.xoffset;
367
+ break;
368
+ case 'sw':
369
+ offx = li.width + li.xoffset;
370
+ break;
371
+ case 'ne':
372
+ offx = li.width + li.xoffset;
373
+ trans = -1;
374
+ break;
375
+ case 'e':
376
+ offx = li.width + li.xoffset;
377
+ trans = -1;
378
+ break;
379
+ case 'se':
380
+ offx = li.width + li.xoffset;
381
+ trans = -1;
382
+ break;
383
+ case 'n':
384
+ offy = li.height + li.yoffset;
385
+ break;
386
+ case 's':
387
+ offy = li.height + li.yoffset;
388
+ trans = -1;
389
+ break;
390
+ default:
391
+ break;
392
+ }
393
+ }
394
+
395
+ var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow;
396
+ var fill = (opts.fill != undefined) ? opts.fill : this.fill;
397
+ var cw = ctx.canvas.width;
398
+ var ch = ctx.canvas.height;
399
+ var w = cw - offx - 2 * this.padding;
400
+ var h = ch - offy - 2 * this.padding;
401
+ var mindim = Math.min(w,h);
402
+ var d = mindim;
403
+
404
+ // Fixes issue #272. Thanks hugwijst!
405
+ // reset slice angles array.
406
+ this._sliceAngles = [];
407
+
408
+ var sm = this.sliceMargin;
409
+ if (this.fill == false) {
410
+ sm += this.lineWidth;
411
+ }
412
+
413
+ var rprime;
414
+ var maxrprime = 0;
415
+
416
+ var ang, ang1, ang2, shadowColor;
417
+ var sa = this.startAngle / 180 * Math.PI;
418
+
419
+ // have to pre-draw shadows, so loop throgh here and calculate some values also.
420
+ for (var i=0, l=gd.length; i<l; i++) {
421
+ ang1 = (i == 0) ? sa : gd[i-1][1] + sa;
422
+ ang2 = gd[i][1] + sa;
423
+
424
+ this._sliceAngles.push([ang1, ang2]);
425
+
426
+ rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth);
427
+
428
+ if (Math.abs(ang2-ang1) > Math.PI) {
429
+ maxrprime = Math.max(rprime, maxrprime);
430
+ }
431
+ }
432
+
433
+ if (this.diameter != null && this.diameter > 0) {
434
+ this._diameter = this.diameter - 2*maxrprime;
435
+ }
436
+ else {
437
+ this._diameter = d - 2*maxrprime;
438
+ }
439
+
440
+ // Need to check for undersized pie. This can happen if
441
+ // plot area too small and legend is too big.
442
+ if (this._diameter < 6) {
443
+ $.jqplot.log('Diameter of pie too small, not rendering.');
444
+ return;
445
+ }
446
+
447
+ var r = this._radius = this._diameter/2;
448
+
449
+ this._center = [(cw - trans * offx)/2 + trans * offx + maxrprime * Math.cos(sa), (ch - trans*offy)/2 + trans * offy + maxrprime * Math.sin(sa)];
450
+
451
+ if (this.shadow) {
452
+ for (var i=0, l=gd.length; i<l; i++) {
453
+ shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')';
454
+ this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], shadowColor, true);
455
+ }
456
+ }
457
+
458
+ for (var i=0; i<gd.length; i++) {
459
+
460
+ this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], colorGenerator.next(), false);
461
+
462
+ if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) {
463
+ var fstr, avgang = (this._sliceAngles[i][0] + this._sliceAngles[i][1])/2, label;
464
+
465
+ if (this.dataLabels == 'label') {
466
+ fstr = this.dataLabelFormatString || '%s';
467
+ label = $.jqplot.sprintf(fstr, gd[i][0]);
468
+ }
469
+ else if (this.dataLabels == 'value') {
470
+ fstr = this.dataLabelFormatString || '%d';
471
+ label = $.jqplot.sprintf(fstr, this.data[i][1]);
472
+ }
473
+ else if (this.dataLabels == 'percent') {
474
+ fstr = this.dataLabelFormatString || '%d%%';
475
+ label = $.jqplot.sprintf(fstr, gd[i][2]*100);
476
+ }
477
+ else if (this.dataLabels.constructor == Array) {
478
+ fstr = this.dataLabelFormatString || '%s';
479
+ label = $.jqplot.sprintf(fstr, this.dataLabels[i]);
480
+ }
481
+
482
+ var fact = (this._radius ) * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge;
483
+
484
+ var x = this._center[0] + Math.cos(avgang) * fact + this.canvas._offsets.left;
485
+ var y = this._center[1] + Math.sin(avgang) * fact + this.canvas._offsets.top;
486
+
487
+ var labelelem = $('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">' + label + '</div>').insertBefore(plot.eventCanvas._elem);
488
+ if (this.dataLabelCenterOn) {
489
+ x -= labelelem.width()/2;
490
+ y -= labelelem.height()/2;
491
+ }
492
+ else {
493
+ x -= labelelem.width() * Math.sin(avgang/2);
494
+ y -= labelelem.height()/2;
495
+ }
496
+ x = Math.round(x);
497
+ y = Math.round(y);
498
+ labelelem.css({left: x, top: y});
499
+ }
500
+ }
501
+ };
502
+
503
+ $.jqplot.PieAxisRenderer = function() {
504
+ $.jqplot.LinearAxisRenderer.call(this);
505
+ };
506
+
507
+ $.jqplot.PieAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
508
+ $.jqplot.PieAxisRenderer.prototype.constructor = $.jqplot.PieAxisRenderer;
509
+
510
+
511
+ // There are no traditional axes on a pie chart. We just need to provide
512
+ // dummy objects with properties so the plot will render.
513
+ // called with scope of axis object.
514
+ $.jqplot.PieAxisRenderer.prototype.init = function(options){
515
+ //
516
+ this.tickRenderer = $.jqplot.PieTickRenderer;
517
+ $.extend(true, this, options);
518
+ // I don't think I'm going to need _dataBounds here.
519
+ // have to go Axis scaling in a way to fit chart onto plot area
520
+ // and provide u2p and p2u functionality for mouse cursor, etc.
521
+ // for convienence set _dataBounds to 0 and 100 and
522
+ // set min/max to 0 and 100.
523
+ this._dataBounds = {min:0, max:100};
524
+ this.min = 0;
525
+ this.max = 100;
526
+ this.showTicks = false;
527
+ this.ticks = [];
528
+ this.showMark = false;
529
+ this.show = false;
530
+ };
531
+
532
+
533
+
534
+
535
+ $.jqplot.PieLegendRenderer = function(){
536
+ $.jqplot.TableLegendRenderer.call(this);
537
+ };
538
+
539
+ $.jqplot.PieLegendRenderer.prototype = new $.jqplot.TableLegendRenderer();
540
+ $.jqplot.PieLegendRenderer.prototype.constructor = $.jqplot.PieLegendRenderer;
541
+
542
+ /**
543
+ * Class: $.jqplot.PieLegendRenderer
544
+ * Legend Renderer specific to pie plots. Set by default
545
+ * when user creates a pie plot.
546
+ */
547
+ $.jqplot.PieLegendRenderer.prototype.init = function(options) {
548
+ // Group: Properties
549
+ //
550
+ // prop: numberRows
551
+ // Maximum number of rows in the legend. 0 or null for unlimited.
552
+ this.numberRows = null;
553
+ // prop: numberColumns
554
+ // Maximum number of columns in the legend. 0 or null for unlimited.
555
+ this.numberColumns = null;
556
+ $.extend(true, this, options);
557
+ };
558
+
559
+ // called with context of legend
560
+ $.jqplot.PieLegendRenderer.prototype.draw = function() {
561
+ var legend = this;
562
+ if (this.show) {
563
+ var series = this._series;
564
+
565
+
566
+ this._elem = $(document.createElement('table'));
567
+ this._elem.addClass('jqplot-table-legend');
568
+
569
+ var ss = {position:'absolute'};
570
+ if (this.background) {
571
+ ss['background'] = this.background;
572
+ }
573
+ if (this.border) {
574
+ ss['border'] = this.border;
575
+ }
576
+ if (this.fontSize) {
577
+ ss['fontSize'] = this.fontSize;
578
+ }
579
+ if (this.fontFamily) {
580
+ ss['fontFamily'] = this.fontFamily;
581
+ }
582
+ if (this.textColor) {
583
+ ss['textColor'] = this.textColor;
584
+ }
585
+ if (this.marginTop != null) {
586
+ ss['marginTop'] = this.marginTop;
587
+ }
588
+ if (this.marginBottom != null) {
589
+ ss['marginBottom'] = this.marginBottom;
590
+ }
591
+ if (this.marginLeft != null) {
592
+ ss['marginLeft'] = this.marginLeft;
593
+ }
594
+ if (this.marginRight != null) {
595
+ ss['marginRight'] = this.marginRight;
596
+ }
597
+
598
+ this._elem.css(ss);
599
+
600
+ // Pie charts legends don't go by number of series, but by number of data points
601
+ // in the series. Refactor things here for that.
602
+
603
+ var pad = false,
604
+ reverse = false,
605
+ nr,
606
+ nc;
607
+ var s = series[0];
608
+ var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors);
609
+
610
+ if (s.show) {
611
+ var pd = s.data;
612
+ if (this.numberRows) {
613
+ nr = this.numberRows;
614
+ if (!this.numberColumns){
615
+ nc = Math.ceil(pd.length/nr);
616
+ }
617
+ else{
618
+ nc = this.numberColumns;
619
+ }
620
+ }
621
+ else if (this.numberColumns) {
622
+ nc = this.numberColumns;
623
+ nr = Math.ceil(pd.length/this.numberColumns);
624
+ }
625
+ else {
626
+ nr = pd.length;
627
+ nc = 1;
628
+ }
629
+
630
+ var i, j;
631
+ var tr, td1, td2;
632
+ var lt, rs, color;
633
+ var idx = 0;
634
+ var div0, div1;
635
+
636
+ for (i=0; i<nr; i++) {
637
+ tr = $(document.createElement('tr'));
638
+ tr.addClass('jqplot-table-legend');
639
+
640
+ if (reverse){
641
+ tr.prependTo(this._elem);
642
+ }
643
+
644
+ else{
645
+ tr.appendTo(this._elem);
646
+ }
647
+
648
+ for (j=0; j<nc; j++) {
649
+ if (idx < pd.length){
650
+ lt = this.labels[idx] || pd[idx][0].toString();
651
+ color = colorGenerator.next();
652
+ if (!reverse){
653
+ if (i>0){
654
+ pad = true;
655
+ }
656
+ else{
657
+ pad = false;
658
+ }
659
+ }
660
+ else{
661
+ if (i == nr -1){
662
+ pad = false;
663
+ }
664
+ else{
665
+ pad = true;
666
+ }
667
+ }
668
+ rs = (pad) ? this.rowSpacing : '0';
669
+
670
+
671
+
672
+ td1 = $(document.createElement('td'));
673
+ td1.addClass('jqplot-table-legend jqplot-table-legend-swatch');
674
+ td1.css({textAlign: 'center', paddingTop: rs});
675
+
676
+ div0 = $(document.createElement('div'));
677
+ div0.addClass('jqplot-table-legend-swatch-outline');
678
+ div1 = $(document.createElement('div'));
679
+ div1.addClass('jqplot-table-legend-swatch');
680
+ div1.css({backgroundColor: color, borderColor: color});
681
+ td1.append(div0.append(div1));
682
+
683
+ td2 = $(document.createElement('td'));
684
+ td2.addClass('jqplot-table-legend jqplot-table-legend-label');
685
+ td2.css('paddingTop', rs);
686
+
687
+ if (this.escapeHtml){
688
+ td2.text(lt);
689
+ }
690
+ else {
691
+ td2.html(lt);
692
+ }
693
+ if (reverse) {
694
+ td2.prependTo(tr);
695
+ td1.prependTo(tr);
696
+ }
697
+ else {
698
+ td1.appendTo(tr);
699
+ td2.appendTo(tr);
700
+ }
701
+ pad = true;
702
+ }
703
+ idx++;
704
+ }
705
+ }
706
+ }
707
+ }
708
+ return this._elem;
709
+ };
710
+
711
+ $.jqplot.PieRenderer.prototype.handleMove = function(ev, gridpos, datapos, neighbor, plot) {
712
+ if (neighbor) {
713
+ var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
714
+ plot.target.trigger('jqplotDataMouseOver', ins);
715
+ if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
716
+ plot.target.trigger('jqplotDataHighlight', ins);
717
+ highlight (plot, ins[0], ins[1]);
718
+ }
719
+ }
720
+ else if (neighbor == null) {
721
+ unhighlight (plot);
722
+ }
723
+ };
724
+
725
+
726
+ // this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]);
727
+
728
+ // setup default renderers for axes and legend so user doesn't have to
729
+ // called with scope of plot
730
+ function preInit(target, data, options) {
731
+ options = options || {};
732
+ options.axesDefaults = options.axesDefaults || {};
733
+ options.legend = options.legend || {};
734
+ options.seriesDefaults = options.seriesDefaults || {};
735
+ // only set these if there is a pie series
736
+ var setopts = false;
737
+ if (options.seriesDefaults.renderer == $.jqplot.PieRenderer) {
738
+ setopts = true;
739
+ }
740
+ else if (options.series) {
741
+ for (var i=0; i < options.series.length; i++) {
742
+ if (options.series[i].renderer == $.jqplot.PieRenderer) {
743
+ setopts = true;
744
+ }
745
+ }
746
+ }
747
+
748
+ if (setopts) {
749
+ options.axesDefaults.renderer = $.jqplot.PieAxisRenderer;
750
+ options.legend.renderer = $.jqplot.PieLegendRenderer;
751
+ options.legend.preDraw = true;
752
+ options.seriesDefaults.pointLabels = {show: false};
753
+ }
754
+ }
755
+
756
+ function postInit(target, data, options) {
757
+ for (var i=0; i<this.series.length; i++) {
758
+ if (this.series[i].renderer.constructor == $.jqplot.PieRenderer) {
759
+ // don't allow mouseover and mousedown at same time.
760
+ if (this.series[i].highlightMouseOver) {
761
+ this.series[i].highlightMouseDown = false;
762
+ }
763
+ }
764
+ }
765
+ }
766
+
767
+ // called with scope of plot
768
+ function postParseOptions(options) {
769
+ for (var i=0; i<this.series.length; i++) {
770
+ this.series[i].seriesColors = this.seriesColors;
771
+ this.series[i].colorGenerator = $.jqplot.colorGenerator;
772
+ }
773
+ }
774
+
775
+ function highlight (plot, sidx, pidx) {
776
+ var s = plot.series[sidx];
777
+ var canvas = plot.plugins.pieRenderer.highlightCanvas;
778
+ canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height);
779
+ s._highlightedPoint = pidx;
780
+ plot.plugins.pieRenderer.highlightedSeriesIndex = sidx;
781
+ s.renderer.drawSlice.call(s, canvas._ctx, s._sliceAngles[pidx][0], s._sliceAngles[pidx][1], s.highlightColorGenerator.get(pidx), false);
782
+ }
783
+
784
+ function unhighlight (plot) {
785
+ var canvas = plot.plugins.pieRenderer.highlightCanvas;
786
+ canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height);
787
+ for (var i=0; i<plot.series.length; i++) {
788
+ plot.series[i]._highlightedPoint = null;
789
+ }
790
+ plot.plugins.pieRenderer.highlightedSeriesIndex = null;
791
+ plot.target.trigger('jqplotDataUnhighlight');
792
+ }
793
+
794
+ function handleMove(ev, gridpos, datapos, neighbor, plot) {
795
+ if (neighbor) {
796
+ var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
797
+ var evt1 = jQuery.Event('jqplotDataMouseOver');
798
+ evt1.pageX = ev.pageX;
799
+ evt1.pageY = ev.pageY;
800
+ plot.target.trigger(evt1, ins);
801
+ if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
802
+ var evt = jQuery.Event('jqplotDataHighlight');
803
+ evt.pageX = ev.pageX;
804
+ evt.pageY = ev.pageY;
805
+ plot.target.trigger(evt, ins);
806
+ highlight (plot, ins[0], ins[1]);
807
+ }
808
+ }
809
+ else if (neighbor == null) {
810
+ unhighlight (plot);
811
+ }
812
+ }
813
+
814
+ function handleMouseDown(ev, gridpos, datapos, neighbor, plot) {
815
+ if (neighbor) {
816
+ var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
817
+ if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) {
818
+ var evt = jQuery.Event('jqplotDataHighlight');
819
+ evt.pageX = ev.pageX;
820
+ evt.pageY = ev.pageY;
821
+ plot.target.trigger(evt, ins);
822
+ highlight (plot, ins[0], ins[1]);
823
+ }
824
+ }
825
+ else if (neighbor == null) {
826
+ unhighlight (plot);
827
+ }
828
+ }
829
+
830
+ function handleMouseUp(ev, gridpos, datapos, neighbor, plot) {
831
+ var idx = plot.plugins.pieRenderer.highlightedSeriesIndex;
832
+ if (idx != null && plot.series[idx].highlightMouseDown) {
833
+ unhighlight(plot);
834
+ }
835
+ }
836
+
837
+ function handleClick(ev, gridpos, datapos, neighbor, plot) {
838
+ if (neighbor) {
839
+ var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
840
+ var evt = jQuery.Event('jqplotDataClick');
841
+ evt.pageX = ev.pageX;
842
+ evt.pageY = ev.pageY;
843
+ plot.target.trigger(evt, ins);
844
+ }
845
+ }
846
+
847
+ function handleRightClick(ev, gridpos, datapos, neighbor, plot) {
848
+ if (neighbor) {
849
+ var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data];
850
+ var idx = plot.plugins.pieRenderer.highlightedSeriesIndex;
851
+ if (idx != null && plot.series[idx].highlightMouseDown) {
852
+ unhighlight(plot);
853
+ }
854
+ var evt = jQuery.Event('jqplotDataRightClick');
855
+ evt.pageX = ev.pageX;
856
+ evt.pageY = ev.pageY;
857
+ plot.target.trigger(evt, ins);
858
+ }
859
+ }
860
+
861
+ // called within context of plot
862
+ // create a canvas which we can draw on.
863
+ // insert it before the eventCanvas, so eventCanvas will still capture events.
864
+ function postPlotDraw() {
865
+ // Memory Leaks patch
866
+ if (this.plugins.pieRenderer && this.plugins.pieRenderer.highlightCanvas) {
867
+ this.plugins.pieRenderer.highlightCanvas.resetCanvas();
868
+ this.plugins.pieRenderer.highlightCanvas = null;
869
+ }
870
+
871
+ this.plugins.pieRenderer = {highlightedSeriesIndex:null};
872
+ this.plugins.pieRenderer.highlightCanvas = new $.jqplot.GenericCanvas();
873
+
874
+ // do we have any data labels? if so, put highlight canvas before those
875
+ var labels = $(this.targetId+' .jqplot-data-label');
876
+ if (labels.length) {
877
+ $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this));
878
+ }
879
+ // else put highlight canvas before event canvas.
880
+ else {
881
+ this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this));
882
+ }
883
+
884
+ var hctx = this.plugins.pieRenderer.highlightCanvas.setContext();
885
+ this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); });
886
+ }
887
+
888
+ $.jqplot.preInitHooks.push(preInit);
889
+
890
+ $.jqplot.PieTickRenderer = function() {
891
+ $.jqplot.AxisTickRenderer.call(this);
892
+ };
893
+
894
+ $.jqplot.PieTickRenderer.prototype = new $.jqplot.AxisTickRenderer();
895
+ $.jqplot.PieTickRenderer.prototype.constructor = $.jqplot.PieTickRenderer;
896
+
897
+ })(jQuery);
898
+
899
+