justgage-rails 1.0.1.2 → 1.0.2.rc1
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.
@@ -1,474 +1,706 @@
|
|
1
|
-
/**
|
2
|
-
* JustGage -
|
3
|
-
*
|
4
|
-
* Licensed under MIT.
|
5
|
-
*
|
6
|
-
*
|
7
|
-
*
|
8
|
-
*
|
9
|
-
*
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
}
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
//
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
1
|
+
/**
|
2
|
+
* JustGage - this is work-in-progress, unreleased, unofficial code, so it might not work top-notch :)
|
3
|
+
* Check http://www.justgage.com for official releases
|
4
|
+
* Licensed under MIT.
|
5
|
+
* @author Bojan Djuricic (@Toorshia)
|
6
|
+
*
|
7
|
+
* LATEST UPDATES
|
8
|
+
* -----------------------------
|
9
|
+
* November 25, 2012.
|
10
|
+
* -----------------------------
|
11
|
+
* Option to define custom rendering function for displayed value
|
12
|
+
* -----------------------------
|
13
|
+
* November 19, 2012.
|
14
|
+
* -----------------------------
|
15
|
+
* Config.value is now updated after gauge refresh
|
16
|
+
* -----------------------------
|
17
|
+
* November 13, 2012.
|
18
|
+
* -----------------------------
|
19
|
+
* Donut display mode added
|
20
|
+
* Option to hide value label
|
21
|
+
* Option to enable responsive gauge size
|
22
|
+
* Removed default title attribute
|
23
|
+
* Option to accept min and max defined as string values
|
24
|
+
* Option to configure value symbol
|
25
|
+
* Fixed bad aspect ratio calculations
|
26
|
+
* Option to configure minimum font size for all texts
|
27
|
+
* Option to show shorthand big numbers (human friendly)
|
28
|
+
*/
|
29
|
+
|
30
|
+
JustGage = function(config) {
|
31
|
+
|
32
|
+
if (!config.id) {alert("Missing id parameter for gauge!"); return false;}
|
33
|
+
if (!document.getElementById(config.id)) {alert("No element with id: \""+config.id+"\" found!"); return false;}
|
34
|
+
|
35
|
+
// configurable parameters
|
36
|
+
this.config =
|
37
|
+
{
|
38
|
+
// id : string
|
39
|
+
// this is container element id
|
40
|
+
id : config.id,
|
41
|
+
|
42
|
+
// title : string
|
43
|
+
// gauge title
|
44
|
+
title : (config.title) ? config.title : "",
|
45
|
+
|
46
|
+
// titleFontColor : string
|
47
|
+
// color of gauge title
|
48
|
+
titleFontColor : (config.titleFontColor) ? config.titleFontColor : "#999999",
|
49
|
+
|
50
|
+
// value : int
|
51
|
+
// value gauge is showing
|
52
|
+
value : (config.value) ? config.value : 0,
|
53
|
+
|
54
|
+
// symbol : string
|
55
|
+
// special symbol to show next to value
|
56
|
+
symbol : (config.symbol) ? config.symbol : "",
|
57
|
+
|
58
|
+
// valueFontColor : string
|
59
|
+
// color of label showing current value
|
60
|
+
valueFontColor : (config.valueFontColor) ? config.valueFontColor : "#010101",
|
61
|
+
|
62
|
+
// showValue : bool
|
63
|
+
// hide or display value text
|
64
|
+
showValue : (config.showValue != null) ? config.showValue : true,
|
65
|
+
|
66
|
+
// min : int
|
67
|
+
// min value
|
68
|
+
min : (config.min) ? parseFloat(config.min) : 0,
|
69
|
+
|
70
|
+
// max : int
|
71
|
+
// max value
|
72
|
+
max : (config.max) ? parseFloat(config.max) : 100,
|
73
|
+
|
74
|
+
// showMinMax : bool
|
75
|
+
// hide or display min and max values
|
76
|
+
showMinMax : (config.showMinMax != null) ? config.showMinMax : true,
|
77
|
+
|
78
|
+
// humanFriendly : bool
|
79
|
+
// convert large numbers for min, max, value to human friendly (e.g. 1234567 -> 1.23M)
|
80
|
+
humanFriendly : (config.humanFriendly) ? config.humanFriendly : false,
|
81
|
+
|
82
|
+
// humanFriendlyDecimal : int
|
83
|
+
// number of decimal places for our human friendly number to contain
|
84
|
+
humanFriendlyDecimal : (config.humanFriendlyDecimal) ? config.humanFriendlyDecimal : 0,
|
85
|
+
|
86
|
+
// textRenderer: func
|
87
|
+
// function applied before rendering text
|
88
|
+
textRenderer : (config.textRenderer) ? config.textRenderer : null,
|
89
|
+
|
90
|
+
// gaugeWidthScale : float
|
91
|
+
// width of the gauge element
|
92
|
+
gaugeWidthScale : (config.gaugeWidthScale) ? config.gaugeWidthScale : 1.0,
|
93
|
+
|
94
|
+
// gaugeColor : string
|
95
|
+
// background color of gauge element
|
96
|
+
gaugeColor : (config.gaugeColor) ? config.gaugeColor : "#edebeb",
|
97
|
+
|
98
|
+
// label : string
|
99
|
+
// text to show below value
|
100
|
+
label : (config.label) ? config.label : "",
|
101
|
+
|
102
|
+
// showInnerShadow : bool
|
103
|
+
// give gauge element small amount of inner shadow
|
104
|
+
showInnerShadow : (config.showInnerShadow != null) ? config.showInnerShadow : true,
|
105
|
+
|
106
|
+
// shadowOpacity : int
|
107
|
+
// 0 ~ 1
|
108
|
+
shadowOpacity : (config.shadowOpacity) ? config.shadowOpacity : 0.2,
|
109
|
+
|
110
|
+
// shadowSize: int
|
111
|
+
// inner shadow size
|
112
|
+
shadowSize : (config.shadowSize) ? config.shadowSize : 5,
|
113
|
+
|
114
|
+
// shadowVerticalOffset : int
|
115
|
+
// how much shadow is offset from top
|
116
|
+
shadowVerticalOffset : (config.shadowVerticalOffset) ? config.shadowVerticalOffset : 3,
|
117
|
+
|
118
|
+
// levelColors : string[]
|
119
|
+
// colors of indicator, from lower to upper, in RGB format
|
120
|
+
levelColors : (config.levelColors) ? config.levelColors : [
|
121
|
+
"#a9d70b",
|
122
|
+
"#f9c802",
|
123
|
+
"#ff0000"
|
124
|
+
],
|
125
|
+
|
126
|
+
// levelColorsGradient : bool
|
127
|
+
// whether to use gradual color change for value, or sector-based
|
128
|
+
levelColorsGradient : (config.levelColorsGradient != null) ? config.levelColorsGradient : true,
|
129
|
+
|
130
|
+
// labelFontColor : string
|
131
|
+
// color of label showing label under value
|
132
|
+
labelFontColor : (config.labelFontColor) ? config.labelFontColor : "#b3b3b3",
|
133
|
+
|
134
|
+
// startAnimationTime : int
|
135
|
+
// length of initial animation
|
136
|
+
startAnimationTime : (config.startAnimationTime) ? config.startAnimationTime : 700,
|
137
|
+
|
138
|
+
// startAnimationType : string
|
139
|
+
// type of initial animation (linear, >, <, <>, bounce)
|
140
|
+
startAnimationType : (config.startAnimationType) ? config.startAnimationType : ">",
|
141
|
+
|
142
|
+
// refreshAnimationTime : int
|
143
|
+
// length of refresh animation
|
144
|
+
refreshAnimationTime : (config.refreshAnimationTime) ? config.refreshAnimationTime : 700,
|
145
|
+
|
146
|
+
// refreshAnimationType : string
|
147
|
+
// type of refresh animation (linear, >, <, <>, bounce)
|
148
|
+
refreshAnimationType : (config.refreshAnimationType) ? config.refreshAnimationType : ">",
|
149
|
+
|
150
|
+
// donut : bool
|
151
|
+
// show full donut gauge
|
152
|
+
donut : (config.donut != null) ? config.donut : false,
|
153
|
+
|
154
|
+
// valueMinFontSize : int
|
155
|
+
// absolute minimum font size for the value
|
156
|
+
valueMinFontSize : config.valueMinFontSize || 16,
|
157
|
+
|
158
|
+
// titleMinFontSize
|
159
|
+
// absolute minimum font size for the title
|
160
|
+
titleMinFontSize : config.titleMinFontSize || 10,
|
161
|
+
|
162
|
+
// labelMinFontSize
|
163
|
+
// absolute minimum font size for the label
|
164
|
+
labelMinFontSize : config.labelMinFontSize || 10,
|
165
|
+
|
166
|
+
// minLabelMinFontSize
|
167
|
+
// absolute minimum font size for the minimum label
|
168
|
+
minLabelMinFontSize : config.minLabelMinFontSize || 10,
|
169
|
+
|
170
|
+
// maxLabelMinFontSize
|
171
|
+
// absolute minimum font size for the maximum label
|
172
|
+
maxLabelMinFontSize : config.maxLabelMinFontSize || 10,
|
173
|
+
|
174
|
+
// relativeGaugeSize : bool
|
175
|
+
// whether gauge size should follow changes in container element size
|
176
|
+
relativeGaugeSize : (config.relativeGaugeSize != null) ? config.relativeGaugeSize : false,
|
177
|
+
};
|
178
|
+
|
179
|
+
// overflow values
|
180
|
+
if (config.value > this.config.max) this.config.value = this.config.max;
|
181
|
+
if (config.value < this.config.min) this.config.value = this.config.min;
|
182
|
+
this.originalValue = config.value;
|
183
|
+
|
184
|
+
// canvas
|
185
|
+
this.canvas = Raphael(this.config.id, "100%", "100%");
|
186
|
+
if (this.config.relativeGaugeSize) {
|
187
|
+
this.canvas.setViewBox(0, 0, 200, 150, true);
|
188
|
+
}
|
189
|
+
|
190
|
+
// canvas dimensions
|
191
|
+
var canvasW, canvasH;
|
192
|
+
if (this.config.relativeGaugeSize) {
|
193
|
+
canvasW = 200;
|
194
|
+
canvasH = 150;
|
195
|
+
} else {
|
196
|
+
canvasW = getStyle(document.getElementById(this.config.id), "width").slice(0, -2) * 1;
|
197
|
+
canvasH = getStyle(document.getElementById(this.config.id), "height").slice(0, -2) * 1;
|
198
|
+
}
|
199
|
+
|
200
|
+
// widget dimensions
|
201
|
+
var widgetW, widgetH, aspect;
|
202
|
+
|
203
|
+
if (this.config.donut) {
|
204
|
+
|
205
|
+
// DONUT *******************************
|
206
|
+
|
207
|
+
// width more than height
|
208
|
+
if(canvasW > canvasH) {
|
209
|
+
widgetH = canvasH;
|
210
|
+
widgetW = widgetH;
|
211
|
+
// width less than height
|
212
|
+
} else if (canvasW < canvasH) {
|
213
|
+
widgetW = canvasW;
|
214
|
+
widgetH = widgetW;
|
215
|
+
// if height don't fit, rescale both
|
216
|
+
if(widgetH > canvasH) {
|
217
|
+
aspect = widgetH / canvasH;
|
218
|
+
widgetH = widgetH / aspect;
|
219
|
+
widgetW = widgetH / aspect;
|
220
|
+
}
|
221
|
+
// equal
|
222
|
+
} else {
|
223
|
+
widgetW = canvasW;
|
224
|
+
widgetH = widgetW;
|
225
|
+
}
|
226
|
+
|
227
|
+
// delta
|
228
|
+
var dx = (canvasW - widgetW)/2;
|
229
|
+
var dy = (canvasH - widgetH)/2;
|
230
|
+
|
231
|
+
// title
|
232
|
+
var titleFontSize = ((widgetH / 8) > 10) ? (widgetH / 10) : 10;
|
233
|
+
var titleX = dx + widgetW / 2;
|
234
|
+
var titleY = dy + widgetH / 15;
|
235
|
+
|
236
|
+
// value
|
237
|
+
var valueFontSize = ((widgetH / 6.4) > 16) ? (widgetH / 5.4) : 18;
|
238
|
+
var valueX = dx + widgetW / 2;
|
239
|
+
var valueY = dy + widgetH / 1.95;
|
240
|
+
|
241
|
+
// label
|
242
|
+
var labelFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10;
|
243
|
+
var labelX = dx + widgetW / 2;
|
244
|
+
var labelY = valueY + valueFontSize / 2 + 6;
|
245
|
+
|
246
|
+
// min
|
247
|
+
var minFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10;
|
248
|
+
var minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * this.config.gaugeWidthScale) / 2 ;
|
249
|
+
var minY = dy + widgetH / 2;
|
250
|
+
|
251
|
+
// max
|
252
|
+
var maxFontSize = ((widgetH / 16) > 10) ? (widgetH / 16) : 10;
|
253
|
+
var maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * this.config.gaugeWidthScale) / 2 ;
|
254
|
+
var maxY = dy + widgetH / 2;
|
255
|
+
|
256
|
+
} else {
|
257
|
+
// HALF *******************************
|
258
|
+
|
259
|
+
// width more than height
|
260
|
+
if(canvasW > canvasH) {
|
261
|
+
widgetH = canvasH;
|
262
|
+
widgetW = widgetH * 1.25;
|
263
|
+
//if width doesn't fit, rescale both
|
264
|
+
if(widgetW > canvasW) {
|
265
|
+
aspect = widgetW / canvasW;
|
266
|
+
widgetW = widgetW / aspect;
|
267
|
+
widgetH = widgetH / aspect;
|
268
|
+
}
|
269
|
+
// width less than height
|
270
|
+
} else if (canvasW < canvasH) {
|
271
|
+
widgetW = canvasW;
|
272
|
+
widgetH = widgetW / 1.25;
|
273
|
+
// if height don't fit, rescale both
|
274
|
+
if(widgetH > canvasH) {
|
275
|
+
aspect = widgetH / canvasH;
|
276
|
+
widgetH = widgetH / aspect;
|
277
|
+
widgetW = widgetH / aspect;
|
278
|
+
}
|
279
|
+
// equal
|
280
|
+
} else {
|
281
|
+
widgetW = canvasW;
|
282
|
+
widgetH = widgetW * 0.75;
|
283
|
+
}
|
284
|
+
|
285
|
+
// delta
|
286
|
+
var dx = (canvasW - widgetW)/2;
|
287
|
+
var dy = (canvasH - widgetH)/2;
|
288
|
+
|
289
|
+
// title
|
290
|
+
var titleFontSize = ((widgetH / 8) > this.config.titleMinFontSize) ? (widgetH / 10) : this.config.titleMinFontSize;
|
291
|
+
var titleX = dx + widgetW / 2;
|
292
|
+
var titleY = dy + widgetH / 6.5;
|
293
|
+
|
294
|
+
// value
|
295
|
+
var valueFontSize = ((widgetH / 6.4) > this.config.valueMinFontSize) ? (widgetH / 6.4) : this.config.valueMinFontSize;
|
296
|
+
var valueX = dx + widgetW / 2;
|
297
|
+
var valueY = dy + widgetH / 1.4;
|
298
|
+
|
299
|
+
// label
|
300
|
+
var labelFontSize = ((widgetH / 16) > this.config.labelMinFontSize) ? (widgetH / 16) : this.config.labelMinFontSize;
|
301
|
+
var labelX = dx + widgetW / 2;
|
302
|
+
//var labelY = dy + widgetH / 1.126760563380282;
|
303
|
+
var labelY = valueY + valueFontSize / 2 + 6;
|
304
|
+
|
305
|
+
// min
|
306
|
+
var minFontSize = ((widgetH / 16) > this.config.minLabelMinFontSize) ? (widgetH / 16) : this.config.minLabelMinFontSize;
|
307
|
+
var minX = dx + (widgetW / 10) + (widgetW / 6.666666666666667 * this.config.gaugeWidthScale) / 2 ;
|
308
|
+
var minY = dy + widgetH / 1.126760563380282;
|
309
|
+
|
310
|
+
// max
|
311
|
+
var maxFontSize = ((widgetH / 16) > this.config.maxLabelMinFontSize) ? (widgetH / 16) : this.config.maxLabelMinFontSize;
|
312
|
+
var maxX = dx + widgetW - (widgetW / 10) - (widgetW / 6.666666666666667 * this.config.gaugeWidthScale) / 2 ;
|
313
|
+
var maxY = dy + widgetH / 1.126760563380282;
|
314
|
+
}
|
315
|
+
// parameters
|
316
|
+
this.params = {
|
317
|
+
canvasW : canvasW,
|
318
|
+
canvasH : canvasH,
|
319
|
+
widgetW : widgetW,
|
320
|
+
widgetH : widgetH,
|
321
|
+
dx : dx,
|
322
|
+
dy : dy,
|
323
|
+
titleFontSize : titleFontSize,
|
324
|
+
titleX : titleX,
|
325
|
+
titleY : titleY,
|
326
|
+
valueFontSize : valueFontSize,
|
327
|
+
valueX : valueX,
|
328
|
+
valueY : valueY,
|
329
|
+
labelFontSize : labelFontSize,
|
330
|
+
labelX : labelX,
|
331
|
+
labelY : labelY,
|
332
|
+
minFontSize : minFontSize,
|
333
|
+
minX : minX,
|
334
|
+
minY : minY,
|
335
|
+
maxFontSize : maxFontSize,
|
336
|
+
maxX : maxX,
|
337
|
+
maxY : maxY
|
338
|
+
};
|
339
|
+
|
340
|
+
// pki - custom attribute for generating gauge paths
|
341
|
+
this.canvas.customAttributes.pki = function (value, min, max, w, h, dx, dy, gws, donut) {
|
342
|
+
|
343
|
+
if (donut) {
|
344
|
+
var
|
345
|
+
alpha = (1 - 2 * (value - min) / (max - min)) * Math.PI,
|
346
|
+
Ro = w / 2 - w / 7,
|
347
|
+
Ri = Ro - w / 6.666666666666667 * gws,
|
348
|
+
|
349
|
+
Cx = w / 2 + dx,
|
350
|
+
Cy = h / 1.95 + dy,
|
351
|
+
|
352
|
+
Xo = w / 2 + dx + Ro * Math.cos(alpha),
|
353
|
+
Yo = h - (h - Cy) + 0 - Ro * Math.sin(alpha),
|
354
|
+
Xi = w / 2 + dx + Ri * Math.cos(alpha),
|
355
|
+
Yi = h - (h - Cy) + 0 - Ri * Math.sin(alpha),
|
356
|
+
path = "";
|
357
|
+
|
358
|
+
path += "M" + (Cx - Ri) + "," + Cy + " ";
|
359
|
+
path += "L" + (Cx - Ro) + "," + Cy + " ";
|
360
|
+
if (value > ((max - min) / 2)) {
|
361
|
+
path += "A" + Ro + "," + Ro + " 0 0 1 " + (Cx + Ro) + "," + Cy + " ";
|
362
|
+
}
|
363
|
+
path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " ";
|
364
|
+
path += "L" + Xi + "," + Yi + " ";
|
365
|
+
if (value > ((max - min) / 2)) {
|
366
|
+
path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx + Ri) + "," + Cy + " ";
|
367
|
+
}
|
368
|
+
path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " ";
|
369
|
+
path += "Z ";
|
370
|
+
return { path: path };
|
371
|
+
|
372
|
+
} else {
|
373
|
+
var
|
374
|
+
alpha = (1 - (value - min) / (max - min)) * Math.PI,
|
375
|
+
|
376
|
+
Ro = w / 2 - w / 10,
|
377
|
+
Ri = Ro - w / 6.666666666666667 * gws,
|
378
|
+
|
379
|
+
Cx = w / 2 + dx,
|
380
|
+
Cy = h / 1.25 + dy,
|
381
|
+
|
382
|
+
Xo = w / 2 + dx + Ro * Math.cos(alpha),
|
383
|
+
Yo = h - (h - Cy) + 0 - Ro * Math.sin(alpha),
|
384
|
+
Xi = w / 2 + dx + Ri * Math.cos(alpha),
|
385
|
+
Yi = h - (h - Cy) + 0 - Ri * Math.sin(alpha),
|
386
|
+
path = "";
|
387
|
+
|
388
|
+
path += "M" + (Cx - Ri) + "," + Cy + " ";
|
389
|
+
path += "L" + (Cx - Ro) + "," + Cy + " ";
|
390
|
+
path += "A" + Ro + "," + Ro + " 0 0 1 " + Xo + "," + Yo + " ";
|
391
|
+
path += "L" + Xi + "," + Yi + " ";
|
392
|
+
path += "A" + Ri + "," + Ri + " 0 0 0 " + (Cx - Ri) + "," + Cy + " ";
|
393
|
+
path += "Z ";
|
394
|
+
return { path: path };
|
395
|
+
}
|
396
|
+
}
|
397
|
+
|
398
|
+
// gauge
|
399
|
+
this.gauge = this.canvas.path().attr({
|
400
|
+
"stroke": "none",
|
401
|
+
"fill": this.config.gaugeColor,
|
402
|
+
pki: [this.config.max, this.config.min, this.config.max, this.params.widgetW, this.params.widgetH, this.params.dx, this.params.dy, this.config.gaugeWidthScale, this.config.donut]
|
403
|
+
});
|
404
|
+
this.gauge.id = this.config.id+"-gauge";
|
405
|
+
|
406
|
+
// level
|
407
|
+
this.level = this.canvas.path().attr({
|
408
|
+
"stroke": "none",
|
409
|
+
"fill": getColorForPercentage((this.config.value - this.config.min) / (this.config.max - this.config.min), this.config.levelColors, this.config.levelColorsGradient),
|
410
|
+
pki: [this.config.min, this.config.min, this.config.max, this.params.widgetW, this.params.widgetH, this.params.dx, this.params.dy, this.config.gaugeWidthScale, this.config.donut]
|
411
|
+
});
|
412
|
+
this.level.id = this.config.id+"-level";
|
413
|
+
|
414
|
+
// title
|
415
|
+
this.txtTitle = this.canvas.text(this.params.titleX, this.params.titleY, this.config.title);
|
416
|
+
this.txtTitle. attr({
|
417
|
+
"font-size":this.params.titleFontSize,
|
418
|
+
"font-weight":"bold",
|
419
|
+
"font-family":"Arial",
|
420
|
+
"fill":this.config.titleFontColor,
|
421
|
+
"fill-opacity":"1"
|
422
|
+
});
|
423
|
+
this.txtTitle.id = this.config.id+"-txttitle";
|
424
|
+
|
425
|
+
// value
|
426
|
+
if(this.config.textRenderer)
|
427
|
+
this.originalValue = this.config.textRenderer(this.originalValue);
|
428
|
+
else if( this.config.humanFriendly )
|
429
|
+
this.originalValue = humanFriendlyNumber( this.originalValue, this.config.humanFriendlyDecimal ) + this.config.symbol;
|
430
|
+
|
431
|
+
this.txtValue = this.canvas.text(this.params.valueX, this.params.valueY, this.originalValue);
|
432
|
+
this.txtValue. attr({
|
433
|
+
"font-size":this.params.valueFontSize,
|
434
|
+
"font-weight":"bold",
|
435
|
+
"font-family":"Arial",
|
436
|
+
"fill":this.config.valueFontColor,
|
437
|
+
"fill-opacity":"0"
|
438
|
+
});
|
439
|
+
this.txtValue.id = this.config.id+"-txtvalue";
|
440
|
+
|
441
|
+
// label
|
442
|
+
this.txtLabel = this.canvas.text(this.params.labelX, this.params.labelY, this.config.label);
|
443
|
+
this.txtLabel. attr({
|
444
|
+
"font-size":this.params.labelFontSize,
|
445
|
+
"font-weight":"normal",
|
446
|
+
"font-family":"Arial",
|
447
|
+
"fill":this.config.labelFontColor,
|
448
|
+
"fill-opacity":"0"
|
449
|
+
});
|
450
|
+
this.txtLabel.id = this.config.id+"-txtlabel";
|
451
|
+
|
452
|
+
// min
|
453
|
+
this.txtMinimum = this.config.min;
|
454
|
+
if( this.config.humanFriendly ) this.txtMinimum = humanFriendlyNumber( this.config.min, this.config.humanFriendlyDecimal );
|
455
|
+
this.txtMin = this.canvas.text(this.params.minX, this.params.minY, this.txtMinimum);
|
456
|
+
this.txtMin. attr({
|
457
|
+
"font-size":this.params.minFontSize,
|
458
|
+
"font-weight":"normal",
|
459
|
+
"font-family":"Arial",
|
460
|
+
"fill":this.config.labelFontColor,
|
461
|
+
"fill-opacity": (this.config.showMinMax == true)? "1" : "0"
|
462
|
+
});
|
463
|
+
this.txtMin.id = this.config.id+"-txtmin";
|
464
|
+
|
465
|
+
// max
|
466
|
+
this.txtMaximum = this.config.max;
|
467
|
+
if( this.config.humanFriendly ) this.txtMaximum = humanFriendlyNumber( this.config.max, this.config.humanFriendlyDecimal );
|
468
|
+
this.txtMax = this.canvas.text(this.params.maxX, this.params.maxY, this.txtMaximum);
|
469
|
+
this.txtMax. attr({
|
470
|
+
"font-size":this.params.maxFontSize,
|
471
|
+
"font-weight":"normal",
|
472
|
+
"font-family":"Arial",
|
473
|
+
"fill":this.config.labelFontColor,
|
474
|
+
"fill-opacity": (this.config.showMinMax == true)? "1" : "0"
|
475
|
+
});
|
476
|
+
this.txtMax.id = this.config.id+"-txtmax";
|
477
|
+
|
478
|
+
var defs = this.canvas.canvas.childNodes[1];
|
479
|
+
var svg = "http://www.w3.org/2000/svg";
|
480
|
+
|
481
|
+
if (ie < 9) {
|
482
|
+
onCreateElementNsReady(function() {
|
483
|
+
this.generateShadow();
|
484
|
+
});
|
485
|
+
} else {
|
486
|
+
this.generateShadow(svg, defs);
|
487
|
+
defs = null;
|
488
|
+
svg = null;
|
489
|
+
}
|
490
|
+
|
491
|
+
// animate
|
492
|
+
this.level.animate({pki: [this.config.value, this.config.min, this.config.max, this.params.widgetW, this.params.widgetH, this.params.dx, this.params.dy, this.config.gaugeWidthScale, this.config.donut]}, this.config.startAnimationTime, this.config.startAnimationType);
|
493
|
+
|
494
|
+
if (this.config.showValue) {
|
495
|
+
this.txtValue.animate({"fill-opacity":"1"}, this.config.startAnimationTime, this.config.startAnimationType);
|
496
|
+
}
|
497
|
+
this.txtLabel.animate({"fill-opacity":"1"}, this.config.startAnimationTime, this.config.startAnimationType);
|
498
|
+
};
|
499
|
+
|
500
|
+
/** Refresh gauge level */
|
501
|
+
JustGage.prototype.refresh = function(val) {
|
502
|
+
// overflow values
|
503
|
+
var originalVal = val;
|
504
|
+
var displayVal = val;
|
505
|
+
if (val > this.config.max) {val = this.config.max;}
|
506
|
+
if (val < this.config.min) {val = this.config.min;}
|
507
|
+
|
508
|
+
var color = getColorForPercentage((val - this.config.min) / (this.config.max - this.config.min), this.config.levelColors, this.config.levelColorsGradient);
|
509
|
+
|
510
|
+
if(this.config.textRenderer)
|
511
|
+
displayVal = this.config.textRenderer(displayVal);
|
512
|
+
else if( this.config.humanFriendly )
|
513
|
+
displayVal = humanFriendlyNumber( displayVal, this.config.humanFriendlyDecimal ) + this.config.symbol;
|
514
|
+
|
515
|
+
this.canvas.getById(this.config.id+"-txtvalue").attr({"text":displayVal});
|
516
|
+
this.canvas.getById(this.config.id+"-level").animate({pki: [val, this.config.min, this.config.max, this.params.widgetW, this.params.widgetH, this.params.dx, this.params.dy, this.config.gaugeWidthScale, this.config.donut], "fill":color}, this.config.refreshAnimationTime, this.config.refreshAnimationType);
|
517
|
+
this.config.value = val;
|
518
|
+
originalVal = null;
|
519
|
+
displayVal = null;
|
520
|
+
};
|
521
|
+
|
522
|
+
/** Generate shadow */
|
523
|
+
JustGage.prototype.generateShadow = function(svg, defs) {
|
524
|
+
// FILTER
|
525
|
+
var gaussFilter=document.createElementNS(svg,"filter");
|
526
|
+
gaussFilter.setAttribute("id", this.config.id + "-inner-shadow");
|
527
|
+
defs.appendChild(gaussFilter);
|
528
|
+
|
529
|
+
// offset
|
530
|
+
var feOffset = document.createElementNS(svg,"feOffset");
|
531
|
+
feOffset.setAttribute("dx", 0);
|
532
|
+
feOffset.setAttribute("dy", this.config.shadowVerticalOffset);
|
533
|
+
gaussFilter.appendChild(feOffset);
|
534
|
+
feOffset = null;
|
535
|
+
|
536
|
+
// blur
|
537
|
+
var feGaussianBlur = document.createElementNS(svg,"feGaussianBlur");
|
538
|
+
feGaussianBlur.setAttribute("result","offset-blur");
|
539
|
+
feGaussianBlur.setAttribute("stdDeviation", this.config.shadowSize);
|
540
|
+
gaussFilter.appendChild(feGaussianBlur);
|
541
|
+
feGaussianBlur = null;
|
542
|
+
|
543
|
+
// composite 1
|
544
|
+
var feComposite1 = document.createElementNS(svg,"feComposite");
|
545
|
+
feComposite1.setAttribute("operator","out");
|
546
|
+
feComposite1.setAttribute("in", "SourceGraphic");
|
547
|
+
feComposite1.setAttribute("in2","offset-blur");
|
548
|
+
feComposite1.setAttribute("result","inverse");
|
549
|
+
gaussFilter.appendChild(feComposite1);
|
550
|
+
feComposite1 = null;
|
551
|
+
|
552
|
+
// flood
|
553
|
+
var feFlood = document.createElementNS(svg,"feFlood");
|
554
|
+
feFlood.setAttribute("flood-color","black");
|
555
|
+
feFlood.setAttribute("flood-opacity", this.config.shadowOpacity);
|
556
|
+
feFlood.setAttribute("result","color");
|
557
|
+
gaussFilter.appendChild(feFlood);
|
558
|
+
feFlood = null;
|
559
|
+
|
560
|
+
// composite 2
|
561
|
+
var feComposite2 = document.createElementNS(svg,"feComposite");
|
562
|
+
feComposite2.setAttribute("operator","in");
|
563
|
+
feComposite2.setAttribute("in", "color");
|
564
|
+
feComposite2.setAttribute("in2","inverse");
|
565
|
+
feComposite2.setAttribute("result","shadow");
|
566
|
+
gaussFilter.appendChild(feComposite2);
|
567
|
+
feComposite2 = null;
|
568
|
+
|
569
|
+
// composite 3
|
570
|
+
var feComposite3 = document.createElementNS(svg,"feComposite");
|
571
|
+
feComposite3.setAttribute("operator","over");
|
572
|
+
feComposite3.setAttribute("in", "shadow");
|
573
|
+
feComposite3.setAttribute("in2","SourceGraphic");
|
574
|
+
gaussFilter.appendChild(feComposite3);
|
575
|
+
feComposite3 = null;
|
576
|
+
|
577
|
+
// set shadow
|
578
|
+
if (this.config.showInnerShadow == true) {
|
579
|
+
this.canvas.canvas.childNodes[2].setAttribute("filter", "url(#" + this.config.id + "-inner-shadow)");
|
580
|
+
this.canvas.canvas.childNodes[3].setAttribute("filter", "url(#" + this.config.id + "-inner-shadow)");
|
581
|
+
}
|
582
|
+
|
583
|
+
// clear vars
|
584
|
+
gaussFilter = null;
|
585
|
+
|
586
|
+
}
|
587
|
+
|
588
|
+
/** Get color for value percentage */
|
589
|
+
function getColorForPercentage(pct, col, grad) {
|
590
|
+
|
591
|
+
var no = col.length;
|
592
|
+
if (no === 1) return col[0];
|
593
|
+
var inc = (grad) ? (1 / (no - 1)) : (1 / no);
|
594
|
+
var colors = new Array();
|
595
|
+
for (var i = 0; i < col.length; i++) {
|
596
|
+
var percentage = (grad) ? (inc * i) : (inc * (i + 1));
|
597
|
+
var rval = parseInt((cutHex(col[i])).substring(0,2),16);
|
598
|
+
var gval = parseInt((cutHex(col[i])).substring(2,4),16);
|
599
|
+
var bval = parseInt((cutHex(col[i])).substring(4,6),16);
|
600
|
+
colors[i] = { pct: percentage, color: { r: rval, g: gval, b: bval } };
|
601
|
+
}
|
602
|
+
|
603
|
+
if(pct == 0) return 'rgb(' + [colors[0].color.r, colors[0].color.g, colors[0].color.b].join(',') + ')';
|
604
|
+
|
605
|
+
for (var i = 0; i < colors.length; i++) {
|
606
|
+
if (pct <= colors[i].pct) {
|
607
|
+
if (grad == true) {
|
608
|
+
var lower = colors[i - 1];
|
609
|
+
var upper = colors[i];
|
610
|
+
var range = upper.pct - lower.pct;
|
611
|
+
var rangePct = (pct - lower.pct) / range;
|
612
|
+
var pctLower = 1 - rangePct;
|
613
|
+
var pctUpper = rangePct;
|
614
|
+
var color = {
|
615
|
+
r: Math.floor(lower.color.r * pctLower + upper.color.r * pctUpper),
|
616
|
+
g: Math.floor(lower.color.g * pctLower + upper.color.g * pctUpper),
|
617
|
+
b: Math.floor(lower.color.b * pctLower + upper.color.b * pctUpper)
|
618
|
+
};
|
619
|
+
return 'rgb(' + [color.r, color.g, color.b].join(',') + ')';
|
620
|
+
} else {
|
621
|
+
return 'rgb(' + [colors[i].color.r, colors[i].color.g, colors[i].color.b].join(',') + ')';
|
622
|
+
}
|
623
|
+
}
|
624
|
+
}
|
625
|
+
|
626
|
+
}
|
627
|
+
|
628
|
+
/** Random integer */
|
629
|
+
function getRandomInt (min, max) {
|
630
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
631
|
+
}
|
632
|
+
|
633
|
+
/** Cut hex */
|
634
|
+
function cutHex(str) {return (str.charAt(0)=="#") ? str.substring(1,7):str}
|
635
|
+
|
636
|
+
/** Human friendly number suffix */
|
637
|
+
// From: http://stackoverflow.com/questions/2692323/code-golf-friendly-number-abbreviator
|
638
|
+
function humanFriendlyNumber( n, d ) {
|
639
|
+
var p = Math.pow;
|
640
|
+
var d = p(10,d);
|
641
|
+
var i = 7
|
642
|
+
while( i ) {
|
643
|
+
s = p(10,i--*3)
|
644
|
+
if( s <= n ) {
|
645
|
+
n = Math.round(n*d/s)/d+"kMGTPE"[i];
|
646
|
+
}
|
647
|
+
}
|
648
|
+
return n;
|
649
|
+
}
|
650
|
+
|
651
|
+
/** Get style */
|
652
|
+
function getStyle(oElm, strCssRule){
|
653
|
+
var strValue = "";
|
654
|
+
if(document.defaultView && document.defaultView.getComputedStyle){
|
655
|
+
strValue = document.defaultView.getComputedStyle(oElm, "").getPropertyValue(strCssRule);
|
656
|
+
}
|
657
|
+
else if(oElm.currentStyle){
|
658
|
+
strCssRule = strCssRule.replace(/\-(\w)/g, function (strMatch, p1){
|
659
|
+
return p1.toUpperCase();
|
660
|
+
});
|
661
|
+
strValue = oElm.currentStyle[strCssRule];
|
662
|
+
}
|
663
|
+
return strValue;
|
664
|
+
}
|
665
|
+
|
666
|
+
/** Create Element NS Ready */
|
667
|
+
function onCreateElementNsReady(func) {
|
668
|
+
if (document.createElementNS != undefined) {
|
669
|
+
func();
|
670
|
+
} else {
|
671
|
+
setTimeout(function() { onCreateElementNsReady(func); }, 100);
|
672
|
+
}
|
673
|
+
}
|
674
|
+
|
675
|
+
/** Get IE version */
|
676
|
+
// ----------------------------------------------------------
|
677
|
+
// A short snippet for detecting versions of IE in JavaScript
|
678
|
+
// without resorting to user-agent sniffing
|
679
|
+
// ----------------------------------------------------------
|
680
|
+
// If you're not in IE (or IE version is less than 5) then:
|
681
|
+
// ie === undefined
|
682
|
+
// If you're in IE (>=5) then you can determine which version:
|
683
|
+
// ie === 7; // IE7
|
684
|
+
// Thus, to detect IE:
|
685
|
+
// if (ie) {}
|
686
|
+
// And to detect the version:
|
687
|
+
// ie === 6 // IE6
|
688
|
+
// ie > 7 // IE8, IE9 ...
|
689
|
+
// ie < 9 // Anything less than IE9
|
690
|
+
// ----------------------------------------------------------
|
691
|
+
// UPDATE: Now using Live NodeList idea from @jdalton
|
692
|
+
var ie = (function(){
|
693
|
+
|
694
|
+
var undef,
|
695
|
+
v = 3,
|
696
|
+
div = document.createElement('div'),
|
697
|
+
all = div.getElementsByTagName('i');
|
698
|
+
|
699
|
+
while (
|
700
|
+
div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->',
|
701
|
+
all[0]
|
702
|
+
);
|
703
|
+
|
704
|
+
return v > 4 ? v : undef;
|
705
|
+
|
706
|
+
}());
|