jquery_cheats 3.0.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/app/assets/javascripts/{jqueryCheats.js → jquery_cheats/jquery_cheats.js} +0 -0
  2. data/jquery_cheats.gemspec +1 -1
  3. data/lib/jquery_cheats/engine.rb +6 -0
  4. data/lib/{railtie.rb → jquery_cheats/railtie.rb} +0 -0
  5. data/lib/jquery_cheats.rb +2 -2
  6. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/excanvas.js +1438 -1438
  7. data/vendor/assets/javascripts/jquery_cheats/jqplot/index.js +1 -0
  8. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/jquery.jqplot.js +10901 -10901
  9. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.BezierCurveRenderer.js +311 -311
  10. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.BezierCurveRenderer.min.js +56 -56
  11. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.barRenderer.js +746 -746
  12. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.barRenderer.min.js +56 -56
  13. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.blockRenderer.js +233 -233
  14. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.blockRenderer.min.js +56 -56
  15. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.bubbleRenderer.js +753 -753
  16. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.bubbleRenderer.min.js +56 -56
  17. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.canvasAxisLabelRenderer.js +201 -201
  18. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.canvasAxisLabelRenderer.min.js +56 -56
  19. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.canvasAxisTickRenderer.js +241 -241
  20. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.canvasAxisTickRenderer.min.js +56 -56
  21. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.canvasOverlay.js +863 -863
  22. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.canvasOverlay.min.js +56 -56
  23. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.canvasTextRenderer.js +447 -447
  24. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.canvasTextRenderer.min.js +56 -56
  25. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.categoryAxisRenderer.js +635 -635
  26. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.categoryAxisRenderer.min.js +56 -56
  27. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.ciParser.js +114 -114
  28. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.ciParser.min.js +56 -56
  29. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.cursor.js +1092 -1092
  30. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.cursor.min.js +56 -56
  31. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.dateAxisRenderer.js +702 -702
  32. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.dateAxisRenderer.min.js +56 -56
  33. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.donutRenderer.js +799 -799
  34. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.donutRenderer.min.js +56 -56
  35. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.dragable.js +223 -223
  36. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.dragable.min.js +56 -56
  37. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.enhancedLegendRenderer.js +240 -240
  38. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.enhancedLegendRenderer.min.js +56 -56
  39. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.funnelRenderer.js +937 -937
  40. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.funnelRenderer.min.js +56 -56
  41. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.highlighter.js +453 -453
  42. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.highlighter.min.js +56 -56
  43. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.json2.js +475 -475
  44. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.json2.min.js +56 -56
  45. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.logAxisRenderer.js +527 -527
  46. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.logAxisRenderer.min.js +56 -56
  47. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.mekkoAxisRenderer.js +610 -610
  48. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.mekkoAxisRenderer.min.js +56 -56
  49. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.mekkoRenderer.js +435 -435
  50. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.mekkoRenderer.min.js +56 -56
  51. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.meterGaugeRenderer.js +1028 -1028
  52. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.meterGaugeRenderer.min.js +56 -56
  53. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.ohlcRenderer.js +371 -371
  54. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.ohlcRenderer.min.js +56 -56
  55. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pieRenderer.js +898 -898
  56. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pieRenderer.min.js +56 -56
  57. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pointLabels.js +361 -361
  58. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pointLabels.min.js +56 -56
  59. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pyramidAxisRenderer.js +729 -729
  60. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pyramidAxisRenderer.min.js +56 -56
  61. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pyramidGridRenderer.js +422 -422
  62. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pyramidGridRenderer.min.js +56 -56
  63. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pyramidRenderer.js +489 -489
  64. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.pyramidRenderer.min.js +56 -56
  65. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.trendline.js +221 -221
  66. data/vendor/assets/javascripts/{jqplot → jquery_cheats/jqplot}/plugins/jqplot.trendline.min.js +56 -56
  67. data/vendor/assets/stylesheets/{jquery.jqplot.css → jquery_cheats/jquery.jqplot.css} +259 -259
  68. metadata +68 -67
  69. data/lib/engine.rb +0 -7
@@ -1,899 +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
-
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
899