rgraph-rails 1.0.5 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/.travis.yml +0 -1
- data/README.md +3 -3
- data/lib/rgraph-rails/version.rb +1 -1
- data/vendor/assets/javascripts/RGraph.bar.js +239 -3764
- data/vendor/assets/javascripts/RGraph.bipolar.js +115 -1986
- data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -399
- data/vendor/assets/javascripts/RGraph.common.context.js +30 -600
- data/vendor/assets/javascripts/RGraph.common.core.js +403 -5187
- data/vendor/assets/javascripts/RGraph.common.csv.js +19 -275
- data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -454
- data/vendor/assets/javascripts/RGraph.common.dynamic.js +84 -1189
- data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1548
- data/vendor/assets/javascripts/RGraph.common.key.js +54 -755
- data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -567
- data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -356
- data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -614
- data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -223
- data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
- data/vendor/assets/javascripts/RGraph.drawing.background.js +35 -620
- data/vendor/assets/javascripts/RGraph.drawing.circle.js +35 -576
- data/vendor/assets/javascripts/RGraph.drawing.image.js +52 -807
- data/vendor/assets/javascripts/RGraph.drawing.marker1.js +41 -717
- data/vendor/assets/javascripts/RGraph.drawing.marker2.js +37 -668
- data/vendor/assets/javascripts/RGraph.drawing.marker3.js +36 -563
- data/vendor/assets/javascripts/RGraph.drawing.poly.js +40 -608
- data/vendor/assets/javascripts/RGraph.drawing.rect.js +35 -597
- data/vendor/assets/javascripts/RGraph.drawing.text.js +34 -642
- data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -809
- data/vendor/assets/javascripts/RGraph.drawing.yaxis.js +51 -856
- data/vendor/assets/javascripts/RGraph.fuel.js +58 -964
- data/vendor/assets/javascripts/RGraph.funnel.js +55 -984
- data/vendor/assets/javascripts/RGraph.gantt.js +75 -1241
- data/vendor/assets/javascripts/RGraph.gauge.js +87 -1397
- data/vendor/assets/javascripts/RGraph.hbar.js +143 -2376
- data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1397
- data/vendor/assets/javascripts/RGraph.line.js +241 -4162
- data/vendor/assets/javascripts/RGraph.meter.js +74 -1278
- metadata +3 -30
- data/vendor/assets/images/bg.png +0 -0
- data/vendor/assets/images/bullet.png +0 -0
- data/vendor/assets/images/facebook-large.png +0 -0
- data/vendor/assets/images/google-plus-large.png +0 -0
- data/vendor/assets/images/logo.png +0 -0
- data/vendor/assets/images/meter-image-sd-needle.png +0 -0
- data/vendor/assets/images/meter-image-sd.png +0 -0
- data/vendor/assets/images/meter-sketch-needle.png +0 -0
- data/vendor/assets/images/meter-sketch.png +0 -0
- data/vendor/assets/images/odometer-background.png +0 -0
- data/vendor/assets/images/rgraph.jpg +0 -0
- data/vendor/assets/images/title.png +0 -0
- data/vendor/assets/images/twitter-large.png +0 -0
- data/vendor/assets/javascripts/RGraph.modaldialog.js +0 -301
- data/vendor/assets/javascripts/RGraph.odo.js +0 -1265
- data/vendor/assets/javascripts/RGraph.pie.js +0 -2272
- data/vendor/assets/javascripts/RGraph.radar.js +0 -1847
- data/vendor/assets/javascripts/RGraph.rose.js +0 -1877
- data/vendor/assets/javascripts/RGraph.rscatter.js +0 -1425
- data/vendor/assets/javascripts/RGraph.scatter.js +0 -2970
- data/vendor/assets/javascripts/RGraph.semicircularprogress.js +0 -1015
- data/vendor/assets/javascripts/RGraph.thermometer.js +0 -1129
- data/vendor/assets/javascripts/RGraph.vprogress.js +0 -1452
- data/vendor/assets/javascripts/RGraph.waterfall.js +0 -1252
- data/vendor/assets/javascripts/financial-data.js +0 -1067
- data/vendor/assets/stylesheets/ModalDialog.css +0 -90
- data/vendor/assets/stylesheets/animations.css +0 -3347
- data/vendor/assets/stylesheets/website.css +0 -446
@@ -1,1425 +0,0 @@
|
|
1
|
-
// version: 2016-06-04
|
2
|
-
/**
|
3
|
-
* o--------------------------------------------------------------------------------o
|
4
|
-
* | This file is part of the RGraph package - you can learn more at: |
|
5
|
-
* | |
|
6
|
-
* | http://www.rgraph.net |
|
7
|
-
* | |
|
8
|
-
* | RGraph is dual licensed under the Open Source GPL (General Public License) |
|
9
|
-
* | v2.0 license and a commercial license which means that you're not bound by |
|
10
|
-
* | the terms of the GPL. The commercial license is just 99 GBP and you can |
|
11
|
-
* | read about it here: |
|
12
|
-
* | http://www.rgraph.net/license |
|
13
|
-
* o--------------------------------------------------------------------------------o
|
14
|
-
*/
|
15
|
-
|
16
|
-
RGraph = window.RGraph || {isRGraph: true};
|
17
|
-
|
18
|
-
/**
|
19
|
-
* The chart constuctor
|
20
|
-
*
|
21
|
-
* @param object canvas
|
22
|
-
* @param array data
|
23
|
-
*/
|
24
|
-
RGraph.RScatter =
|
25
|
-
RGraph.Rscatter = function (conf)
|
26
|
-
{
|
27
|
-
/**
|
28
|
-
* Allow for object config style
|
29
|
-
*/
|
30
|
-
if ( typeof conf === 'object'
|
31
|
-
&& typeof conf.data === 'object'
|
32
|
-
&& typeof conf.id === 'string') {
|
33
|
-
|
34
|
-
var parseConfObjectForOptions = true; // Set this so the config is parsed (at the end of the constructor)
|
35
|
-
|
36
|
-
this.data = new Array(conf.data.length);
|
37
|
-
|
38
|
-
// Store the data set(s)
|
39
|
-
this.data = RGraph.arrayClone(conf.data);
|
40
|
-
|
41
|
-
|
42
|
-
// Account for just one dataset being given
|
43
|
-
if (typeof conf.data === 'object' && typeof conf.data[0] === 'object' && typeof conf.data[0][0] === 'number') {
|
44
|
-
var tmp = RGraph.arrayClone(conf.data);
|
45
|
-
conf.data = new Array();
|
46
|
-
conf.data[0] = RGraph.arrayClone(tmp);
|
47
|
-
|
48
|
-
this.data = RGraph.arrayClone(conf.data);
|
49
|
-
}
|
50
|
-
|
51
|
-
} else {
|
52
|
-
|
53
|
-
var conf = {id: conf};
|
54
|
-
conf.data = arguments[1];
|
55
|
-
|
56
|
-
|
57
|
-
this.data = [];
|
58
|
-
|
59
|
-
// Handle multiple datasets being given as one argument
|
60
|
-
if (arguments[1][0] && arguments[1][0][0] && typeof arguments[1][0][0] == 'object') {
|
61
|
-
// Store the data set(s)
|
62
|
-
for (var i=0; i<arguments[1].length; ++i) {
|
63
|
-
this.data[i] = arguments[1][i];
|
64
|
-
}
|
65
|
-
|
66
|
-
// Handle multiple data sets being supplied as seperate arguments
|
67
|
-
} else {
|
68
|
-
|
69
|
-
// Store the data set(s)
|
70
|
-
for (var i=1; i<arguments.length; ++i) {
|
71
|
-
this.data[i - 1] = RGraph.arrayClone(arguments[i]);
|
72
|
-
}
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
this.id = conf.id
|
80
|
-
this.canvas = document.getElementById(this.id)
|
81
|
-
this.context = this.canvas.getContext ? this.canvas.getContext("2d") : null;
|
82
|
-
this.canvas.__object__ = this;
|
83
|
-
this.type = 'rscatter';
|
84
|
-
this.hasTooltips = false;
|
85
|
-
this.isRGraph = true;
|
86
|
-
this.uid = RGraph.CreateUID();
|
87
|
-
this.canvas.uid = this.canvas.uid ? this.canvas.uid : RGraph.CreateUID();
|
88
|
-
this.colorsParsed = false;
|
89
|
-
this.coordsText = [];
|
90
|
-
this.original_colors = [];
|
91
|
-
this.firstDraw = true; // After the first draw this will be false
|
92
|
-
|
93
|
-
|
94
|
-
this.centerx = 0;
|
95
|
-
this.centery = 0;
|
96
|
-
this.radius = 0;
|
97
|
-
this.max = 0;
|
98
|
-
|
99
|
-
// Convert all of the data pieces to numbers
|
100
|
-
for (var i=0; i<this.data.length; ++i) {
|
101
|
-
for (var j=0; j<this.data[i].length; ++j) {
|
102
|
-
if (typeof this.data[i][j][0] === 'string') {
|
103
|
-
this.data[i][j][0] = parseFloat(this.data[i][j][0]);
|
104
|
-
}
|
105
|
-
|
106
|
-
if (typeof this.data[i][j][1] === 'string') {
|
107
|
-
this.data[i][j][1] = parseFloat(this.data[i][j][1]);
|
108
|
-
}
|
109
|
-
}
|
110
|
-
}
|
111
|
-
|
112
|
-
|
113
|
-
this.properties =
|
114
|
-
{
|
115
|
-
'chart.background.color': 'transparent',
|
116
|
-
'chart.background.grid': true,
|
117
|
-
'chart.background.grid.diagonals': true,
|
118
|
-
'chart.background.grid.diagonals.count': null,
|
119
|
-
'chart.background.grid.radials': true,
|
120
|
-
'chart.background.grid.radials.count': null,
|
121
|
-
'chart.background.grid.linewidth': 1,
|
122
|
-
'chart.background.grid.color': '#ccc',
|
123
|
-
'chart.radius': null,
|
124
|
-
'chart.colors': [], // This is used internally for the key
|
125
|
-
'chart.colors.default': 'black',
|
126
|
-
'chart.gutter.left': 25,
|
127
|
-
'chart.gutter.right': 25,
|
128
|
-
'chart.gutter.top': 25,
|
129
|
-
'chart.gutter.bottom': 25,
|
130
|
-
'chart.title': '',
|
131
|
-
'chart.title.background': null,
|
132
|
-
'chart.title.hpos': null,
|
133
|
-
'chart.title.vpos': null,
|
134
|
-
'chart.title.bold': true,
|
135
|
-
'chart.title.font': null,
|
136
|
-
'chart.title.x': null,
|
137
|
-
'chart.title.y': null,
|
138
|
-
'chart.title.halign': null,
|
139
|
-
'chart.title.valign': null,
|
140
|
-
'chart.labels': null,
|
141
|
-
'chart.labels.color': null,
|
142
|
-
'chart.labels.axes': 'nsew',
|
143
|
-
'chart.labels.axes.background': 'rgba(255,255,255,0.8)',
|
144
|
-
'chart.labels.count': 5,
|
145
|
-
'chart.text.color': 'black',
|
146
|
-
'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
|
147
|
-
'chart.text.size': 12,
|
148
|
-
'chart.text.accessible': true,
|
149
|
-
'chart.text.accessible.overflow': 'visible',
|
150
|
-
'chart.text.accessible.pointerevents': false,
|
151
|
-
'chart.key': null,
|
152
|
-
'chart.key.background': 'white',
|
153
|
-
'chart.key.position': 'graph',
|
154
|
-
'chart.key.halign': 'right',
|
155
|
-
'chart.key.shadow': false,
|
156
|
-
'chart.key.shadow.color': '#666',
|
157
|
-
'chart.key.shadow.blur': 3,
|
158
|
-
'chart.key.shadow.offsetx': 2,
|
159
|
-
'chart.key.shadow.offsety': 2,
|
160
|
-
'chart.key.position.gutter.boxed':false,
|
161
|
-
'chart.key.position.x': null,
|
162
|
-
'chart.key.position.y': null,
|
163
|
-
'chart.key.color.shape': 'square',
|
164
|
-
'chart.key.rounded': true,
|
165
|
-
'chart.key.linewidth': 1,
|
166
|
-
'chart.key.colors': null,
|
167
|
-
'chart.key.interactive': false,
|
168
|
-
'chart.key.interactive.highlight.chart.fill':'rgba(255,0,0,0.9)',
|
169
|
-
'chart.key.interactive.highlight.label':'rgba(255,0,0,0.2)',
|
170
|
-
'chart.key.text.color': 'black',
|
171
|
-
'chart.contextmenu': null,
|
172
|
-
'chart.tooltips': null,
|
173
|
-
'chart.tooltips.event': 'onmousemove',
|
174
|
-
'chart.tooltips.effect': 'fade',
|
175
|
-
'chart.tooltips.css.class': 'RGraph_tooltip',
|
176
|
-
'chart.tooltips.highlight': true,
|
177
|
-
'chart.tooltips.hotspot': 3,
|
178
|
-
'chart.tooltips.coords.page': false,
|
179
|
-
'chart.annotatable': false,
|
180
|
-
'chart.annotate.color': 'black',
|
181
|
-
'chart.zoom.factor': 1.5,
|
182
|
-
'chart.zoom.fade.in': true,
|
183
|
-
'chart.zoom.fade.out': true,
|
184
|
-
'chart.zoom.hdir': 'right',
|
185
|
-
'chart.zoom.vdir': 'down',
|
186
|
-
'chart.zoom.frames': 25,
|
187
|
-
'chart.zoom.delay': 16.666,
|
188
|
-
'chart.zoom.shadow': true,
|
189
|
-
'chart.zoom.background': true,
|
190
|
-
'chart.zoom.action': 'zoom',
|
191
|
-
'chart.resizable': false,
|
192
|
-
'chart.resize.handle.background': null,
|
193
|
-
'chart.ymax': null,
|
194
|
-
'chart.ymin': 0,
|
195
|
-
'chart.tickmarks': 'cross',
|
196
|
-
'chart.ticksize': 3,
|
197
|
-
'chart.scale.decimals': null,
|
198
|
-
'chart.scale.point': '.',
|
199
|
-
'chart.scale.thousand': ',',
|
200
|
-
'chart.scale.round': false,
|
201
|
-
'chart.scale.zerostart': true,
|
202
|
-
'chart.units.pre': '',
|
203
|
-
'chart.units.post': '',
|
204
|
-
'chart.events.mousemove': null,
|
205
|
-
'chart.events.click': null,
|
206
|
-
'chart.highlight.stroke': 'transparent',
|
207
|
-
'chart.highlight.fill': 'rgba(255,255,255,0.7)',
|
208
|
-
'chart.highlight.point.radius': 3,
|
209
|
-
'chart.axes.color': 'black',
|
210
|
-
'chart.axes.numticks': null,
|
211
|
-
'chart.axes.caps': true,
|
212
|
-
'chart.segment.highlight': false,
|
213
|
-
'chart.segment.highlight.count': null,
|
214
|
-
'chart.segment.highlight.fill': 'rgba(0,255,0,0.5)',
|
215
|
-
'chart.segment.highlight.stroke':'rgba(0,0,0,0)',
|
216
|
-
'chart.line': false,
|
217
|
-
'chart.line.close': false,
|
218
|
-
'chart.line.linewidth': 1,
|
219
|
-
'chart.line.colors': ['black'],
|
220
|
-
'chart.line.shadow': false,
|
221
|
-
'chart.line.shadow.color': 'black',
|
222
|
-
'chart.line.shadow.blur': 2,
|
223
|
-
'chart.line.shadow.offsetx': 3,
|
224
|
-
'chart.line.shadow.offsety': 3,
|
225
|
-
'chart.clearto': 'rgba(0,0,0,0)'
|
226
|
-
}
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
/**
|
232
|
-
* Create the $ objects so that functions can be added to them
|
233
|
-
*/
|
234
|
-
|
235
|
-
for (var i=0,idx=0; i<this.data.length; ++i) {
|
236
|
-
for (var j=0,len=this.data[i].length; j<len; j+=1,idx+=1) {
|
237
|
-
this['$' + idx] = {}
|
238
|
-
}
|
239
|
-
}
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
/**
|
246
|
-
* Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
|
247
|
-
* done already
|
248
|
-
*/
|
249
|
-
if (!this.canvas.__rgraph_aa_translated__) {
|
250
|
-
this.context.translate(0.5,0.5);
|
251
|
-
|
252
|
-
this.canvas.__rgraph_aa_translated__ = true;
|
253
|
-
}
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
// Short variable names
|
258
|
-
var RG = RGraph,
|
259
|
-
ca = this.canvas,
|
260
|
-
co = ca.getContext('2d'),
|
261
|
-
prop = this.properties,
|
262
|
-
pa2 = RG.path2,
|
263
|
-
win = window,
|
264
|
-
doc = document,
|
265
|
-
ma = Math
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
/**
|
270
|
-
* "Decorate" the object with the generic effects if the effects library has been included
|
271
|
-
*/
|
272
|
-
if (RG.Effects && typeof RG.Effects.decorate === 'function') {
|
273
|
-
RG.Effects.decorate(this);
|
274
|
-
}
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
/**
|
280
|
-
* A simple setter
|
281
|
-
*
|
282
|
-
* @param string name The name of the property to set
|
283
|
-
* @param string value The value of the property
|
284
|
-
*/
|
285
|
-
this.set =
|
286
|
-
this.Set = function (name, value)
|
287
|
-
{
|
288
|
-
var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
|
289
|
-
|
290
|
-
/**
|
291
|
-
* the number of arguments is only one and it's an
|
292
|
-
* object - parse it for configuration data and return.
|
293
|
-
*/
|
294
|
-
if (arguments.length === 1 && typeof name === 'object') {
|
295
|
-
RG.parseObjectStyleConfig(this, name);
|
296
|
-
return this;
|
297
|
-
}
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
/**
|
302
|
-
* This should be done first - prepend the property name with "chart." if necessary
|
303
|
-
*/
|
304
|
-
if (name.substr(0,6) != 'chart.') {
|
305
|
-
name = 'chart.' + name;
|
306
|
-
}
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
// Convert uppercase letters to dot+lower case letter
|
312
|
-
while(name.match(/([A-Z])/)) {
|
313
|
-
name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
|
314
|
-
}
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
//
|
323
|
-
// Change chart.segments.highlight* to chart.segment.highlight (no plural)
|
324
|
-
//
|
325
|
-
if (name === 'chart.segments.highlight') name = 'chart.segment.highlight';
|
326
|
-
if (name === 'chart.segments.highlight.count') name = 'chart.segment.highlight.count';
|
327
|
-
if (name === 'chart.segments.highlight.fill') name = 'chart.segment.highlight.fill';
|
328
|
-
if (name === 'chart.segments.highlight.stroke') name = 'chart.segment.highlight.stroke';
|
329
|
-
|
330
|
-
prop[name.toLowerCase()] = value;
|
331
|
-
|
332
|
-
return this;
|
333
|
-
};
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
/**
|
339
|
-
* A simple getter
|
340
|
-
*
|
341
|
-
* @param string name The name of the property to get
|
342
|
-
*/
|
343
|
-
this.get =
|
344
|
-
this.Get = function (name)
|
345
|
-
{
|
346
|
-
/**
|
347
|
-
* This should be done first - prepend the property name with "chart." if necessary
|
348
|
-
*/
|
349
|
-
if (name.substr(0,6) != 'chart.') {
|
350
|
-
name = 'chart.' + name;
|
351
|
-
}
|
352
|
-
|
353
|
-
// Convert uppercase letters to dot+lower case letter
|
354
|
-
name = name.replace(/([A-Z])/g, function (str)
|
355
|
-
{
|
356
|
-
return '.' + String(RegExp.$1).toLowerCase()
|
357
|
-
});
|
358
|
-
|
359
|
-
return prop[name.toLowerCase()];
|
360
|
-
};
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
/**
|
366
|
-
* This method draws the rose chart
|
367
|
-
*/
|
368
|
-
this.draw =
|
369
|
-
this.Draw = function ()
|
370
|
-
{
|
371
|
-
/**
|
372
|
-
* Fire the onbeforedraw event
|
373
|
-
*/
|
374
|
-
RG.FireCustomEvent(this, 'onbeforedraw');
|
375
|
-
|
376
|
-
|
377
|
-
/**
|
378
|
-
* This doesn't affect the chart, but is used for compatibility
|
379
|
-
*/
|
380
|
-
this.gutterLeft = prop['chart.gutter.left'];
|
381
|
-
this.gutterRight = prop['chart.gutter.right'];
|
382
|
-
this.gutterTop = prop['chart.gutter.top'];
|
383
|
-
this.gutterBottom = prop['chart.gutter.bottom'];
|
384
|
-
|
385
|
-
// Calculate the radius
|
386
|
-
this.radius = (Math.min(ca.width - this.gutterLeft - this.gutterRight, ca.height - this.gutterTop - this.gutterBottom) / 2);
|
387
|
-
this.centerx = ((ca.width - this.gutterLeft - this.gutterRight) / 2) + this.gutterLeft;
|
388
|
-
this.centery = ((ca.height - this.gutterTop - this.gutterBottom) / 2) + this.gutterTop;
|
389
|
-
this.coords = [];
|
390
|
-
this.coords2 = [];
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
/**
|
395
|
-
* Stop this growing uncontrollably
|
396
|
-
*/
|
397
|
-
this.coordsText = [];
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
/**
|
403
|
-
* If there's a user specified radius/centerx/centery, use them
|
404
|
-
*/
|
405
|
-
if (typeof(prop['chart.centerx']) == 'number') this.centerx = prop['chart.centerx'];
|
406
|
-
if (typeof(prop['chart.centery']) == 'number') this.centery = prop['chart.centery'];
|
407
|
-
if (typeof(prop['chart.radius']) == 'number') this.radius = prop['chart.radius'];
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
/**
|
412
|
-
* Parse the colors for gradients. Its down here so that the center X/Y can be used
|
413
|
-
*/
|
414
|
-
if (!this.colorsParsed) {
|
415
|
-
|
416
|
-
this.parseColors();
|
417
|
-
|
418
|
-
// Don't want to do this again
|
419
|
-
this.colorsParsed = true;
|
420
|
-
}
|
421
|
-
|
422
|
-
|
423
|
-
/**
|
424
|
-
* Work out the scale
|
425
|
-
*/
|
426
|
-
var max = prop['chart.ymax'];
|
427
|
-
var min = prop['chart.ymin'];
|
428
|
-
|
429
|
-
if (typeof(max) == 'number') {
|
430
|
-
this.max = max;
|
431
|
-
this.scale2 = RG.getScale2(this, {
|
432
|
-
'max':max,
|
433
|
-
'min':min,
|
434
|
-
'strict':true,
|
435
|
-
'scale.decimals':Number(prop['chart.scale.decimals']),
|
436
|
-
'scale.point':prop['chart.scale.point'],
|
437
|
-
'scale.thousand':prop['chart.scale.thousand'],
|
438
|
-
'scale.round':prop['chart.scale.round'],
|
439
|
-
'units.pre':prop['chart.units.pre'],
|
440
|
-
'units.post':prop['chart.units.post'],
|
441
|
-
'ylabels.count':prop['chart.labels.count']
|
442
|
-
});
|
443
|
-
} else {
|
444
|
-
|
445
|
-
for (var i=0; i<this.data.length; i+=1) {
|
446
|
-
for (var j=0,len=this.data[i].length; j<len; j+=1) {
|
447
|
-
this.max = Math.max(this.max, this.data[i][j][1]);
|
448
|
-
}
|
449
|
-
}
|
450
|
-
|
451
|
-
this.min = prop['chart.ymin'];
|
452
|
-
|
453
|
-
this.scale2 = RG.getScale2(this, {
|
454
|
-
'max':this.max,
|
455
|
-
'min':min,
|
456
|
-
'scale.decimals':Number(prop['chart.scale.decimals']),
|
457
|
-
'scale.point':prop['chart.scale.point'],
|
458
|
-
'scale.thousand':prop['chart.scale.thousand'],
|
459
|
-
'scale.round':prop['chart.scale.round'],
|
460
|
-
'units.pre':prop['chart.units.pre'],
|
461
|
-
'units.post':prop['chart.units.post'],
|
462
|
-
'ylabels.count':prop['chart.labels.count']
|
463
|
-
});
|
464
|
-
this.max = this.scale2.max;
|
465
|
-
}
|
466
|
-
|
467
|
-
/**
|
468
|
-
* Change the centerx marginally if the key is defined
|
469
|
-
*/
|
470
|
-
if (prop['chart.key'] && prop['chart.key'].length > 0 && prop['chart.key'].length >= 3) {
|
471
|
-
this.centerx = this.centerx - prop['chart.gutter.right'] + 5;
|
472
|
-
}
|
473
|
-
|
474
|
-
/**
|
475
|
-
* Populate the colors array for the purposes of generating the key
|
476
|
-
*/
|
477
|
-
if (typeof(prop['chart.key']) == 'object' && RG.is_array(prop['chart.key']) && prop['chart.key'][0]) {
|
478
|
-
|
479
|
-
// Reset the colors array
|
480
|
-
prop['chart.colors'] = [];
|
481
|
-
|
482
|
-
for (var i=0; i<this.data.length; i+=1) {
|
483
|
-
for (var j=0,len=this.data[i].length; j<len; j+=1) {
|
484
|
-
if (typeof this.data[i][j][2] == 'string') {
|
485
|
-
prop['chart.colors'].push(this.data[i][j][2]);
|
486
|
-
}
|
487
|
-
}
|
488
|
-
}
|
489
|
-
}
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
/**
|
495
|
-
* Populate the chart.tooltips array
|
496
|
-
*/
|
497
|
-
this.Set('chart.tooltips', []);
|
498
|
-
|
499
|
-
for (var i=0; i<this.data.length; i+=1) {
|
500
|
-
for (var j=0,len=this.data[i].length; j<len; j+=1) {
|
501
|
-
if (typeof this.data[i][j][3] == 'string') {
|
502
|
-
prop['chart.tooltips'].push(this.data[i][j][3]);
|
503
|
-
}
|
504
|
-
}
|
505
|
-
}
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
// This resets the chart drawing state
|
510
|
-
co.beginPath();
|
511
|
-
|
512
|
-
this.DrawBackground();
|
513
|
-
this.DrawRscatter();
|
514
|
-
this.DrawLabels();
|
515
|
-
|
516
|
-
/**
|
517
|
-
* Setup the context menu if required
|
518
|
-
*/
|
519
|
-
if (prop['chart.contextmenu']) {
|
520
|
-
RG.ShowContext(this);
|
521
|
-
}
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
// Draw the title if any has been set
|
526
|
-
if (prop['chart.title']) {
|
527
|
-
RG.DrawTitle(
|
528
|
-
this,
|
529
|
-
prop['chart.title'],
|
530
|
-
this.centery - this.radius - 10,
|
531
|
-
this.centerx,
|
532
|
-
prop['chart.title.size'] ? prop['chart.title.size'] : prop['chart.text.size'] + 2
|
533
|
-
);
|
534
|
-
}
|
535
|
-
|
536
|
-
|
537
|
-
/**
|
538
|
-
* This function enables resizing
|
539
|
-
*/
|
540
|
-
if (prop['chart.resizable']) {
|
541
|
-
RG.AllowResizing(this);
|
542
|
-
}
|
543
|
-
|
544
|
-
|
545
|
-
/**
|
546
|
-
* This installs the event listeners
|
547
|
-
*/
|
548
|
-
RG.InstallEventListeners(this);
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
//
|
556
|
-
// Allow the segments to be highlighted
|
557
|
-
//
|
558
|
-
if (prop['chart.segment.highlight']) {
|
559
|
-
RG.allowSegmentHighlight({
|
560
|
-
object: this,
|
561
|
-
|
562
|
-
// This is duplicated in the drawBackground function
|
563
|
-
count: typeof prop['chart.segment.highlight.count'] === 'number' ? prop['chart.segment.highlight.count'] : ((prop['chart.background.grid.diagonals.count'] ? prop['chart.background.grid.diagonals.count'] : (prop['chart.labels'] ? prop['chart.labels'].length : 8))),
|
564
|
-
|
565
|
-
fill: prop['chart.segment.highlight.fill'],
|
566
|
-
stroke: prop['chart.segment.highlight.stroke']
|
567
|
-
});
|
568
|
-
}
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
/**
|
574
|
-
* Fire the onfirstdraw event
|
575
|
-
*/
|
576
|
-
if (this.firstDraw) {
|
577
|
-
RG.fireCustomEvent(this, 'onfirstdraw');
|
578
|
-
this.firstDraw = false;
|
579
|
-
this.firstDrawFunc();
|
580
|
-
}
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
/**
|
586
|
-
* Fire the RGraph ondraw event
|
587
|
-
*/
|
588
|
-
RG.FireCustomEvent(this, 'ondraw');
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
return this;
|
594
|
-
};
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
/**
|
600
|
-
* This method draws the rscatter charts background
|
601
|
-
*/
|
602
|
-
this.drawBackground =
|
603
|
-
this.DrawBackground = function ()
|
604
|
-
{
|
605
|
-
//
|
606
|
-
// Draw the background color first
|
607
|
-
//
|
608
|
-
if (prop['chart.background.color'] != 'transparent') {
|
609
|
-
pa2(co, ['b','a', this.centerx, this.centery, this.radius, 0, 2 * ma.PI, -1, 'f', prop['chart.background.color']]);
|
610
|
-
}
|
611
|
-
|
612
|
-
|
613
|
-
var gridEnabled = prop['chart.background.grid'];
|
614
|
-
|
615
|
-
|
616
|
-
if (gridEnabled) {
|
617
|
-
co.lineWidth = prop['chart.background.grid.linewidth'];
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
// Draw the background grey circles
|
622
|
-
if (prop['chart.background.grid.radials']) {
|
623
|
-
|
624
|
-
co.strokeStyle = prop['chart.background.grid.color'];
|
625
|
-
|
626
|
-
if (RG.isNull(prop['chart.background.grid.radials.count'])) {
|
627
|
-
prop['chart.background.grid.radials.count'] = prop['chart.labels.count'];
|
628
|
-
}
|
629
|
-
|
630
|
-
// Radius must be greater than 0 for Opera to work
|
631
|
-
|
632
|
-
var r = this.radius / prop['chart.background.grid.radials.count'];
|
633
|
-
|
634
|
-
for (var i=0,len=this.radius; i<=len; i+=r) {
|
635
|
-
|
636
|
-
// Radius must be greater than 0 for Opera to work
|
637
|
-
co.arc(this.centerx, this.centery, i, 0, RG.TWOPI, 0);
|
638
|
-
}
|
639
|
-
co.stroke();
|
640
|
-
}
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
// Draw the background lines that go from the center outwards
|
649
|
-
if (prop['chart.background.grid.diagonals']) {
|
650
|
-
|
651
|
-
co.strokeStyle = prop['chart.background.grid.color'];
|
652
|
-
|
653
|
-
co.beginPath();
|
654
|
-
|
655
|
-
// This is duplicated in the allowSegmentHighlight call
|
656
|
-
var inc = 360 / ((prop['chart.background.grid.diagonals.count'] ? prop['chart.background.grid.diagonals.count'] : (prop['chart.labels'] ? prop['chart.labels'].length : 8)));
|
657
|
-
|
658
|
-
|
659
|
-
for (var i=inc; i<360; i+=inc) {
|
660
|
-
|
661
|
-
// Radius must be greater than 0 for Opera to work
|
662
|
-
co.arc(
|
663
|
-
this.centerx,
|
664
|
-
this.centery,
|
665
|
-
this.radius,
|
666
|
-
(i / (180 / RG.PI)) - RG.HALFPI,
|
667
|
-
((i + 0.01) / (180 / RG.PI)) - RG.HALFPI,
|
668
|
-
0
|
669
|
-
);
|
670
|
-
|
671
|
-
co.lineTo(this.centerx, this.centery);
|
672
|
-
}
|
673
|
-
co.stroke();
|
674
|
-
}
|
675
|
-
}
|
676
|
-
|
677
|
-
// Reset the linewidth
|
678
|
-
co.lineWidth = 1;
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
687
|
-
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
co.beginPath();
|
693
|
-
co.strokeStyle = prop['chart.axes.color'];
|
694
|
-
|
695
|
-
// Draw the X axis
|
696
|
-
co.moveTo(this.centerx - this.radius, Math.round(this.centery));
|
697
|
-
co.lineTo(this.centerx + this.radius, Math.round(this.centery));
|
698
|
-
|
699
|
-
// Draw the X ends
|
700
|
-
if (prop['chart.axes.caps']) {
|
701
|
-
co.moveTo(ma.round(this.centerx - this.radius), this.centery - 5);
|
702
|
-
co.lineTo(ma.round(this.centerx - this.radius), this.centery + 5);
|
703
|
-
co.moveTo(ma.round(this.centerx + this.radius), this.centery - 5);
|
704
|
-
co.lineTo(ma.round(this.centerx + this.radius), this.centery + 5);
|
705
|
-
}
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
if (!RG.isNull(prop['chart.axes.numticks'])) {
|
710
|
-
var numticks = prop['chart.axes.numticks']
|
711
|
-
} else {
|
712
|
-
var numticks = prop['chart.labels.count'];
|
713
|
-
}
|
714
|
-
|
715
|
-
var caps = prop['chart.axes.caps'];
|
716
|
-
|
717
|
-
if (numticks) {
|
718
|
-
// Draw the X check marks
|
719
|
-
for (var i=(this.centerx - this.radius); i<(this.centerx + this.radius); i+=(this.radius / numticks)) {
|
720
|
-
co.moveTo(ma.round(i), this.centery - 3);
|
721
|
-
co.lineTo(ma.round(i), this.centery + 3);
|
722
|
-
}
|
723
|
-
|
724
|
-
// Draw the Y check marks
|
725
|
-
for (var i=(this.centery - this.radius); i<(this.centery + this.radius); i+=(this.radius / numticks)) {
|
726
|
-
co.moveTo(this.centerx - 3, ma.round(i));
|
727
|
-
co.lineTo(this.centerx + 3, ma.round(i));
|
728
|
-
}
|
729
|
-
}
|
730
|
-
|
731
|
-
// Draw the Y axis
|
732
|
-
co.moveTo(ma.round(this.centerx), this.centery - this.radius);
|
733
|
-
co.lineTo(ma.round(this.centerx), this.centery + this.radius);
|
734
|
-
|
735
|
-
// Draw the Y ends
|
736
|
-
if (prop['chart.axes.caps']) {
|
737
|
-
co.moveTo(this.centerx - 5, ma.round(this.centery - this.radius));
|
738
|
-
co.lineTo(this.centerx + 5, ma.round(this.centery - this.radius));
|
739
|
-
|
740
|
-
co.moveTo(this.centerx - 5, ma.round(this.centery + this.radius));
|
741
|
-
co.lineTo(this.centerx + 5, ma.round(this.centery + this.radius));
|
742
|
-
}
|
743
|
-
|
744
|
-
// Stroke it
|
745
|
-
co.closePath();
|
746
|
-
co.stroke();
|
747
|
-
};
|
748
|
-
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
/**
|
753
|
-
* This method draws a set of data on the graph
|
754
|
-
*/
|
755
|
-
this.drawRscatter =
|
756
|
-
this.DrawRscatter = function ()
|
757
|
-
{
|
758
|
-
for (var dataset=0; dataset<this.data.length; dataset+=1) {
|
759
|
-
|
760
|
-
var data = this.data[dataset];
|
761
|
-
this.coords2[dataset] = [];
|
762
|
-
|
763
|
-
var drawPoints = function (obj)
|
764
|
-
{
|
765
|
-
for (var i=0; i<data.length; ++i) {
|
766
|
-
|
767
|
-
var d1 = data[i][0],
|
768
|
-
d2 = data[i][1],
|
769
|
-
a = d1 / (180 / RG.PI), // RADIANS
|
770
|
-
r = ( (d2 - prop['chart.ymin']) / (obj.scale2.max - obj.scale2.min) ) * obj.radius,
|
771
|
-
x = Math.sin(a) * r,
|
772
|
-
y = Math.cos(a) * r,
|
773
|
-
color = data[i][2] ? data[i][2] : prop['chart.colors.default'],
|
774
|
-
tooltip = data[i][3] ? data[i][3] : null
|
775
|
-
|
776
|
-
if (tooltip && String(tooltip).length) {
|
777
|
-
obj.hasTooltips = true;
|
778
|
-
}
|
779
|
-
|
780
|
-
/**
|
781
|
-
* Account for the correct quadrant
|
782
|
-
*/
|
783
|
-
x = x + obj.centerx;
|
784
|
-
y = obj.centery - y;
|
785
|
-
|
786
|
-
|
787
|
-
obj.drawTick(x, y, color);
|
788
|
-
|
789
|
-
// Populate the coords array with the coordinates and the tooltip
|
790
|
-
obj.coords.push([x, y, color, tooltip]);
|
791
|
-
obj.coords2[dataset].push([x, y, color, tooltip]);
|
792
|
-
}
|
793
|
-
}
|
794
|
-
|
795
|
-
drawPoints(this);
|
796
|
-
|
797
|
-
if (prop['chart.line']) {
|
798
|
-
this.drawLine(dataset);
|
799
|
-
}
|
800
|
-
|
801
|
-
drawPoints(this);
|
802
|
-
}
|
803
|
-
};
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
/*
|
809
|
-
* Draws a connecting line through the points if requested
|
810
|
-
*
|
811
|
-
* @param object opt The options to the line
|
812
|
-
*/
|
813
|
-
this.drawLine = function (idx)
|
814
|
-
{
|
815
|
-
var opt = {
|
816
|
-
dataset: idx,
|
817
|
-
coords: this.coords2[idx],
|
818
|
-
color: prop['chart.line.colors'][idx],
|
819
|
-
shadow: prop['chart.line.shadow'],
|
820
|
-
shadowColor: prop['chart.line.shadow.color'],
|
821
|
-
shadowOffsetX: prop['chart.line.shadow.offsetx'],
|
822
|
-
shadowOffsetY: prop['chart.line.shadow.offsety'],
|
823
|
-
shadowBlur: prop['chart.line.shadow.blur'],
|
824
|
-
linewidth: prop['chart.line.linewidth']
|
825
|
-
};
|
826
|
-
|
827
|
-
co.beginPath();
|
828
|
-
|
829
|
-
co.strokeStyle = this.parseSingleColorForGradient(opt.color);
|
830
|
-
co.lineWidth = typeof prop['chart.line.linewidth'] === 'object' ? prop['chart.line.linewidth'][idx] : prop['chart.line.linewidth'];
|
831
|
-
co.lineCap = 'round';
|
832
|
-
|
833
|
-
if (opt.shadow) {
|
834
|
-
RG.setShadow(
|
835
|
-
this,
|
836
|
-
opt.shadowColor,
|
837
|
-
opt.shadowOffsetX,
|
838
|
-
opt.shadowOffsetY,
|
839
|
-
opt.shadowBlur
|
840
|
-
);
|
841
|
-
}
|
842
|
-
|
843
|
-
for (var i=0; i<this.coords2[idx].length; ++i) {
|
844
|
-
if (i === 0) {
|
845
|
-
co.moveTo(this.coords2[idx][i][0], this.coords2[idx][i][1]);
|
846
|
-
|
847
|
-
var startCoords = RG.arrayClone(this.coords2[idx]);
|
848
|
-
|
849
|
-
} else {
|
850
|
-
co.lineTo(this.coords2[idx][i][0], this.coords2[idx][i][1]);
|
851
|
-
}
|
852
|
-
}
|
853
|
-
|
854
|
-
// Draw the line back to the start?
|
855
|
-
if (
|
856
|
-
(typeof prop['chart.line.close'] === 'boolean' && prop['chart.line.close'])
|
857
|
-
|| (typeof prop['chart.line.close'] === 'object' && prop['chart.line.close'][idx])
|
858
|
-
) {
|
859
|
-
co.lineTo(this.coords2[idx][0][0], this.coords2[idx][0][1]);
|
860
|
-
}
|
861
|
-
|
862
|
-
co.stroke();
|
863
|
-
|
864
|
-
RG.noShadow(this);
|
865
|
-
};
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
/**
|
871
|
-
* Unsuprisingly, draws the labels
|
872
|
-
*/
|
873
|
-
this.drawLabels =
|
874
|
-
this.DrawLabels = function ()
|
875
|
-
{
|
876
|
-
co.lineWidth = 1;
|
877
|
-
|
878
|
-
// Default the color to black
|
879
|
-
co.fillStyle = 'black';
|
880
|
-
co.strokeStyle = 'black';
|
881
|
-
|
882
|
-
var key = prop['chart.key'];
|
883
|
-
var r = this.radius;
|
884
|
-
var axesColor = prop['chart.axes.color'];
|
885
|
-
var color = prop['chart.text.color'];
|
886
|
-
var font = prop['chart.text.font'];
|
887
|
-
var size = prop['chart.text.size'];
|
888
|
-
var axes = prop['chart.labels.axes'].toLowerCase();
|
889
|
-
var units_pre = prop['chart.units.pre'];
|
890
|
-
var units_post = prop['chart.units.post'];
|
891
|
-
var decimals = prop['chart.scale.decimals'];
|
892
|
-
var centerx = this.centerx;
|
893
|
-
var centery = this.centery;
|
894
|
-
|
895
|
-
co.fillStyle = prop['chart.text.color'];
|
896
|
-
|
897
|
-
// Draw any labels
|
898
|
-
if (typeof prop['chart.labels'] == 'object' && prop['chart.labels']) {
|
899
|
-
this.DrawCircularLabels(co, prop['chart.labels'], font , size, r);
|
900
|
-
}
|
901
|
-
|
902
|
-
|
903
|
-
//
|
904
|
-
// If the axes are transparent - then the labels should have no offset,
|
905
|
-
// otherwise it defaults to true. Similarly the labels can or can't be
|
906
|
-
// centered if there's no axes
|
907
|
-
//
|
908
|
-
var offset = 10;
|
909
|
-
var centered = false;
|
910
|
-
|
911
|
-
if ( axesColor === 'rgba(0,0,0,0)'
|
912
|
-
|| axesColor === 'rgb(0,0,0)'
|
913
|
-
|| axesColor === 'transparent') {
|
914
|
-
|
915
|
-
offset = 0;
|
916
|
-
centered = true;
|
917
|
-
}
|
918
|
-
|
919
|
-
// Draw the axis labels
|
920
|
-
for (var i=0,len=this.scale2.labels.length; i<len; ++i) {
|
921
|
-
if (axes.indexOf('n') > -1) RG.text2(this, {'tag': 'scale','font':font,'size':size,'x':centerx - offset,'y':centery - (r * ((i+1) / len)),'text':this.scale2.labels[i],'valign':'center','halign':centered ? 'center' : 'right',bounding: true, boundingFill: prop['chart.labels.axes.background'], boundingStroke: 'rgba(0,0,0,0)'});
|
922
|
-
if (axes.indexOf('s') > -1) RG.text2(this, {'tag': 'scale','font':font,'size':size,'x':centerx - offset,'y':centery + (r * ((i+1) / len)),'text':this.scale2.labels[i],'valign':'center','halign':centered ? 'center' : 'right',bounding: true, boundingFill: prop['chart.labels.axes.background'], boundingStroke: 'rgba(0,0,0,0)'});
|
923
|
-
if (axes.indexOf('e') > -1) RG.text2(this, {'tag': 'scale','font':font,'size':size,'x':centerx + (r * ((i+1) / len)),'y':centery + offset,'text':this.scale2.labels[i],'valign':centered ? 'center' : 'top','halign':'center',bounding: true, boundingFill: prop['chart.labels.axes.background'], boundingStroke: 'rgba(0,0,0,0)'});
|
924
|
-
if (axes.indexOf('w') > -1) RG.text2(this, {'tag': 'scale','font':font,'size':size,'x':centerx - (r * ((i+1) / len)),'y':centery + offset,'text':this.scale2.labels[i],'valign':centered ? 'center' : 'top','halign':'center',bounding: true, boundingFill: prop['chart.labels.axes.background'], boundingStroke: 'rgba(0,0,0,0)'});
|
925
|
-
}
|
926
|
-
|
927
|
-
// Draw the center minimum value (but only if there's at least one axes labels stipulated)
|
928
|
-
if (prop['chart.labels.axes'].length > 0 && prop['chart.scale.zerostart']) {
|
929
|
-
RG.text2(this, {
|
930
|
-
'font':font,
|
931
|
-
'size':size,
|
932
|
-
'x':centerx,
|
933
|
-
'y':centery,
|
934
|
-
'text':RG.numberFormat(this, Number(this.scale2.min).toFixed(this.scale2.decimals), this.scale2.units_pre, this.scale2.units_post),
|
935
|
-
'valign':'center',
|
936
|
-
'halign':'center',
|
937
|
-
'bounding':true,
|
938
|
-
'boundingFill': prop['chart.labels.axes.background'],
|
939
|
-
'boundingStroke': 'rgba(0,0,0,0)',
|
940
|
-
'tag': 'scale'
|
941
|
-
});
|
942
|
-
}
|
943
|
-
|
944
|
-
/**
|
945
|
-
* Draw the key
|
946
|
-
*/
|
947
|
-
if (key && key.length) {
|
948
|
-
RG.drawKey(this, key, prop['chart.colors']);
|
949
|
-
}
|
950
|
-
};
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
/**
|
956
|
-
* Draws the circular labels that go around the charts
|
957
|
-
*
|
958
|
-
* @param labels array The labels that go around the chart
|
959
|
-
*/
|
960
|
-
this.drawCircularLabels =
|
961
|
-
this.DrawCircularLabels = function (context, labels, font_face, font_size, r)
|
962
|
-
{
|
963
|
-
var r = r + 10,
|
964
|
-
color = prop['chart.labels.color'];
|
965
|
-
|
966
|
-
for (var i=0; i<labels.length; ++i) {
|
967
|
-
|
968
|
-
var a = (360 / labels.length) * (i + 1) - (360 / (labels.length * 2));
|
969
|
-
var a = a - 90 + (prop['chart.labels.position'] == 'edge' ? ((360 / labels.length) / 2) : 0);
|
970
|
-
|
971
|
-
var x = ma.cos(a / (180/RG.PI) ) * r;
|
972
|
-
var y = ma.sin(a / (180/RG.PI)) * r;
|
973
|
-
|
974
|
-
RG.Text2(this, {
|
975
|
-
'color': color,
|
976
|
-
'font':font_face,
|
977
|
-
'size':font_size,
|
978
|
-
'x':this.centerx + x,
|
979
|
-
'y':this.centery + y,
|
980
|
-
'text':String(labels[i]),
|
981
|
-
'valign':'center',
|
982
|
-
'halign':( (this.centerx + x) > this.centerx) ? 'left' : 'right',
|
983
|
-
'tag': 'labels'
|
984
|
-
});
|
985
|
-
}
|
986
|
-
};
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
/**
|
992
|
-
* Draws a single tickmark
|
993
|
-
*/
|
994
|
-
this.drawTick =
|
995
|
-
this.DrawTick = function (x, y, color)
|
996
|
-
{
|
997
|
-
var tickmarks = prop['chart.tickmarks'];
|
998
|
-
var ticksize = prop['chart.ticksize'];
|
999
|
-
|
1000
|
-
co.strokeStyle = color;
|
1001
|
-
co.fillStyle = color;
|
1002
|
-
|
1003
|
-
// Set the linewidth for the tickmark to 1
|
1004
|
-
var prevLinewidth = co.lineWidth;
|
1005
|
-
co.lineWidth = 1;
|
1006
|
-
|
1007
|
-
// Cross
|
1008
|
-
if (tickmarks == 'cross') {
|
1009
|
-
|
1010
|
-
co.beginPath();
|
1011
|
-
co.moveTo(x + ticksize, y + ticksize);
|
1012
|
-
co.lineTo(x - ticksize, y - ticksize);
|
1013
|
-
co.stroke();
|
1014
|
-
|
1015
|
-
co.beginPath();
|
1016
|
-
co.moveTo(x - ticksize, y + ticksize);
|
1017
|
-
co.lineTo(x + ticksize, y - ticksize);
|
1018
|
-
co.stroke();
|
1019
|
-
|
1020
|
-
// Circle
|
1021
|
-
} else if (tickmarks == 'circle') {
|
1022
|
-
|
1023
|
-
co.beginPath();
|
1024
|
-
co.arc(x, y, ticksize, 0, 6.2830, false);
|
1025
|
-
co.fill();
|
1026
|
-
|
1027
|
-
// Square
|
1028
|
-
} else if (tickmarks == 'square') {
|
1029
|
-
|
1030
|
-
co.beginPath();
|
1031
|
-
co.fillRect(x - ticksize, y - ticksize, 2 * ticksize, 2 * ticksize);
|
1032
|
-
co.fill();
|
1033
|
-
|
1034
|
-
// Diamond shape tickmarks
|
1035
|
-
} else if (tickmarks == 'diamond') {
|
1036
|
-
|
1037
|
-
co.beginPath();
|
1038
|
-
co.moveTo(x, y - ticksize);
|
1039
|
-
co.lineTo(x + ticksize, y);
|
1040
|
-
co.lineTo(x, y + ticksize);
|
1041
|
-
co.lineTo(x - ticksize, y);
|
1042
|
-
co.closePath();
|
1043
|
-
co.fill();
|
1044
|
-
|
1045
|
-
// Plus style tickmarks
|
1046
|
-
} else if (tickmarks == 'plus') {
|
1047
|
-
|
1048
|
-
co.lineWidth = 1;
|
1049
|
-
|
1050
|
-
co.beginPath();
|
1051
|
-
co.moveTo(x, y - ticksize);
|
1052
|
-
co.lineTo(x, y + ticksize);
|
1053
|
-
co.moveTo(x - ticksize, y);
|
1054
|
-
co.lineTo(x + ticksize, y);
|
1055
|
-
co.stroke();
|
1056
|
-
}
|
1057
|
-
|
1058
|
-
|
1059
|
-
co.lineWidth = prevLinewidth;
|
1060
|
-
};
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
/**
|
1066
|
-
* This function makes it much easier to get the (if any) point that is currently being hovered over.
|
1067
|
-
*
|
1068
|
-
* @param object e The event object
|
1069
|
-
*/
|
1070
|
-
this.getShape =
|
1071
|
-
this.getPoint = function (e)
|
1072
|
-
{
|
1073
|
-
var mouseXY = RG.getMouseXY(e);
|
1074
|
-
var mouseX = mouseXY[0];
|
1075
|
-
var mouseY = mouseXY[1];
|
1076
|
-
var overHotspot = false;
|
1077
|
-
var offset = prop['chart.tooltips.hotspot']; // This is how far the hotspot extends
|
1078
|
-
|
1079
|
-
for (var i=0,len=this.coords.length; i<len; ++i) {
|
1080
|
-
|
1081
|
-
var x = this.coords[i][0];
|
1082
|
-
var y = this.coords[i][1];
|
1083
|
-
var tooltip = this.coords[i][3];
|
1084
|
-
|
1085
|
-
if (
|
1086
|
-
mouseX < (x + offset) &&
|
1087
|
-
mouseX > (x - offset) &&
|
1088
|
-
mouseY < (y + offset) &&
|
1089
|
-
mouseY > (y - offset)
|
1090
|
-
) {
|
1091
|
-
|
1092
|
-
var tooltip = RG.parseTooltipText(prop['chart.tooltips'], i);
|
1093
|
-
|
1094
|
-
return {0:this,1:x,2:y,3:i,'object':this, 'x':x, 'y':y, 'index':i, 'tooltip': tooltip};
|
1095
|
-
}
|
1096
|
-
}
|
1097
|
-
};
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
/**
|
1103
|
-
* This function facilitates the installation of tooltip event listeners if
|
1104
|
-
* tooltips are defined.
|
1105
|
-
*/
|
1106
|
-
this.allowTooltips =
|
1107
|
-
this.AllowTooltips = function ()
|
1108
|
-
{
|
1109
|
-
// Preload any tooltip images that are used in the tooltips
|
1110
|
-
RG.PreLoadTooltipImages(this);
|
1111
|
-
|
1112
|
-
|
1113
|
-
/**
|
1114
|
-
* This installs the window mousedown event listener that lears any
|
1115
|
-
* highlight that may be visible.
|
1116
|
-
*/
|
1117
|
-
RG.InstallWindowMousedownTooltipListener(this);
|
1118
|
-
|
1119
|
-
|
1120
|
-
/**
|
1121
|
-
* This installs the canvas mousemove event listener. This function
|
1122
|
-
* controls the pointer shape.
|
1123
|
-
*/
|
1124
|
-
RG.InstallCanvasMousemoveTooltipListener(this);
|
1125
|
-
|
1126
|
-
|
1127
|
-
/**
|
1128
|
-
* This installs the canvas mouseup event listener. This is the
|
1129
|
-
* function that actually shows the appropriate tooltip (if any).
|
1130
|
-
*/
|
1131
|
-
RG.InstallCanvasMouseupTooltipListener(this);
|
1132
|
-
};
|
1133
|
-
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1137
|
-
/**
|
1138
|
-
* Each object type has its own Highlight() function which highlights the appropriate shape
|
1139
|
-
*
|
1140
|
-
* @param object shape The shape to highlight
|
1141
|
-
*/
|
1142
|
-
this.highlight =
|
1143
|
-
this.Highlight = function (shape)
|
1144
|
-
{
|
1145
|
-
if (typeof prop['chart.highlight.style'] === 'function') {
|
1146
|
-
(prop['chart.highlight.style'])(shape);
|
1147
|
-
} else {
|
1148
|
-
RG.Highlight.Point(this, shape);
|
1149
|
-
}
|
1150
|
-
};
|
1151
|
-
|
1152
|
-
|
1153
|
-
|
1154
|
-
|
1155
|
-
/**
|
1156
|
-
* The getObjectByXY() worker method. Don't call this call:
|
1157
|
-
*
|
1158
|
-
* RGraph.ObjectRegistry.getObjectByXY(e)
|
1159
|
-
*
|
1160
|
-
* @param object e The event object
|
1161
|
-
*/
|
1162
|
-
this.getObjectByXY = function (e)
|
1163
|
-
{
|
1164
|
-
var mouseXY = RG.getMouseXY(e);
|
1165
|
-
var mouseX = mouseXY[0];
|
1166
|
-
var mouseY = mouseXY[1];
|
1167
|
-
var centerx = this.centerx;
|
1168
|
-
var centery = this.centery;
|
1169
|
-
var radius = this.radius;
|
1170
|
-
|
1171
|
-
if (
|
1172
|
-
mouseX > (centerx - radius)
|
1173
|
-
&& mouseX < (centerx + radius)
|
1174
|
-
&& mouseY > (centery - radius)
|
1175
|
-
&& mouseY < (centery + radius)
|
1176
|
-
) {
|
1177
|
-
|
1178
|
-
return this;
|
1179
|
-
}
|
1180
|
-
};
|
1181
|
-
|
1182
|
-
|
1183
|
-
|
1184
|
-
|
1185
|
-
/**
|
1186
|
-
* This function positions a tooltip when it is displayed
|
1187
|
-
*
|
1188
|
-
* @param obj object The chart object
|
1189
|
-
* @param int x The X coordinate specified for the tooltip
|
1190
|
-
* @param int y The Y coordinate specified for the tooltip
|
1191
|
-
* @param objec tooltip The tooltips DIV element
|
1192
|
-
*/
|
1193
|
-
this.positionTooltip = function (obj, x, y, tooltip, idx)
|
1194
|
-
{
|
1195
|
-
var coordX = obj.coords[tooltip.__index__][0];
|
1196
|
-
var coordY = obj.coords[tooltip.__index__][1];
|
1197
|
-
var canvasXY = RG.getCanvasXY(obj.canvas);
|
1198
|
-
var mouseXY = RG.getMouseXY(window.event);
|
1199
|
-
var gutterLeft = obj.gutterLeft;
|
1200
|
-
var gutterTop = obj.gutterTop;
|
1201
|
-
var width = tooltip.offsetWidth;
|
1202
|
-
var height = tooltip.offsetHeight;
|
1203
|
-
|
1204
|
-
// Set the top position
|
1205
|
-
tooltip.style.left = 0;
|
1206
|
-
tooltip.style.top = window.event.pageY - height - 5 + 'px';
|
1207
|
-
|
1208
|
-
// By default any overflow is hidden
|
1209
|
-
tooltip.style.overflow = '';
|
1210
|
-
|
1211
|
-
// Reposition the tooltip if at the edges:
|
1212
|
-
|
1213
|
-
// LEFT edge
|
1214
|
-
if (canvasXY[0] + mouseXY[0] - (width / 2) < 0) {
|
1215
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.1) + 'px';
|
1216
|
-
|
1217
|
-
// RIGHT edge
|
1218
|
-
} else if (canvasXY[0] + mouseXY[0] + (width / 2) > doc.body.offsetWidth) {
|
1219
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width * 0.9) + 'px';
|
1220
|
-
|
1221
|
-
// Default positioning - CENTERED
|
1222
|
-
} else {
|
1223
|
-
tooltip.style.left = canvasXY[0] + mouseXY[0] - (width / 2) + 'px';
|
1224
|
-
}
|
1225
|
-
};
|
1226
|
-
|
1227
|
-
|
1228
|
-
|
1229
|
-
|
1230
|
-
/**
|
1231
|
-
* This function returns the radius (ie the distance from the center) for a particular
|
1232
|
-
* value.
|
1233
|
-
*
|
1234
|
-
* @param number value The value you want the radius for
|
1235
|
-
*/
|
1236
|
-
this.getRadius = function (value)
|
1237
|
-
{
|
1238
|
-
var max = this.max;
|
1239
|
-
|
1240
|
-
if (value < 0 || value > max) {
|
1241
|
-
return null;
|
1242
|
-
}
|
1243
|
-
|
1244
|
-
var r = (value / max) * this.radius;
|
1245
|
-
|
1246
|
-
return r;
|
1247
|
-
};
|
1248
|
-
|
1249
|
-
|
1250
|
-
|
1251
|
-
|
1252
|
-
/**
|
1253
|
-
* This allows for easy specification of gradients
|
1254
|
-
*/
|
1255
|
-
this.parseColors = function ()
|
1256
|
-
{
|
1257
|
-
// Save the original colors so that they can be restored when the canvas is reset
|
1258
|
-
if (this.original_colors.length === 0) {
|
1259
|
-
this.original_colors['data'] = RG.array_clone(this.data);
|
1260
|
-
this.original_colors['chart.highlight.stroke'] = RG.arrayClone(prop['chart.highlight.stroke']);
|
1261
|
-
this.original_colors['chart.highlight.fill'] = RG.arrayClone(prop['chart.highlight.fill']);
|
1262
|
-
this.original_colors['chart.colors.default'] = RG.arrayClone(prop['chart.colors.default']);
|
1263
|
-
this.original_colors['chart.background.grid.color'] = RG.arrayClone(prop['chart.background.grid.color']);
|
1264
|
-
this.original_colors['chart.background.color'] = RG.arrayClone(prop['chart.background.color']);
|
1265
|
-
this.original_colors['chart.segment.highlight.stroke'] = RG.arrayClone(prop['chart.segment.highlight.stroke']);
|
1266
|
-
this.original_colors['chart.segment.highlight.fill'] = RG.arrayClone(prop['chart.segment.highlight.fill']);
|
1267
|
-
}
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
// Go through the data
|
1275
|
-
for (var i=0; i<this.data.length; i+=1) {
|
1276
|
-
for (var j=0,len=this.data[i].length; j<len; j+=1) {
|
1277
|
-
this.data[i][j][2] = this.parseSingleColorForGradient(this.data[i][j][2]);
|
1278
|
-
}
|
1279
|
-
}
|
1280
|
-
|
1281
|
-
prop['chart.highlight.stroke'] = this.parseSingleColorForGradient(prop['chart.highlight.stroke']);
|
1282
|
-
prop['chart.highlight.fill'] = this.parseSingleColorForGradient(prop['chart.highlight.fill']);
|
1283
|
-
prop['chart.colors.default'] = this.parseSingleColorForGradient(prop['chart.colors.default']);
|
1284
|
-
prop['chart.background.grid.color'] = this.parseSingleColorForGradient(prop['chart.background.grid.color']);
|
1285
|
-
prop['chart.background.color'] = this.parseSingleColorForGradient(prop['chart.background.color']);
|
1286
|
-
prop['chart.segment.highlight.stroke'] = this.parseSingleColorForGradient(prop['chart.segment.highlight.stroke']);
|
1287
|
-
prop['chart.segment.highlight.fill'] = this.parseSingleColorForGradient(prop['chart.segment.highlight.fill']);
|
1288
|
-
};
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
/**
|
1294
|
-
* Use this function to reset the object to the post-constructor state. Eg reset colors if
|
1295
|
-
* need be etc
|
1296
|
-
*/
|
1297
|
-
this.reset = function ()
|
1298
|
-
{
|
1299
|
-
};
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
/**
|
1305
|
-
* This parses a single color value
|
1306
|
-
*/
|
1307
|
-
this.parseSingleColorForGradient = function (color)
|
1308
|
-
{
|
1309
|
-
if (!color || typeof color != 'string') {
|
1310
|
-
return color;
|
1311
|
-
}
|
1312
|
-
|
1313
|
-
if (color.match(/^gradient\((.*)\)$/i)) {
|
1314
|
-
|
1315
|
-
var parts = RegExp.$1.split(':');
|
1316
|
-
|
1317
|
-
// Create the gradient
|
1318
|
-
var grad = co.createRadialGradient(this.centerx, this.centery, 0, this.centerx, this.centery, this.radius);
|
1319
|
-
|
1320
|
-
var diff = 1 / (parts.length - 1);
|
1321
|
-
|
1322
|
-
grad.addColorStop(0, RG.trim(parts[0]));
|
1323
|
-
|
1324
|
-
for (var j=1; j<parts.length; ++j) {
|
1325
|
-
grad.addColorStop(j * diff, RG.trim(parts[j]));
|
1326
|
-
}
|
1327
|
-
}
|
1328
|
-
|
1329
|
-
return grad ? grad : color;
|
1330
|
-
};
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1334
|
-
|
1335
|
-
/**
|
1336
|
-
* This function handles highlighting an entire data-series for the interactive
|
1337
|
-
* key
|
1338
|
-
*
|
1339
|
-
* @param int index The index of the data series to be highlighted
|
1340
|
-
*/
|
1341
|
-
this.interactiveKeyHighlight = function (index)
|
1342
|
-
{
|
1343
|
-
if (this.coords2 && this.coords2[index] && this.coords2[index].length) {
|
1344
|
-
this.coords2[index].forEach(function (value, idx, arr)
|
1345
|
-
{
|
1346
|
-
co.beginPath();
|
1347
|
-
co.fillStyle = prop['chart.key.interactive.highlight.chart.fill'];
|
1348
|
-
co.arc(value[0], value[1], prop['chart.ticksize'] + 2, 0, RG.TWOPI, false);
|
1349
|
-
co.fill();
|
1350
|
-
});
|
1351
|
-
}
|
1352
|
-
};
|
1353
|
-
|
1354
|
-
|
1355
|
-
|
1356
|
-
|
1357
|
-
/**
|
1358
|
-
* Using a function to add events makes it easier to facilitate method chaining
|
1359
|
-
*
|
1360
|
-
* @param string type The type of even to add
|
1361
|
-
* @param function func
|
1362
|
-
*/
|
1363
|
-
this.on = function (type, func)
|
1364
|
-
{
|
1365
|
-
if (type.substr(0,2) !== 'on') {
|
1366
|
-
type = 'on' + type;
|
1367
|
-
}
|
1368
|
-
|
1369
|
-
this[type] = func;
|
1370
|
-
|
1371
|
-
return this;
|
1372
|
-
};
|
1373
|
-
|
1374
|
-
|
1375
|
-
|
1376
|
-
|
1377
|
-
/**
|
1378
|
-
* This helps the Gantt reset colors when the reset function is called.
|
1379
|
-
* It handles going through the data and resetting the colors.
|
1380
|
-
*/
|
1381
|
-
this.resetColorsToOriginalValues = function ()
|
1382
|
-
{
|
1383
|
-
/**
|
1384
|
-
* Copy the original colors over for single-event-per-line data
|
1385
|
-
*/
|
1386
|
-
for (var i=0,len=this.original_colors['data'].length; i<len; ++i) {
|
1387
|
-
for (var j=0,len2=this.original_colors['data'][i].length; j<len2;++j) {
|
1388
|
-
this.data[i][j][2] = RG.array_clone(this.original_colors['data'][i][j][2]);
|
1389
|
-
}
|
1390
|
-
}
|
1391
|
-
};
|
1392
|
-
|
1393
|
-
|
1394
|
-
|
1395
|
-
|
1396
|
-
/**
|
1397
|
-
* This function runs once only
|
1398
|
-
* (put at the end of the file (before any effects))
|
1399
|
-
*/
|
1400
|
-
this.firstDrawFunc = function ()
|
1401
|
-
{
|
1402
|
-
};
|
1403
|
-
|
1404
|
-
|
1405
|
-
RG.att(ca);
|
1406
|
-
|
1407
|
-
|
1408
|
-
|
1409
|
-
|
1410
|
-
/**
|
1411
|
-
* Register the object
|
1412
|
-
*/
|
1413
|
-
RG.Register(this);
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
/**
|
1419
|
-
* This is the 'end' of the constructor so if the first argument
|
1420
|
-
* contains configuration data - handle that.
|
1421
|
-
*/
|
1422
|
-
if (parseConfObjectForOptions) {
|
1423
|
-
RG.parseObjectStyleConfig(this, conf.options);
|
1424
|
-
}
|
1425
|
-
};
|