rgraph-rails 4.62 → 4.64
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 +5 -5
- data/README.md +3 -4
- data/lib/rgraph-rails/version.rb +1 -1
- data/vendor/assets/javascripts/RGraph.bar.js +240 -3742
- data/vendor/assets/javascripts/RGraph.bipolar.js +165 -2005
- data/vendor/assets/javascripts/RGraph.common.annotate.js +35 -395
- data/vendor/assets/javascripts/RGraph.common.context.js +30 -595
- data/vendor/assets/javascripts/RGraph.common.core.js +418 -5359
- data/vendor/assets/javascripts/RGraph.common.csv.js +20 -276
- data/vendor/assets/javascripts/RGraph.common.deprecated.js +35 -450
- data/vendor/assets/javascripts/RGraph.common.dynamic.js +88 -1395
- data/vendor/assets/javascripts/RGraph.common.effects.js +90 -1545
- data/vendor/assets/javascripts/RGraph.common.key.js +52 -753
- data/vendor/assets/javascripts/RGraph.common.resizing.js +37 -563
- data/vendor/assets/javascripts/RGraph.common.sheets.js +29 -352
- data/vendor/assets/javascripts/RGraph.common.tooltips.js +32 -450
- data/vendor/assets/javascripts/RGraph.common.zoom.js +14 -219
- data/vendor/assets/javascripts/RGraph.cornergauge.js +71 -0
- data/vendor/assets/javascripts/RGraph.drawing.background.js +34 -570
- data/vendor/assets/javascripts/RGraph.drawing.circle.js +33 -544
- data/vendor/assets/javascripts/RGraph.drawing.image.js +51 -755
- data/vendor/assets/javascripts/RGraph.drawing.marker1.js +37 -645
- data/vendor/assets/javascripts/RGraph.drawing.marker2.js +36 -633
- data/vendor/assets/javascripts/RGraph.drawing.marker3.js +35 -514
- data/vendor/assets/javascripts/RGraph.drawing.poly.js +37 -559
- data/vendor/assets/javascripts/RGraph.drawing.rect.js +33 -548
- data/vendor/assets/javascripts/RGraph.drawing.text.js +36 -664
- data/vendor/assets/javascripts/RGraph.drawing.xaxis.js +50 -812
- 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 +77 -1354
- data/vendor/assets/javascripts/RGraph.gauge.js +85 -1421
- data/vendor/assets/javascripts/RGraph.hbar.js +162 -2788
- data/vendor/assets/javascripts/RGraph.hprogress.js +80 -1401
- data/vendor/assets/javascripts/RGraph.line.js +249 -4248
- data/vendor/assets/javascripts/RGraph.meter.js +74 -1280
- data/vendor/assets/javascripts/RGraph.modaldialog.js +19 -301
- data/vendor/assets/javascripts/RGraph.odo.js +71 -1264
- data/vendor/assets/javascripts/RGraph.pie.js +137 -2288
- data/vendor/assets/javascripts/RGraph.radar.js +110 -1847
- data/vendor/assets/javascripts/RGraph.rose.js +108 -1977
- data/vendor/assets/javascripts/RGraph.rscatter.js +80 -1432
- data/vendor/assets/javascripts/RGraph.scatter.js +172 -3163
- data/vendor/assets/javascripts/RGraph.semicircularprogress.js +60 -1120
- data/vendor/assets/javascripts/RGraph.svg.bar.js +66 -1735
- data/vendor/assets/javascripts/RGraph.svg.common.ajax.js +21 -246
- data/vendor/assets/javascripts/RGraph.svg.common.core.js +255 -3937
- data/vendor/assets/javascripts/RGraph.svg.common.csv.js +20 -276
- data/vendor/assets/javascripts/RGraph.svg.common.fx.js +68 -1303
- data/vendor/assets/javascripts/RGraph.svg.common.key.js +19 -205
- data/vendor/assets/javascripts/RGraph.svg.common.sheets.js +29 -352
- data/vendor/assets/javascripts/RGraph.svg.common.tooltips.js +22 -273
- data/vendor/assets/javascripts/RGraph.svg.funnel.js +32 -0
- data/vendor/assets/javascripts/RGraph.svg.hbar.js +59 -1400
- data/vendor/assets/javascripts/RGraph.svg.line.js +70 -1580
- data/vendor/assets/javascripts/RGraph.svg.pie.js +55 -1131
- data/vendor/assets/javascripts/RGraph.svg.radar.js +57 -1502
- data/vendor/assets/javascripts/RGraph.svg.rose.js +66 -1817
- data/vendor/assets/javascripts/RGraph.svg.scatter.js +58 -1261
- data/vendor/assets/javascripts/RGraph.svg.semicircularprogress.js +28 -865
- data/vendor/assets/javascripts/RGraph.svg.waterfall.js +45 -1252
- data/vendor/assets/javascripts/RGraph.thermometer.js +63 -1136
- data/vendor/assets/javascripts/RGraph.vprogress.js +83 -1470
- data/vendor/assets/javascripts/RGraph.waterfall.js +83 -1347
- metadata +5 -4
- data/vendor/assets/javascripts/financial-data.js +0 -1067
@@ -1,1137 +1,64 @@
|
|
1
|
-
// version: 2017-05-08
|
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 licensed under the Open Source MIT license. That means that it's |
|
9
|
-
* | totally free to use! |
|
10
|
-
* o--------------------------------------------------------------------------------o
|
11
|
-
*/
|
12
1
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
'chart.linewidth': 1,
|
77
|
-
'chart.background.color': 'white',
|
78
|
-
'chart.strokestyle': 'black',
|
79
|
-
'chart.colors': ['Gradient(#c00:red:#f66:#fcc)'],
|
80
|
-
'chart.gutter.left': 25,
|
81
|
-
'chart.gutter.right': 25,
|
82
|
-
'chart.gutter.top': 25,
|
83
|
-
'chart.gutter.bottom': 25,
|
84
|
-
'chart.ticksize': 2,
|
85
|
-
'chart.text.color': 'black',
|
86
|
-
'chart.text.font': 'Segoe UI, Arial, Verdana, sans-serif',
|
87
|
-
'chart.text.size': 12,
|
88
|
-
'chart.text.accessible': true,
|
89
|
-
'chart.text.accessible.overflow': 'visible',
|
90
|
-
'chart.text.accessible.pointerevents': true,
|
91
|
-
'chart.numticks': 10,
|
92
|
-
'chart.units.pre': '',
|
93
|
-
'chart.units.post': '',
|
94
|
-
'chart.zoom.factor': 1.5,
|
95
|
-
'chart.zoom.fade.in': true,
|
96
|
-
'chart.zoom.fade.out': true,
|
97
|
-
'chart.zoom.hdir': 'right',
|
98
|
-
'chart.zoom.vdir': 'down',
|
99
|
-
'chart.zoom.frames': 25,
|
100
|
-
'chart.zoom.delay': 16.666,
|
101
|
-
'chart.zoom.shadow': true,
|
102
|
-
'chart.zoom.background': true,
|
103
|
-
'chart.title': '',
|
104
|
-
'chart.title.side': '',
|
105
|
-
'chart.title.side.bold': true,
|
106
|
-
'chart.title.side.font': null,
|
107
|
-
'chart.shadow': true,
|
108
|
-
'chart.shadow.offsetx': 0,
|
109
|
-
'chart.shadow.offsety': 0,
|
110
|
-
'chart.shadow.blur': 15,
|
111
|
-
'chart.shadow.color': '#ddd',
|
112
|
-
'chart.resizable': false,
|
113
|
-
'chart.contextmenu': null,
|
114
|
-
'chart.adjustable': false,
|
115
|
-
'chart.value.label': true,
|
116
|
-
'chart.value.label.decimals': null,
|
117
|
-
'chart.value.label.thousand': ',',
|
118
|
-
'chart.value.label.point': '.',
|
119
|
-
'chart.labels.count': 5,
|
120
|
-
'chart.scale.visible': false,
|
121
|
-
'chart.scale.decimals': 0,
|
122
|
-
'chart.annotatable': false,
|
123
|
-
'chart.annotate.color': 'black',
|
124
|
-
'chart.scale.decimals': 0,
|
125
|
-
'chart.scale.point': '.',
|
126
|
-
'chart.scale.thousand': ',',
|
127
|
-
'chart.tooltips': null,
|
128
|
-
'chart.tooltips.highlight': true,
|
129
|
-
'chart.tooltips.effect': 'fade',
|
130
|
-
'chart.tooltips.event': 'onclick',
|
131
|
-
'chart.highlight.stroke': 'rgba(0,0,0,0)',
|
132
|
-
'chart.highlight.fill': 'rgba(255,255,255,0.7)',
|
133
|
-
'chart.clearto': 'rgba(0,0,0,0)',
|
134
|
-
'chart.bulb.bottom.radius.adjust': 0,
|
135
|
-
'chart.bulb.bottom.radius': null
|
136
|
-
}
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
/**
|
141
|
-
* A simple check that the browser has canvas support
|
142
|
-
*/
|
143
|
-
if (!this.canvas) {
|
144
|
-
alert('[THERMOMETER] No canvas support');
|
145
|
-
return;
|
146
|
-
}
|
147
|
-
|
148
|
-
/**
|
149
|
-
* The thermometer can only have one data point so only this.$0 needs to be created
|
150
|
-
*/
|
151
|
-
this.$0 = {};
|
152
|
-
|
153
|
-
|
154
|
-
/**
|
155
|
-
* Translate half a pixel for antialiasing purposes - but only if it hasn't beeen
|
156
|
-
* done already
|
157
|
-
*/
|
158
|
-
if (!this.canvas.__rgraph_aa_translated__) {
|
159
|
-
this.context.translate(0.5,0.5);
|
160
|
-
|
161
|
-
this.canvas.__rgraph_aa_translated__ = true;
|
162
|
-
}
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
// Short variable names
|
168
|
-
var RG = RGraph,
|
169
|
-
ca = this.canvas,
|
170
|
-
co = ca.getContext('2d'),
|
171
|
-
prop = this.properties,
|
172
|
-
pa2 = RG.path2,
|
173
|
-
win = window,
|
174
|
-
doc = document,
|
175
|
-
ma = Math
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
/**
|
180
|
-
* "Decorate" the object with the generic effects if the effects library has been included
|
181
|
-
*/
|
182
|
-
if (RG.Effects && typeof RG.Effects.decorate === 'function') {
|
183
|
-
RG.Effects.decorate(this);
|
184
|
-
}
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
/**
|
190
|
-
* A setter.
|
191
|
-
*
|
192
|
-
* @param name string The name of the property to set
|
193
|
-
* @param value mixed The value of the property
|
194
|
-
*/
|
195
|
-
this.set =
|
196
|
-
this.Set = function (name)
|
197
|
-
{
|
198
|
-
var value = typeof arguments[1] === 'undefined' ? null : arguments[1];
|
199
|
-
|
200
|
-
/**
|
201
|
-
* the number of arguments is only one and it's an
|
202
|
-
* object - parse it for configuration data and return.
|
203
|
-
*/
|
204
|
-
if (arguments.length === 1 && typeof name === 'object') {
|
205
|
-
RG.parseObjectStyleConfig(this, name);
|
206
|
-
return this;
|
207
|
-
}
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
/**
|
213
|
-
* This should be done first - prepend the property name with "chart." if necessary
|
214
|
-
*/
|
215
|
-
if (name.substr(0,6) != 'chart.') {
|
216
|
-
name = 'chart.' + name;
|
217
|
-
}
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
// Convert uppercase letters to dot+lower case letter
|
223
|
-
while(name.match(/([A-Z])/)) {
|
224
|
-
name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
|
225
|
-
}
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
/**
|
233
|
-
* Change of name
|
234
|
-
*/
|
235
|
-
if (name == 'chart.ylabels.count') {
|
236
|
-
name = 'chart.labels.count';
|
237
|
-
}
|
238
|
-
prop[name.toLowerCase()] = value;
|
239
|
-
|
240
|
-
return this;
|
241
|
-
};
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
/**
|
247
|
-
* A getter.
|
248
|
-
*
|
249
|
-
* @param name string The name of the property to get
|
250
|
-
*/
|
251
|
-
this.get =
|
252
|
-
this.Get = function (name)
|
253
|
-
{
|
254
|
-
/**
|
255
|
-
* This should be done first - prepend the property name with "chart." if necessary
|
256
|
-
*/
|
257
|
-
if (name.substr(0,6) != 'chart.') {
|
258
|
-
name = 'chart.' + name;
|
259
|
-
}
|
260
|
-
|
261
|
-
// Convert uppercase letters to dot+lower case letter
|
262
|
-
while(name.match(/([A-Z])/)) {
|
263
|
-
name = name.replace(/([A-Z])/, '.' + RegExp.$1.toLowerCase());
|
264
|
-
}
|
265
|
-
|
266
|
-
return prop[name];
|
267
|
-
};
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
/**
|
273
|
-
* Draws the thermometer
|
274
|
-
*/
|
275
|
-
this.draw =
|
276
|
-
this.Draw = function ()
|
277
|
-
{
|
278
|
-
// Fire the custom RGraph onbeforedraw event (which should be fired before the chart is drawn)
|
279
|
-
RG.fireCustomEvent(this, 'onbeforedraw');
|
280
|
-
|
281
|
-
// Max/min boundary constraints
|
282
|
-
this.value = ma.min(this.max, this.value);
|
283
|
-
this.value = ma.max(this.min, this.value);
|
284
|
-
|
285
|
-
/**
|
286
|
-
* Parse the colors. This allows for simple gradient syntax
|
287
|
-
*/
|
288
|
-
if (!this.colorsParsed) {
|
289
|
-
this.parseColors();
|
290
|
-
|
291
|
-
// Don't want to do this again
|
292
|
-
this.colorsParsed = true;
|
293
|
-
}
|
294
|
-
|
295
|
-
/**
|
296
|
-
* Set the current value
|
297
|
-
*/
|
298
|
-
this.currentValue = this.value;
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
/**
|
303
|
-
* Stop this growing uncontrollably
|
304
|
-
*/
|
305
|
-
this.coordsText = [];
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
// This is new in May 2011 and facilitates indiviual gutter settings,
|
312
|
-
// eg chart.gutter.left
|
313
|
-
this.gutterLeft = prop['chart.gutter.left'];
|
314
|
-
this.gutterRight = prop['chart.gutter.right'];
|
315
|
-
this.gutterTop = prop['chart.gutter.top'];
|
316
|
-
this.gutterBottom = prop['chart.gutter.bottom'];
|
317
|
-
|
318
|
-
|
319
|
-
// Get the scale
|
320
|
-
this.scale2 = RG.getScale2(
|
321
|
-
this, {
|
322
|
-
max:this.max,
|
323
|
-
min:this.min,
|
324
|
-
strict:true,
|
325
|
-
'scale.thousand':prop['chart.scale.thousand'],
|
326
|
-
'scale.point':prop['chart.scale.point'],
|
327
|
-
'scale.decimals':prop['chart.scale.decimals'],
|
328
|
-
'ylabels.count':prop['chart.labels.count'],
|
329
|
-
'scale.round':prop['chart.scale.round'],
|
330
|
-
'units.pre': prop['chart.units.pre'],
|
331
|
-
'units.post': prop['chart.units.post']
|
332
|
-
}
|
333
|
-
);
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
// Work out the coordinates and positions
|
347
|
-
|
348
|
-
this.x = this.gutterLeft;
|
349
|
-
this.width = ca.width - this.gutterLeft - this.gutterRight;
|
350
|
-
this.y = this.gutterTop + (this.width / 2);
|
351
|
-
|
352
|
-
|
353
|
-
this.halfWidth = this.width / 2;
|
354
|
-
|
355
|
-
this.bulbTopCenterx = this.gutterLeft + (this.width / 2);
|
356
|
-
this.bulbTopCentery = this.gutterTop + (this.width / 2);
|
357
|
-
this.bulbTopRadius = this.width / 2;
|
358
|
-
this.bulbBottomCenterx = this.gutterLeft + (this.width / 2);
|
359
|
-
this.bulbBottomRadius = typeof prop['chart.bulb.bottom.radius'] === 'number' ? prop['chart.bulb.bottom.radius'] : this.width * 0.75 + prop['chart.bulb.bottom.radius.adjust'];
|
360
|
-
this.bulbBottomCentery = ca.height - this.gutterBottom - this.bulbBottomRadius;
|
361
|
-
|
362
|
-
this.scaleTopY = this.bulbTopCentery;
|
363
|
-
this.scaleBottomY = this.bulbBottomCentery - this.bulbBottomRadius;
|
364
|
-
this.scaleHeight = this.scaleBottomY - this.scaleTopY;
|
365
|
-
|
366
|
-
this.height = this.getYCoord(this.min) - this.getYCoord(this.value);
|
367
|
-
|
368
|
-
this.coords[0] = [
|
369
|
-
this.x,
|
370
|
-
this.getYCoord(this.value),
|
371
|
-
this.width,
|
372
|
-
this.height
|
373
|
-
];
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
// Draw the background
|
389
|
-
this.drawBackground();
|
390
|
-
|
391
|
-
// Draw the bar that represents the value
|
392
|
-
this.drawBar();
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
// Draw the tickmarks
|
398
|
-
this.drawTickMarks();
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
/**
|
403
|
-
* Draw the label
|
404
|
-
*/
|
405
|
-
this.drawLabels();
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
/**
|
410
|
-
* Draw the title
|
411
|
-
*/
|
412
|
-
if (prop['chart.title']) {
|
413
|
-
this.drawTitle();
|
414
|
-
}
|
415
|
-
|
416
|
-
/**
|
417
|
-
* Draw the side title
|
418
|
-
*/
|
419
|
-
if (prop['chart.title.side']) {
|
420
|
-
this.drawSideTitle();
|
421
|
-
}
|
422
|
-
|
423
|
-
/**
|
424
|
-
* This function enables resizing
|
425
|
-
*/
|
426
|
-
if (prop['chart.resizable']) {
|
427
|
-
RG.allowResizing(this);
|
428
|
-
}
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
/**
|
434
|
-
* Setup the context menu if required
|
435
|
-
*/
|
436
|
-
if (prop['chart.contextmenu']) {
|
437
|
-
RG.showContext(this);
|
438
|
-
}
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
/**
|
444
|
-
* This installs the event listeners
|
445
|
-
*/
|
446
|
-
RG.installEventListeners(this);
|
447
|
-
|
448
|
-
|
449
|
-
/**
|
450
|
-
* Fire the onfirstdraw event
|
451
|
-
*/
|
452
|
-
if (this.firstDraw) {
|
453
|
-
RG.fireCustomEvent(this, 'onfirstdraw');
|
454
|
-
this.firstDraw = false;
|
455
|
-
this.firstDrawFunc();
|
456
|
-
}
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
/**
|
461
|
-
* Fire the custom RGraph ondraw event (which should be fired when you have drawn the chart)
|
462
|
-
*/
|
463
|
-
RG.fireCustomEvent(this, 'ondraw');
|
464
|
-
|
465
|
-
return this;
|
466
|
-
};
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
/**
|
473
|
-
* Draws the thermometer itself
|
474
|
-
*/
|
475
|
-
this.drawBackground =
|
476
|
-
this.DrawBackground = function ()
|
477
|
-
{
|
478
|
-
if (prop['chart.shadow']) {
|
479
|
-
RG.setShadow(
|
480
|
-
this,
|
481
|
-
prop['chart.shadow.color'],
|
482
|
-
prop['chart.shadow.offsetx'],
|
483
|
-
prop['chart.shadow.offsety'],
|
484
|
-
prop['chart.shadow.blur']
|
485
|
-
);
|
486
|
-
}
|
487
|
-
|
488
|
-
// Draw the outline and background
|
489
|
-
this.pathBackground();
|
490
|
-
|
491
|
-
co.strokeStyle = prop['chart.strokestyle'];
|
492
|
-
co.fillStyle = prop['chart.background.color'];
|
493
|
-
co.lineWidth = 1 + prop['chart.linewidth'];
|
494
|
-
|
495
|
-
co.stroke();
|
496
|
-
co.fill();
|
497
|
-
|
498
|
-
co.lineWidth = 1;
|
499
|
-
};
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
/**
|
505
|
-
* This draws the bar that indicates the value of the thermometer. It makes use
|
506
|
-
* of the .pathBar() function.
|
507
|
-
*/
|
508
|
-
this.drawBar =
|
509
|
-
this.DrawBar = function ()
|
510
|
-
{
|
511
|
-
this.pathBar();
|
512
|
-
|
513
|
-
pa2(co, 'f %', prop['chart.colors'][0]);
|
514
|
-
};
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
//
|
520
|
-
// This function draws the path that indicates the specified value. It
|
521
|
-
// doesn't stroke or fill the path.
|
522
|
-
//
|
523
|
-
this.pathBar = function ()
|
524
|
-
{
|
525
|
-
var barHeight = this.coords[0][3],
|
526
|
-
y = (this.coords[0][1] + this.coords[0][3]) - barHeight
|
527
|
-
|
528
|
-
RG.noShadow(this);
|
529
|
-
|
530
|
-
// Draw the actual bar that indicates the value
|
531
|
-
pa2(co,
|
532
|
-
'b r % % % % a % % % 0 6.28 false',
|
533
|
-
|
534
|
-
this.coords[0][0],
|
535
|
-
y,
|
536
|
-
this.coords[0][2],
|
537
|
-
this.bulbBottomCentery - y,
|
538
|
-
|
539
|
-
this.bulbBottomCenterx,
|
540
|
-
this.bulbBottomCentery,
|
541
|
-
this.bulbBottomRadius
|
542
|
-
);
|
543
|
-
};
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
//
|
549
|
-
// This function draws the path that indicates that encompasses the
|
550
|
-
// background. It's used by the overChartArea() function.
|
551
|
-
//
|
552
|
-
this.pathBackground = function ()
|
553
|
-
{
|
554
|
-
pa2(
|
555
|
-
this.context,
|
556
|
-
'b r % % % % a % % % 0 6.28 false m % % a % % % 0 6.28 false',
|
557
|
-
|
558
|
-
this.x,
|
559
|
-
this.scaleTopY,
|
560
|
-
this.coords[0][2],
|
561
|
-
this.bulbBottomCentery - this.scaleTopY,
|
562
|
-
|
563
|
-
this.bulbTopCenterx,
|
564
|
-
this.bulbTopCentery,
|
565
|
-
this.bulbTopRadius,
|
566
|
-
|
567
|
-
this.bulbBottomCenterx,
|
568
|
-
this.bulbBottomCentery,
|
569
|
-
|
570
|
-
this.bulbBottomCenterx,
|
571
|
-
this.bulbBottomCentery,
|
572
|
-
this.bulbBottomRadius
|
573
|
-
);
|
574
|
-
};
|
575
|
-
|
576
|
-
|
577
|
-
|
578
|
-
|
579
|
-
/**
|
580
|
-
* Draws the tickmarks of the thermometer
|
581
|
-
*/
|
582
|
-
this.drawTickMarks =
|
583
|
-
this.DrawTickMarks = function ()
|
584
|
-
{
|
585
|
-
if (prop['chart.numticks']) {
|
586
|
-
|
587
|
-
var ticksize = prop['chart.ticksize'];
|
588
|
-
|
589
|
-
co.strokeStyle = prop['chart.strokestyle'];
|
590
|
-
co.lineWidth = prop['chart.linewidth'] / 2;
|
591
|
-
|
592
|
-
// Left hand side tickmarks
|
593
|
-
co.beginPath();
|
594
|
-
for (var i=0; i<=prop['chart.numticks']; ++i) {
|
595
|
-
|
596
|
-
var y = this.scaleBottomY - ((this.scaleHeight / prop['chart.numticks']) * i);
|
597
|
-
|
598
|
-
co.moveTo(this.gutterLeft, ma.round(y));
|
599
|
-
co.lineTo(this.gutterLeft + ticksize, ma.round(y));
|
600
|
-
|
601
|
-
// Right hand side tickmarks
|
602
|
-
co.moveTo(ca.width - this.gutterRight, ma.round(y));
|
603
|
-
co.lineTo(ca.width - this.gutterRight - ticksize, ma.round(y));
|
604
|
-
}
|
605
|
-
co.stroke();
|
606
|
-
|
607
|
-
co.lineWidth = 1;
|
608
|
-
}
|
609
|
-
};
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
/**
|
615
|
-
* Draws the labels of the thermometer. Now (4th August 2011) draws
|
616
|
-
* the scale too
|
617
|
-
*/
|
618
|
-
this.drawLabels =
|
619
|
-
this.DrawLabels = function ()
|
620
|
-
{
|
621
|
-
/**
|
622
|
-
* This draws draws the label that sits at the top of the chart
|
623
|
-
*/
|
624
|
-
if (prop['chart.value.label']) {
|
625
|
-
co.fillStyle = prop['chart.text.color'];
|
626
|
-
|
627
|
-
// Weird...
|
628
|
-
var text = prop['chart.scale.visible'] ?
|
629
|
-
RG.numberFormat(this,this.value.toFixed(typeof prop['chart.value.label.decimals'] == 'number' ? prop['chart.value.label.decimals'] : prop['chart.scale.decimals']))
|
630
|
-
:
|
631
|
-
RG.numberFormat(this,this.value.toFixed(typeof prop['chart.value.label.decimals'] == 'number' ? prop['chart.value.label.decimals'] : prop['chart.scale.decimals']),prop['chart.units.pre'],prop['chart.units.post']);
|
632
|
-
|
633
|
-
RG.text2(this, {
|
634
|
-
font: prop['chart.text.font'],
|
635
|
-
size: prop['chart.text.size'],
|
636
|
-
x: this.coords[0][0] + (this.coords[0][2] / 2),
|
637
|
-
y: this.coords[0][1] + 7,
|
638
|
-
text: text,
|
639
|
-
valign:'top',
|
640
|
-
halign:'center',
|
641
|
-
bounding:true,
|
642
|
-
boundingFill:'white',
|
643
|
-
tag: 'value.label'
|
644
|
-
});
|
645
|
-
}
|
646
|
-
|
647
|
-
|
648
|
-
/**
|
649
|
-
* Draw the scale if requested
|
650
|
-
*/
|
651
|
-
if (prop['chart.scale.visible']) {
|
652
|
-
this.drawScale();
|
653
|
-
}
|
654
|
-
};
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
/**
|
660
|
-
* Draws the title
|
661
|
-
*/
|
662
|
-
this.drawTitle =
|
663
|
-
this.DrawTitle = function ()
|
664
|
-
{
|
665
|
-
co.fillStyle = prop['chart.text.color'];
|
666
|
-
|
667
|
-
RG.text2(this, {
|
668
|
-
font: prop['chart.text.font'],
|
669
|
-
size: prop['chart.text.size'] + 2,
|
670
|
-
x: this.gutterLeft + (this.width / 2),
|
671
|
-
y: this.gutterTop - 3,
|
672
|
-
text: String(prop['chart.title']),
|
673
|
-
valign: 'bottom',
|
674
|
-
halign: 'center',
|
675
|
-
bold: true,
|
676
|
-
tag: 'title'
|
677
|
-
});
|
678
|
-
};
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
/**
|
684
|
-
* Draws the title
|
685
|
-
*/
|
686
|
-
this.drawSideTitle =
|
687
|
-
this.DrawSideTitle = function ()
|
688
|
-
{
|
689
|
-
var font = prop['chart.title.side.font'] ? prop['chart.title.side.font'] : prop['chart.text.font'];
|
690
|
-
var size = prop['chart.title.side.size'] ? prop['chart.title.side.size'] : prop['chart.text.size'] + 2;
|
691
|
-
|
692
|
-
co.fillStyle = prop['chart.text.color'];
|
693
|
-
RG.text2(this, {
|
694
|
-
font: font,
|
695
|
-
size: size + 2,
|
696
|
-
x: this.gutterLeft - 3,
|
697
|
-
y: (this.scaleHeight / 2) + this.gutterTop + this.bulbTopRadius,
|
698
|
-
text: String(prop['chart.title.side']),
|
699
|
-
valign: 'bottom',
|
700
|
-
halign: 'center',
|
701
|
-
angle: 270,
|
702
|
-
bold: prop['chart.title.side.bold'],
|
703
|
-
tag: 'title.side',
|
704
|
-
accessible: false
|
705
|
-
});
|
706
|
-
};
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
/**
|
712
|
-
* Draw the scale if requested
|
713
|
-
*/
|
714
|
-
this.drawScale =
|
715
|
-
this.DrawScale = function ()
|
716
|
-
{
|
717
|
-
co.fillStyle = prop['chart.text.color'];
|
718
|
-
|
719
|
-
var font = prop['chart.text.font'],
|
720
|
-
size = prop['chart.text.size'],
|
721
|
-
units_pre = prop['chart.units.pre'],
|
722
|
-
units_post = prop['chart.units.post'],
|
723
|
-
decimals = prop['chart.scale.decimals'],
|
724
|
-
numLabels = prop['chart.labels.count'],
|
725
|
-
step = (this.max - this.min) / numLabels;
|
726
|
-
|
727
|
-
for (var i=1; i<=numLabels; ++i) {
|
728
|
-
|
729
|
-
var x = ca.width - this.gutterRight + (prop['chart.linewidth'] / 2),
|
730
|
-
y = ca.height - this.gutterBottom - (2 * this.bulbBottomRadius) - ((this.scaleHeight / numLabels) * i),
|
731
|
-
text = RG.numberFormat(
|
732
|
-
this,
|
733
|
-
String((this.min + (i * step)).toFixed(decimals)),
|
734
|
-
units_pre,
|
735
|
-
units_post
|
736
|
-
);
|
737
|
-
|
738
|
-
RG.text2(this, {
|
739
|
-
font: font,
|
740
|
-
size: size,
|
741
|
-
x: x + 6,
|
742
|
-
y: y,
|
743
|
-
text: text,
|
744
|
-
valign: 'center',
|
745
|
-
tag: 'scale'
|
746
|
-
});
|
747
|
-
}
|
748
|
-
|
749
|
-
// Draw zero
|
750
|
-
RG.text2(this, {
|
751
|
-
font: font,
|
752
|
-
size: size,
|
753
|
-
x: x + 6,
|
754
|
-
y: this.bulbBottomCentery - this.bulbBottomRadius,
|
755
|
-
text: RG.numberFormat(
|
756
|
-
this,
|
757
|
-
this.min.toFixed(decimals),
|
758
|
-
units_pre,
|
759
|
-
units_post
|
760
|
-
),
|
761
|
-
valign: 'center',
|
762
|
-
tag: 'scale'
|
763
|
-
});
|
764
|
-
};
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
/**
|
770
|
-
* Returns the focused/clicked bar
|
771
|
-
*
|
772
|
-
* @param event e The event object
|
773
|
-
*/
|
774
|
-
this.getShape =
|
775
|
-
this.getBar = function (e)
|
776
|
-
{
|
777
|
-
var mouseXY = RG.getMouseXY(e),
|
778
|
-
mouseX = mouseXY[0],
|
779
|
-
mouseY = mouseXY[1];
|
780
|
-
|
781
|
-
for (var i=0; i<this.coords.length; i++) {
|
782
|
-
|
783
|
-
var coords = this.coords[i],
|
784
|
-
left = coords[0],
|
785
|
-
top = coords[1],
|
786
|
-
width = coords[2],
|
787
|
-
height = coords[3];
|
788
|
-
|
789
|
-
this.pathBar();
|
790
|
-
|
791
|
-
if (co.isPointInPath(mouseX, mouseY)) {
|
792
|
-
|
793
|
-
var tooltip = RG.parseTooltipText ? RG.parseTooltipText(prop['chart.tooltips'], i) : '';
|
794
|
-
|
795
|
-
return {
|
796
|
-
0: this, object: this,
|
797
|
-
1: left, x: left,
|
798
|
-
2: top, y: top,
|
799
|
-
3: width, width: width,
|
800
|
-
4: height, height: height,
|
801
|
-
5: i, index: i,
|
802
|
-
tooltip: tooltip
|
803
|
-
};
|
804
|
-
}
|
805
|
-
}
|
806
|
-
|
807
|
-
return null;
|
808
|
-
};
|
809
|
-
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
/**
|
814
|
-
* This function returns the value that the mouse is positioned t, regardless of
|
815
|
-
* the actual indicated value.
|
816
|
-
*
|
817
|
-
* @param object e The event object (or it can also be an two element array containing the X/Y coords)
|
818
|
-
*/
|
819
|
-
this.getValue = function (arg)
|
820
|
-
{
|
821
|
-
if (arg.length === 2) {
|
822
|
-
var mouseX = arg[0],
|
823
|
-
mouseY = arg[1];
|
824
|
-
} else {
|
825
|
-
var mouseXY = RG.getMouseXY(arg),
|
826
|
-
mouseX = mouseXY[0],
|
827
|
-
mouseY = mouseXY[1];
|
828
|
-
}
|
829
|
-
|
830
|
-
var value = (this.scaleHeight - (mouseY - this.scaleTopY)) / this.scaleHeight;
|
831
|
-
value *= (this.max - this.min);
|
832
|
-
value += this.min;
|
833
|
-
|
834
|
-
value = ma.max(value, this.min);
|
835
|
-
value = ma.min(value, this.max);
|
836
|
-
|
837
|
-
return value;
|
838
|
-
};
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
/**
|
844
|
-
* Each object type has its own Highlight() function which highlights the appropriate shape
|
845
|
-
*
|
846
|
-
* @param object shape The shape to highlight
|
847
|
-
*/
|
848
|
-
this.highlight =
|
849
|
-
this.Highlight = function (shape)
|
850
|
-
{
|
851
|
-
if (prop['chart.tooltips.highlight']) {
|
852
|
-
|
853
|
-
if (typeof prop['chart.highlight.style'] === 'function') {
|
854
|
-
(prop['chart.highlight.style'])(shape);
|
855
|
-
return;
|
856
|
-
}
|
857
|
-
|
858
|
-
this.pathBar();
|
859
|
-
|
860
|
-
pa2(co, 's % f %',
|
861
|
-
prop['chart.highlight.stroke'],
|
862
|
-
prop['chart.highlight.fill']
|
863
|
-
);
|
864
|
-
}
|
865
|
-
};
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
/**
|
871
|
-
* The getObjectByXY() worker method. Don't call this - call:
|
872
|
-
*
|
873
|
-
* RGraph.ObjectRegistry.getObjectByXY(e)
|
874
|
-
*
|
875
|
-
* @param object e The event object
|
876
|
-
*/
|
877
|
-
this.getObjectByXY = function (e)
|
878
|
-
{
|
879
|
-
|
880
|
-
var mouseXY = RG.getMouseXY(e),
|
881
|
-
mouseX = mouseXY[0],
|
882
|
-
mouseY = mouseXY[1]
|
883
|
-
|
884
|
-
// Draw the background shape (don't stroke or fill it)
|
885
|
-
this.pathBackground();
|
886
|
-
|
887
|
-
if (co.isPointInPath(mouseX, mouseY)) {
|
888
|
-
return this;
|
889
|
-
}
|
890
|
-
};
|
891
|
-
|
892
|
-
|
893
|
-
|
894
|
-
|
895
|
-
/**
|
896
|
-
* This method handles the adjusting calculation for when the mouse is moved
|
897
|
-
*
|
898
|
-
* @param object e The event object
|
899
|
-
*/
|
900
|
-
this.adjusting_mousemove =
|
901
|
-
this.Adjusting_mousemove = function (e)
|
902
|
-
{
|
903
|
-
/**
|
904
|
-
* Handle adjusting for the Thermometer
|
905
|
-
*/
|
906
|
-
if (prop['chart.adjustable'] && RG.Registry.get('chart.adjusting') && RG.Registry.Get('chart.adjusting').uid == this.uid) {
|
907
|
-
|
908
|
-
var mouseXY = RG.getMouseXY(e),
|
909
|
-
value = this.getValue(e);
|
910
|
-
|
911
|
-
if (typeof(value) == 'number') {
|
912
|
-
|
913
|
-
// Fire the onadjust event
|
914
|
-
RG.fireCustomEvent(this, 'onadjust');
|
915
|
-
|
916
|
-
this.value = Number(value.toFixed(prop['chart.scale.decimals']));
|
917
|
-
|
918
|
-
RG.redrawCanvas(ca);
|
919
|
-
}
|
920
|
-
}
|
921
|
-
};
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
/**
|
927
|
-
* Returns the appropriate Y coord for a value
|
928
|
-
*
|
929
|
-
* @param number value The value to return the coord for
|
930
|
-
*/
|
931
|
-
this.getYCoord = function (value)
|
932
|
-
{
|
933
|
-
if (value > this.max || value < this.min) {
|
934
|
-
return null;
|
935
|
-
}
|
936
|
-
|
937
|
-
var y = ma.abs(value - this.min) / ma.abs(this.max - this.min)
|
938
|
-
y = y * (this.scaleBottomY - this.scaleTopY);
|
939
|
-
|
940
|
-
|
941
|
-
return this.scaleBottomY - y;
|
942
|
-
};
|
943
|
-
|
944
|
-
|
945
|
-
|
946
|
-
|
947
|
-
/**
|
948
|
-
* This returns true/false as to whether the cursor is over the chart area.
|
949
|
-
* The cursor does not necessarily have to be over the bar itself.
|
950
|
-
*/
|
951
|
-
this.overChartArea = function (e)
|
952
|
-
{
|
953
|
-
var mouseXY = RG.getMouseXY(e),
|
954
|
-
mouseX = mouseXY[0],
|
955
|
-
mouseY = mouseXY[1];
|
956
|
-
|
957
|
-
this.pathBackground();
|
958
|
-
|
959
|
-
return co.isPointInPath(mouseX, mouseY);
|
960
|
-
};
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
/**
|
966
|
-
* This allows for easy specification of gradients
|
967
|
-
*/
|
968
|
-
this.parseColors = function ()
|
969
|
-
{
|
970
|
-
// Save the original colors so that they can be restored when the canvas is reset
|
971
|
-
if (this.original_colors.length === 0) {
|
972
|
-
this.original_colors['chart.colors'] = RG.arrayClone(prop['chart.colors']);
|
973
|
-
}
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
var colors = prop['chart.colors'];
|
980
|
-
|
981
|
-
for (var i=0; i<colors.length; ++i) {
|
982
|
-
colors[i] = this.parseSingleColorForGradient(colors[i]);
|
983
|
-
}
|
984
|
-
};
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
/**
|
990
|
-
* Use this function to reset the object to the post-constructor state. Eg reset colors if
|
991
|
-
* need be etc
|
992
|
-
*/
|
993
|
-
this.reset = function ()
|
994
|
-
{
|
995
|
-
};
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
/**
|
1001
|
-
* This parses a single color value
|
1002
|
-
*/
|
1003
|
-
this.parseSingleColorForGradient = function (color)
|
1004
|
-
{
|
1005
|
-
if (!color) {
|
1006
|
-
return color;
|
1007
|
-
}
|
1008
|
-
|
1009
|
-
if (typeof color === 'string' && color.match(/^gradient\((.*)\)$/i)) {
|
1010
|
-
|
1011
|
-
var parts = RegExp.$1.split(':');
|
1012
|
-
|
1013
|
-
// Create the gradient
|
1014
|
-
var grad = co.createLinearGradient(
|
1015
|
-
prop['chart.gutter.left'],
|
1016
|
-
0,
|
1017
|
-
ca.width - prop['chart.gutter.right'],
|
1018
|
-
0
|
1019
|
-
);
|
1020
|
-
|
1021
|
-
var diff = 1 / (parts.length - 1);
|
1022
|
-
|
1023
|
-
grad.addColorStop(0, RG.trim(parts[0]));
|
1024
|
-
|
1025
|
-
for (var j=1; j<parts.length; ++j) {
|
1026
|
-
grad.addColorStop(j * diff, RG.trim(parts[j]));
|
1027
|
-
}
|
1028
|
-
}
|
1029
|
-
|
1030
|
-
return grad ? grad : color;
|
1031
|
-
};
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
1035
|
-
|
1036
|
-
/**
|
1037
|
-
* Using a function to add events makes it easier to facilitate method chaining
|
1038
|
-
*
|
1039
|
-
* @param string type The type of even to add
|
1040
|
-
* @param function func
|
1041
|
-
*/
|
1042
|
-
this.on = function (type, func)
|
1043
|
-
{
|
1044
|
-
if (type.substr(0,2) !== 'on') {
|
1045
|
-
type = 'on' + type;
|
1046
|
-
}
|
1047
|
-
|
1048
|
-
if (typeof this[type] !== 'function') {
|
1049
|
-
this[type] = func;
|
1050
|
-
} else {
|
1051
|
-
RG.addCustomEventListener(this, type, func);
|
1052
|
-
}
|
1053
|
-
|
1054
|
-
return this;
|
1055
|
-
};
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
/**
|
1061
|
-
* This function runs once only
|
1062
|
-
* (put at the end of the file (before any effects))
|
1063
|
-
*/
|
1064
|
-
this.firstDrawFunc = function ()
|
1065
|
-
{
|
1066
|
-
};
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
|
1071
|
-
/**
|
1072
|
-
* Gauge Grow
|
1073
|
-
*
|
1074
|
-
* This effect gradually increases the represented value
|
1075
|
-
*
|
1076
|
-
* @param object obj The chart object
|
1077
|
-
* @param Not used - pass null
|
1078
|
-
* @param function An optional callback function
|
1079
|
-
*/
|
1080
|
-
this.grow = function ()
|
1081
|
-
{
|
1082
|
-
var obj = this,
|
1083
|
-
callback = arguments[1] || function () {},
|
1084
|
-
opt = arguments[0] || {},
|
1085
|
-
frames = opt.frames ? opt.frames : 30,
|
1086
|
-
origValue = Number(obj.currentValue),
|
1087
|
-
newValue = obj.value;
|
1088
|
-
|
1089
|
-
newValue = ma.min(newValue, this.max);
|
1090
|
-
newValue = ma.max(newValue, this.min);
|
1091
|
-
|
1092
|
-
var diff = newValue - origValue,
|
1093
|
-
step = (diff / frames),
|
1094
|
-
frame = 0;
|
1095
|
-
|
1096
|
-
|
1097
|
-
function iterate ()
|
1098
|
-
{
|
1099
|
-
// Set the new value
|
1100
|
-
obj.value = (step * frame) + origValue;
|
1101
|
-
|
1102
|
-
RG.clear(obj.canvas);
|
1103
|
-
RG.redrawCanvas(obj.canvas);
|
1104
|
-
|
1105
|
-
if (frame < frames) {
|
1106
|
-
frame++;
|
1107
|
-
RG.Effects.updateCanvas(iterate);
|
1108
|
-
} else {
|
1109
|
-
callback(obj);
|
1110
|
-
}
|
1111
|
-
}
|
1112
|
-
|
1113
|
-
iterate();
|
1114
|
-
|
1115
|
-
return this;
|
1116
|
-
};
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
|
1121
|
-
|
1122
|
-
/**
|
1123
|
-
* Now, because canvases can support multiple charts, canvases must always be registered
|
1124
|
-
*/
|
1125
|
-
RG.register(this);
|
1126
|
-
|
1127
|
-
|
1128
|
-
|
1129
|
-
|
1130
|
-
/**
|
1131
|
-
* This is the 'end' of the constructor so if the first argument
|
1132
|
-
* contains configuration data - handle that.
|
1133
|
-
*/
|
1134
|
-
if (parseConfObjectForOptions) {
|
1135
|
-
RG.parseObjectStyleConfig(this, conf.options);
|
1136
|
-
}
|
1137
|
-
};
|
2
|
+
RGraph=window.RGraph||{isRGraph:true};RGraph.Thermometer=function(conf)
|
3
|
+
{if(typeof conf==='object'&&typeof conf.id==='string'){var parseConfObjectForOptions=true;}else{var conf={id:arguments[0],min:arguments[1],max:arguments[2],value:arguments[3]}}
|
4
|
+
this.id=conf.id;this.canvas=document.getElementById(this.id);this.context=this.canvas.getContext?this.canvas.getContext('2d'):null;this.canvas.__object__=this;this.uid=RGraph.CreateUID();this.canvas.uid=this.canvas.uid?this.canvas.uid:RGraph.CreateUID();this.colorsParsed=false;this.type='thermometer';this.isRGraph=true;this.min=RGraph.stringsToNumbers(conf.min);this.max=RGraph.stringsToNumbers(conf.max);this.value=RGraph.stringsToNumbers(conf.value);this.coords=[];this.graphArea=[];this.currentValue=null;this.coordsText=[];this.original_colors=[];this.firstDraw=true;this.properties={'chart.linewidth':1,'chart.background.color':'white','chart.strokestyle':'black','chart.colors':['Gradient(#c00:red:#f66:#fcc)'],'chart.gutter.left':25,'chart.gutter.right':25,'chart.gutter.top':25,'chart.gutter.bottom':25,'chart.ticksize':2,'chart.text.color':'black','chart.text.font':'Segoe UI, Arial, Verdana, sans-serif','chart.text.size':12,'chart.text.accessible':true,'chart.text.accessible.overflow':'visible','chart.text.accessible.pointerevents':true,'chart.numticks':10,'chart.units.pre':'','chart.units.post':'','chart.zoom.factor':1.5,'chart.zoom.fade.in':true,'chart.zoom.fade.out':true,'chart.zoom.hdir':'right','chart.zoom.vdir':'down','chart.zoom.frames':25,'chart.zoom.delay':16.666,'chart.zoom.shadow':true,'chart.zoom.background':true,'chart.title':'','chart.title.side':'','chart.title.side.bold':true,'chart.title.side.font':null,'chart.shadow':true,'chart.shadow.offsetx':0,'chart.shadow.offsety':0,'chart.shadow.blur':15,'chart.shadow.color':'#ddd','chart.resizable':false,'chart.contextmenu':null,'chart.adjustable':false,'chart.value.label':true,'chart.value.label.decimals':null,'chart.value.label.thousand':',','chart.value.label.point':'.','chart.labels.count':5,'chart.scale.visible':false,'chart.scale.decimals':0,'chart.annotatable':false,'chart.annotate.color':'black','chart.scale.decimals':0,'chart.scale.point':'.','chart.scale.thousand':',','chart.tooltips':null,'chart.tooltips.highlight':true,'chart.tooltips.effect':'fade','chart.tooltips.event':'onclick','chart.highlight.stroke':'rgba(0,0,0,0)','chart.highlight.fill':'rgba(255,255,255,0.7)','chart.clearto':'rgba(0,0,0,0)','chart.bulb.bottom.radius.adjust':0,'chart.bulb.bottom.radius':null}
|
5
|
+
if(!this.canvas){alert('[THERMOMETER] No canvas support');return;}
|
6
|
+
this.$0={};if(!this.canvas.__rgraph_aa_translated__){this.context.translate(0.5,0.5);this.canvas.__rgraph_aa_translated__=true;}
|
7
|
+
var RG=RGraph,ca=this.canvas,co=ca.getContext('2d'),prop=this.properties,pa2=RG.path2,win=window,doc=document,ma=Math
|
8
|
+
if(RG.Effects&&typeof RG.Effects.decorate==='function'){RG.Effects.decorate(this);}
|
9
|
+
this.set=this.Set=function(name)
|
10
|
+
{var value=typeof arguments[1]==='undefined'?null:arguments[1];if(arguments.length===1&&typeof name==='object'){RG.parseObjectStyleConfig(this,name);return this;}
|
11
|
+
if(name.substr(0,6)!='chart.'){name='chart.'+name;}
|
12
|
+
while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
|
13
|
+
if(name=='chart.ylabels.count'){name='chart.labels.count';}
|
14
|
+
prop[name.toLowerCase()]=value;return this;};this.get=this.Get=function(name)
|
15
|
+
{if(name.substr(0,6)!='chart.'){name='chart.'+name;}
|
16
|
+
while(name.match(/([A-Z])/)){name=name.replace(/([A-Z])/,'.'+RegExp.$1.toLowerCase());}
|
17
|
+
return prop[name];};this.draw=this.Draw=function()
|
18
|
+
{RG.fireCustomEvent(this,'onbeforedraw');this.value=ma.min(this.max,this.value);this.value=ma.max(this.min,this.value);if(!this.colorsParsed){this.parseColors();this.colorsParsed=true;}
|
19
|
+
this.currentValue=this.value;this.coordsText=[];this.gutterLeft=prop['chart.gutter.left'];this.gutterRight=prop['chart.gutter.right'];this.gutterTop=prop['chart.gutter.top'];this.gutterBottom=prop['chart.gutter.bottom'];this.scale2=RG.getScale2(this,{max:this.max,min:this.min,strict:true,'scale.thousand':prop['chart.scale.thousand'],'scale.point':prop['chart.scale.point'],'scale.decimals':prop['chart.scale.decimals'],'ylabels.count':prop['chart.labels.count'],'scale.round':prop['chart.scale.round'],'units.pre':prop['chart.units.pre'],'units.post':prop['chart.units.post']});this.x=this.gutterLeft;this.width=ca.width-this.gutterLeft-this.gutterRight;this.y=this.gutterTop+(this.width/2);this.halfWidth=this.width/2;this.bulbTopCenterx=this.gutterLeft+(this.width/2);this.bulbTopCentery=this.gutterTop+(this.width/2);this.bulbTopRadius=this.width/2;this.bulbBottomCenterx=this.gutterLeft+(this.width/2);this.bulbBottomRadius=typeof prop['chart.bulb.bottom.radius']==='number'?prop['chart.bulb.bottom.radius']:this.width*0.75+prop['chart.bulb.bottom.radius.adjust'];this.bulbBottomCentery=ca.height-this.gutterBottom-this.bulbBottomRadius;this.scaleTopY=this.bulbTopCentery;this.scaleBottomY=this.bulbBottomCentery-this.bulbBottomRadius;this.scaleHeight=this.scaleBottomY-this.scaleTopY;this.height=this.getYCoord(this.min)-this.getYCoord(this.value);this.coords[0]=[this.x,this.getYCoord(this.value),this.width,this.height];this.drawBackground();this.drawBar();this.drawTickMarks();this.drawLabels();if(prop['chart.title']){this.drawTitle();}
|
20
|
+
if(prop['chart.title.side']){this.drawSideTitle();}
|
21
|
+
if(prop['chart.resizable']){RG.allowResizing(this);}
|
22
|
+
if(prop['chart.contextmenu']){RG.showContext(this);}
|
23
|
+
RG.installEventListeners(this);if(this.firstDraw){this.firstDraw=false;RG.fireCustomEvent(this,'onfirstdraw');this.firstDrawFunc();}
|
24
|
+
RG.fireCustomEvent(this,'ondraw');return this;};this.drawBackground=this.DrawBackground=function()
|
25
|
+
{if(prop['chart.shadow']){RG.setShadow(this,prop['chart.shadow.color'],prop['chart.shadow.offsetx'],prop['chart.shadow.offsety'],prop['chart.shadow.blur']);}
|
26
|
+
this.pathBackground();co.strokeStyle=prop['chart.strokestyle'];co.fillStyle=prop['chart.background.color'];co.lineWidth=1+prop['chart.linewidth'];co.stroke();co.fill();co.lineWidth=1;};this.drawBar=this.DrawBar=function()
|
27
|
+
{this.pathBar();pa2(co,'f %',prop['chart.colors'][0]);};this.pathBar=function()
|
28
|
+
{var barHeight=this.coords[0][3],y=(this.coords[0][1]+this.coords[0][3])-barHeight
|
29
|
+
RG.noShadow(this);pa2(co,'b r % % % % a % % % 0 6.28 false',this.coords[0][0],y,this.coords[0][2],this.bulbBottomCentery-y,this.bulbBottomCenterx,this.bulbBottomCentery,this.bulbBottomRadius);};this.pathBackground=function()
|
30
|
+
{pa2(this.context,'b r % % % % a % % % 0 6.28 false m % % a % % % 0 6.28 false',this.x,this.scaleTopY,this.coords[0][2],this.bulbBottomCentery-this.scaleTopY,this.bulbTopCenterx,this.bulbTopCentery,this.bulbTopRadius,this.bulbBottomCenterx,this.bulbBottomCentery,this.bulbBottomCenterx,this.bulbBottomCentery,this.bulbBottomRadius);};this.drawTickMarks=this.DrawTickMarks=function()
|
31
|
+
{if(prop['chart.numticks']){var ticksize=prop['chart.ticksize'];co.strokeStyle=prop['chart.strokestyle'];co.lineWidth=prop['chart.linewidth']/2;co.beginPath();for(var i=0;i<=prop['chart.numticks'];++i){var y=this.scaleBottomY-((this.scaleHeight/prop['chart.numticks'])*i);co.moveTo(this.gutterLeft,ma.round(y));co.lineTo(this.gutterLeft+ticksize,ma.round(y));co.moveTo(ca.width-this.gutterRight,ma.round(y));co.lineTo(ca.width-this.gutterRight-ticksize,ma.round(y));}
|
32
|
+
co.stroke();co.lineWidth=1;}};this.drawLabels=this.DrawLabels=function()
|
33
|
+
{if(prop['chart.value.label']){co.fillStyle=prop['chart.text.color'];var text=prop['chart.scale.visible']?RG.numberFormat(this,this.value.toFixed(typeof prop['chart.value.label.decimals']=='number'?prop['chart.value.label.decimals']:prop['chart.scale.decimals'])):RG.numberFormat(this,this.value.toFixed(typeof prop['chart.value.label.decimals']=='number'?prop['chart.value.label.decimals']:prop['chart.scale.decimals']),prop['chart.units.pre'],prop['chart.units.post']);RG.text2(this,{font:prop['chart.text.font'],size:prop['chart.text.size'],x:this.coords[0][0]+(this.coords[0][2]/2),y:this.coords[0][1]+7,text:text,valign:'top',halign:'center',bounding:true,boundingFill:'white',tag:'value.label'});}
|
34
|
+
if(prop['chart.scale.visible']){this.drawScale();}};this.drawTitle=this.DrawTitle=function()
|
35
|
+
{co.fillStyle=prop['chart.text.color'];RG.text2(this,{font:prop['chart.text.font'],size:prop['chart.text.size']+2,x:this.gutterLeft+(this.width/2),y:this.gutterTop-3,text:String(prop['chart.title']),valign:'bottom',halign:'center',bold:true,tag:'title'});};this.drawSideTitle=this.DrawSideTitle=function()
|
36
|
+
{var font=prop['chart.title.side.font']?prop['chart.title.side.font']:prop['chart.text.font'];var size=prop['chart.title.side.size']?prop['chart.title.side.size']:prop['chart.text.size']+2;co.fillStyle=prop['chart.text.color'];RG.text2(this,{font:font,size:size+2,x:this.gutterLeft-3,y:(this.scaleHeight/2)+this.gutterTop+this.bulbTopRadius,text:String(prop['chart.title.side']),valign:'bottom',halign:'center',angle:270,bold:prop['chart.title.side.bold'],tag:'title.side',accessible:false});};this.drawScale=this.DrawScale=function()
|
37
|
+
{co.fillStyle=prop['chart.text.color'];var font=prop['chart.text.font'],size=prop['chart.text.size'],units_pre=prop['chart.units.pre'],units_post=prop['chart.units.post'],decimals=prop['chart.scale.decimals'],numLabels=prop['chart.labels.count'],step=(this.max-this.min)/numLabels;for(var i=1;i<=numLabels;++i){var x=ca.width-this.gutterRight+(prop['chart.linewidth']/2),y=ca.height-this.gutterBottom-(2*this.bulbBottomRadius)-((this.scaleHeight/numLabels)*i),text=RG.numberFormat(this,String((this.min+(i*step)).toFixed(decimals)),units_pre,units_post);RG.text2(this,{font:font,size:size,x:x+6,y:y,text:text,valign:'center',tag:'scale'});}
|
38
|
+
RG.text2(this,{font:font,size:size,x:x+6,y:this.bulbBottomCentery-this.bulbBottomRadius,text:RG.numberFormat(this,this.min.toFixed(decimals),units_pre,units_post),valign:'center',tag:'scale'});};this.getShape=this.getBar=function(e)
|
39
|
+
{var mouseXY=RG.getMouseXY(e),mouseX=mouseXY[0],mouseY=mouseXY[1];for(var i=0;i<this.coords.length;i++){var coords=this.coords[i],left=coords[0],top=coords[1],width=coords[2],height=coords[3];this.pathBar();if(co.isPointInPath(mouseX,mouseY)){var tooltip=RG.parseTooltipText?RG.parseTooltipText(prop['chart.tooltips'],i):'';return{0:this,object:this,1:left,x:left,2:top,y:top,3:width,width:width,4:height,height:height,5:i,index:i,tooltip:tooltip};}}
|
40
|
+
return null;};this.getValue=function(arg)
|
41
|
+
{if(arg.length===2){var mouseX=arg[0],mouseY=arg[1];}else{var mouseXY=RG.getMouseXY(arg),mouseX=mouseXY[0],mouseY=mouseXY[1];}
|
42
|
+
var value=(this.scaleHeight-(mouseY-this.scaleTopY))/this.scaleHeight;value*=(this.max-this.min);value+=this.min;value=ma.max(value,this.min);value=ma.min(value,this.max);return value;};this.highlight=this.Highlight=function(shape)
|
43
|
+
{if(prop['chart.tooltips.highlight']){if(typeof prop['chart.highlight.style']==='function'){(prop['chart.highlight.style'])(shape);return;}
|
44
|
+
this.pathBar();pa2(co,'s % f %',prop['chart.highlight.stroke'],prop['chart.highlight.fill']);}};this.getObjectByXY=function(e)
|
45
|
+
{var mouseXY=RG.getMouseXY(e),mouseX=mouseXY[0],mouseY=mouseXY[1]
|
46
|
+
this.pathBackground();if(co.isPointInPath(mouseX,mouseY)){return this;}};this.adjusting_mousemove=this.Adjusting_mousemove=function(e)
|
47
|
+
{if(prop['chart.adjustable']&&RG.Registry.get('chart.adjusting')&&RG.Registry.Get('chart.adjusting').uid==this.uid){var mouseXY=RG.getMouseXY(e),value=this.getValue(e);if(typeof(value)=='number'){RG.fireCustomEvent(this,'onadjust');this.value=Number(value.toFixed(prop['chart.scale.decimals']));RG.redrawCanvas(ca);}}};this.getYCoord=function(value)
|
48
|
+
{if(value>this.max||value<this.min){return null;}
|
49
|
+
var y=ma.abs(value-this.min)/ma.abs(this.max-this.min)
|
50
|
+
y=y*(this.scaleBottomY-this.scaleTopY);return this.scaleBottomY-y;};this.overChartArea=function(e)
|
51
|
+
{var mouseXY=RG.getMouseXY(e),mouseX=mouseXY[0],mouseY=mouseXY[1];this.pathBackground();return co.isPointInPath(mouseX,mouseY);};this.parseColors=function()
|
52
|
+
{if(this.original_colors.length===0){this.original_colors['chart.colors']=RG.arrayClone(prop['chart.colors']);}
|
53
|
+
var colors=prop['chart.colors'];for(var i=0;i<colors.length;++i){colors[i]=this.parseSingleColorForGradient(colors[i]);}};this.reset=function()
|
54
|
+
{};this.parseSingleColorForGradient=function(color)
|
55
|
+
{if(!color){return color;}
|
56
|
+
if(typeof color==='string'&&color.match(/^gradient\((.*)\)$/i)){var parts=RegExp.$1.split(':');var grad=co.createLinearGradient(prop['chart.gutter.left'],0,ca.width-prop['chart.gutter.right'],0);var diff=1/(parts.length-1);grad.addColorStop(0,RG.trim(parts[0]));for(var j=1;j<parts.length;++j){grad.addColorStop(j*diff,RG.trim(parts[j]));}}
|
57
|
+
return grad?grad:color;};this.on=function(type,func)
|
58
|
+
{if(type.substr(0,2)!=='on'){type='on'+type;}
|
59
|
+
if(typeof this[type]!=='function'){this[type]=func;}else{RG.addCustomEventListener(this,type,func);}
|
60
|
+
return this;};this.firstDrawFunc=function()
|
61
|
+
{};this.grow=function()
|
62
|
+
{var obj=this,callback=arguments[1]||function(){},opt=arguments[0]||{},frames=opt.frames?opt.frames:30,origValue=Number(obj.currentValue),newValue=obj.value;newValue=ma.min(newValue,this.max);newValue=ma.max(newValue,this.min);var diff=newValue-origValue,step=(diff/frames),frame=0;function iterate()
|
63
|
+
{obj.value=(step*frame)+origValue;RG.clear(obj.canvas);RG.redrawCanvas(obj.canvas);if(frame<frames){frame++;RG.Effects.updateCanvas(iterate);}else{callback(obj);}}
|
64
|
+
iterate();return this;};RG.register(this);if(parseConfObjectForOptions){RG.parseObjectStyleConfig(this,conf.options);}};
|