gaugejs-rails 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/lib/gaugejs-rails/version.rb +1 -1
- data/vendor/assets/javascripts/gauge.coffee +235 -62
- data/vendor/assets/javascripts/gauge.js +434 -95
- data/vendor/assets/javascripts/gauge.min.js +1 -37
- metadata +35 -52
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7792f0ff9f7668bd59dddd368d587d9bad11a971
|
4
|
+
data.tar.gz: ce93b68f4f959194499a33bea483fe9fc9de750a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a4f04035de74497add989e8d92524f6bb13cd367ba88d19110788493bb30331ce98b61c9fdab750eb27fcbd96c7e2ad232f59b6043a261b922e065d45d2414d5
|
7
|
+
data.tar.gz: 92a99b24344e071b16dfe3788c3b25a4fde32643a104634c144fc4133490b3b7149cb43948a1ae5bf513d8dfb97addfb665b6ae9c01eee33b5be2b6e3cf9b348
|
@@ -51,7 +51,7 @@ secondsToString = (sec) ->
|
|
51
51
|
hr = Math.floor(sec / 3600)
|
52
52
|
min = Math.floor((sec - (hr * 3600))/60)
|
53
53
|
sec -= ((hr * 3600) + (min * 60))
|
54
|
-
sec += ''
|
54
|
+
sec += ''
|
55
55
|
min += ''
|
56
56
|
while min.length < 2
|
57
57
|
min = '0' + min
|
@@ -66,8 +66,17 @@ formatNumber = (num) ->
|
|
66
66
|
updateObjectValues = (obj1, obj2) ->
|
67
67
|
for own key, val of obj2
|
68
68
|
obj1[key] = val
|
69
|
+
return obj1
|
69
70
|
|
70
|
-
|
71
|
+
mergeObjects = (obj1, obj2) ->
|
72
|
+
out = {}
|
73
|
+
for own key, val of obj1
|
74
|
+
out[key] = val
|
75
|
+
for own key, val of obj2
|
76
|
+
out[key] = val
|
77
|
+
return out
|
78
|
+
|
79
|
+
addCommas = (nStr) ->
|
71
80
|
nStr += ''
|
72
81
|
x = nStr.split('.')
|
73
82
|
x1 = x[0]
|
@@ -79,14 +88,20 @@ addCommas =(nStr) ->
|
|
79
88
|
x1 = x1.replace(rgx, '$1' + ',' + '$2')
|
80
89
|
return x1 + x2
|
81
90
|
|
91
|
+
cutHex = (nStr) ->
|
92
|
+
if nStr.charAt(0) == "#"
|
93
|
+
return nStr.substring(1,7)
|
94
|
+
return nStr
|
95
|
+
|
82
96
|
class ValueUpdater
|
83
97
|
animationSpeed: 32
|
84
|
-
constructor: () ->
|
85
|
-
|
98
|
+
constructor: (addToAnimationQueue=true, @clear=true) ->
|
99
|
+
if addToAnimationQueue
|
100
|
+
AnimationUpdater.add(@)
|
86
101
|
|
87
|
-
update: ->
|
88
|
-
if @displayedValue != @value
|
89
|
-
if @ctx
|
102
|
+
update: (force=false) ->
|
103
|
+
if force or @displayedValue != @value
|
104
|
+
if @ctx and @clear
|
90
105
|
@ctx.clearRect(0, 0, @canvas.width, @canvas.height)
|
91
106
|
diff = @value - @displayedValue
|
92
107
|
if Math.abs(diff / @animationSpeed) <= 0.001
|
@@ -97,6 +112,62 @@ class ValueUpdater
|
|
97
112
|
return true
|
98
113
|
return false
|
99
114
|
|
115
|
+
class BaseGauge extends ValueUpdater
|
116
|
+
displayScale: 1
|
117
|
+
|
118
|
+
setTextField: (textField) ->
|
119
|
+
@textField = if textField instanceof TextRenderer then textField else new TextRenderer(textField)
|
120
|
+
|
121
|
+
setMinValue: (@minValue, updateStartValue=true) ->
|
122
|
+
if updateStartValue
|
123
|
+
@displayedValue = @minValue
|
124
|
+
for gauge in @gp or []
|
125
|
+
gauge.displayedValue = @minValue
|
126
|
+
|
127
|
+
setOptions: (options=null) ->
|
128
|
+
@options = mergeObjects(@options, options)
|
129
|
+
if @textField
|
130
|
+
@textField.el.style.fontSize = options.fontSize + 'px'
|
131
|
+
|
132
|
+
if @options.angle > .5
|
133
|
+
@gauge.options.angle = .5
|
134
|
+
@configDisplayScale()
|
135
|
+
return @
|
136
|
+
|
137
|
+
configDisplayScale: () ->
|
138
|
+
prevDisplayScale = @displayScale
|
139
|
+
|
140
|
+
if @options.highDpiSupport == false
|
141
|
+
delete @displayScale
|
142
|
+
else
|
143
|
+
devicePixelRatio = window.devicePixelRatio or 1
|
144
|
+
backingStorePixelRatio =
|
145
|
+
@ctx.webkitBackingStorePixelRatio or
|
146
|
+
@ctx.mozBackingStorePixelRatio or
|
147
|
+
@ctx.msBackingStorePixelRatio or
|
148
|
+
@ctx.oBackingStorePixelRatio or
|
149
|
+
@ctx.backingStorePixelRatio or 1
|
150
|
+
@displayScale = devicePixelRatio / backingStorePixelRatio
|
151
|
+
|
152
|
+
if @displayScale != prevDisplayScale
|
153
|
+
width = @canvas.G__width or @canvas.width
|
154
|
+
height = @canvas.G__height or @canvas.height
|
155
|
+
@canvas.width = width * @displayScale
|
156
|
+
@canvas.height = height * @displayScale
|
157
|
+
@canvas.style.width = "#{width}px"
|
158
|
+
@canvas.style.height = "#{height}px"
|
159
|
+
@canvas.G__width = width
|
160
|
+
@canvas.G__height = height
|
161
|
+
|
162
|
+
return @
|
163
|
+
|
164
|
+
class TextRenderer
|
165
|
+
constructor: (@el) ->
|
166
|
+
|
167
|
+
# Default behaviour, override to customize rendering
|
168
|
+
render: (gauge) ->
|
169
|
+
@el.innerHTML = formatNumber(gauge.displayedValue)
|
170
|
+
|
100
171
|
class AnimatedText extends ValueUpdater
|
101
172
|
displayedValue: 0
|
102
173
|
value: 0
|
@@ -122,27 +193,34 @@ AnimatedTextFactory =
|
|
122
193
|
out.push(new AnimatedText(elem))
|
123
194
|
return out
|
124
195
|
|
125
|
-
class GaugePointer
|
126
|
-
|
127
|
-
|
196
|
+
class GaugePointer extends ValueUpdater
|
197
|
+
displayedValue: 0
|
198
|
+
value: 0
|
128
199
|
options:
|
129
200
|
strokeWidth: 0.035
|
130
201
|
length: 0.1
|
131
|
-
|
132
|
-
|
133
|
-
|
202
|
+
color: "#000000"
|
203
|
+
|
204
|
+
constructor: (@gauge) ->
|
205
|
+
@ctx = @gauge.ctx
|
206
|
+
@canvas = @gauge.canvas
|
207
|
+
super(false, false)
|
134
208
|
@setOptions()
|
135
209
|
|
136
210
|
setOptions: (options=null) ->
|
137
211
|
updateObjectValues(@options, options)
|
138
212
|
@length = @canvas.height * @options.length
|
139
213
|
@strokeWidth = @canvas.height * @options.strokeWidth
|
214
|
+
@maxValue = @gauge.maxValue
|
215
|
+
@minValue = @gauge.minValue
|
216
|
+
@animationSpeed = @gauge.animationSpeed
|
217
|
+
@options.angle = @gauge.options.angle
|
140
218
|
|
141
|
-
render: (
|
219
|
+
render: () ->
|
220
|
+
angle = @gauge.getAngle.call(@, @displayedValue)
|
142
221
|
centerX = @canvas.width / 2
|
143
222
|
centerY = @canvas.height * 0.9
|
144
|
-
|
145
|
-
# angle = Math.PI * 1.45
|
223
|
+
|
146
224
|
x = Math.round(centerX + @length * Math.cos(angle))
|
147
225
|
y = Math.round(centerY + @length * Math.sin(angle))
|
148
226
|
|
@@ -152,7 +230,7 @@ class GaugePointer
|
|
152
230
|
endX = Math.round(centerX + @strokeWidth * Math.cos(angle + Math.PI/2))
|
153
231
|
endY = Math.round(centerY + @strokeWidth * Math.sin(angle + Math.PI/2))
|
154
232
|
|
155
|
-
@ctx.fillStyle =
|
233
|
+
@ctx.fillStyle = @options.color
|
156
234
|
@ctx.beginPath()
|
157
235
|
|
158
236
|
@ctx.arc(centerX, centerY, @strokeWidth, 0, Math.PI*2, true)
|
@@ -164,7 +242,6 @@ class GaugePointer
|
|
164
242
|
@ctx.lineTo(endX, endY)
|
165
243
|
@ctx.fill()
|
166
244
|
|
167
|
-
|
168
245
|
class Bar
|
169
246
|
constructor: (@elem) ->
|
170
247
|
updateValues: (arrValues) ->
|
@@ -182,22 +259,24 @@ class Bar
|
|
182
259
|
|
183
260
|
valPercent = (@value / @maxValue) * 100
|
184
261
|
avgPercent = (@avgValue / @maxValue) * 100
|
185
|
-
|
262
|
+
|
186
263
|
$(".bar-value", @elem).css({"width": valPercent + "%"})
|
187
264
|
$(".typical-value", @elem).css({"width": avgPercent + "%"})
|
188
265
|
|
189
|
-
class Gauge extends
|
266
|
+
class Gauge extends BaseGauge
|
190
267
|
elem: null
|
191
|
-
value: 20
|
268
|
+
value: [20] # we support multiple pointers
|
192
269
|
maxValue: 80
|
193
|
-
|
270
|
+
minValue: 0
|
194
271
|
displayedAngle: 0
|
195
272
|
displayedValue: 0
|
196
273
|
lineWidth: 40
|
197
274
|
paddingBottom: 0.1
|
275
|
+
percentColors: null,
|
198
276
|
options:
|
199
277
|
colorStart: "#6fadcf"
|
200
|
-
colorStop:
|
278
|
+
colorStop: undefined
|
279
|
+
gradientType: 0 # 0 : radial, 1 : linear
|
201
280
|
strokeColor: "#e0e0e0"
|
202
281
|
pointer:
|
203
282
|
length: 0.8
|
@@ -205,32 +284,101 @@ class Gauge extends ValueUpdater
|
|
205
284
|
angle: 0.15
|
206
285
|
lineWidth: 0.44
|
207
286
|
fontSize: 40
|
287
|
+
limitMax: false
|
288
|
+
percentColors : [
|
289
|
+
[ 0.0, "#a9d70b" ],
|
290
|
+
[ 0.50, "#f9c802" ],
|
291
|
+
[ 1.0, "#ff0000" ]
|
292
|
+
]
|
293
|
+
|
208
294
|
constructor: (@canvas) ->
|
209
295
|
super()
|
296
|
+
@percentColors = null
|
297
|
+
if typeof G_vmlCanvasManager != 'undefined'
|
298
|
+
@canvas = window.G_vmlCanvasManager.initElement(@canvas)
|
210
299
|
@ctx = @canvas.getContext('2d')
|
211
|
-
@gp = new GaugePointer(@
|
300
|
+
@gp = [new GaugePointer(@)]
|
212
301
|
@setOptions()
|
213
302
|
@render()
|
214
303
|
|
215
304
|
setOptions: (options=null) ->
|
216
|
-
|
305
|
+
super(options)
|
306
|
+
@configPercentColors()
|
217
307
|
@lineWidth = @canvas.height * (1 - @paddingBottom) * @options.lineWidth # .2 - .7
|
218
308
|
@radius = @canvas.height * (1 - @paddingBottom) - @lineWidth
|
219
|
-
@
|
220
|
-
|
221
|
-
|
309
|
+
@ctx.clearRect(0, 0, @canvas.width, @canvas.height)
|
310
|
+
@render()
|
311
|
+
for gauge in @gp
|
312
|
+
gauge.setOptions(@options.pointer)
|
313
|
+
gauge.render()
|
222
314
|
return @
|
223
|
-
|
315
|
+
|
316
|
+
configPercentColors: () ->
|
317
|
+
@percentColors = null;
|
318
|
+
if (@options.percentColors != undefined)
|
319
|
+
@percentColors = new Array()
|
320
|
+
for i in [0..(@options.percentColors.length-1)]
|
321
|
+
rval = parseInt((cutHex(@options.percentColors[i][1])).substring(0,2),16)
|
322
|
+
gval = parseInt((cutHex(@options.percentColors[i][1])).substring(2,4),16)
|
323
|
+
bval = parseInt((cutHex(@options.percentColors[i][1])).substring(4,6),16)
|
324
|
+
@percentColors[i] = { pct: @options.percentColors[i][0], color: { r: rval, g: gval, b: bval } }
|
325
|
+
|
224
326
|
set: (value) ->
|
225
|
-
|
226
|
-
if
|
227
|
-
|
228
|
-
|
327
|
+
|
328
|
+
if not (value instanceof Array)
|
329
|
+
value = [value]
|
330
|
+
# check if we have enough GaugePointers initialized
|
331
|
+
# lazy initialization
|
332
|
+
if value.length > @gp.length
|
333
|
+
for i in [0...(value.length - @gp.length)]
|
334
|
+
@gp.push(new GaugePointer(@))
|
335
|
+
|
336
|
+
# get max value and update pointer(s)
|
337
|
+
i = 0
|
338
|
+
max_hit = false
|
339
|
+
|
340
|
+
for val in value
|
341
|
+
if val > @maxValue
|
342
|
+
@maxValue = @value * 1.1
|
343
|
+
max_hit = true
|
344
|
+
@gp[i].value = val
|
345
|
+
@gp[i++].setOptions({maxValue: @maxValue, angle: @options.angle})
|
346
|
+
@value = value[value.length - 1] # TODO: Span maybe??
|
347
|
+
|
348
|
+
if max_hit
|
349
|
+
unless @options.limitMax
|
350
|
+
AnimationUpdater.run()
|
351
|
+
else
|
352
|
+
AnimationUpdater.run()
|
229
353
|
|
230
354
|
getAngle: (value) ->
|
231
|
-
return (1 + @options.angle) * Math.PI + (value / @maxValue) * (1 - @options.angle * 2) * Math.PI
|
355
|
+
return (1 + @options.angle) * Math.PI + ((value - @minValue) / (@maxValue - @minValue)) * (1 - @options.angle * 2) * Math.PI
|
232
356
|
|
233
|
-
|
357
|
+
getColorForPercentage: (pct, grad) ->
|
358
|
+
if pct == 0
|
359
|
+
color = @percentColors[0].color;
|
360
|
+
else
|
361
|
+
color = @percentColors[@percentColors.length - 1].color;
|
362
|
+
for i in [0..(@percentColors.length - 1)]
|
363
|
+
if (pct <= @percentColors[i].pct)
|
364
|
+
if grad == true
|
365
|
+
# Gradually change between colors
|
366
|
+
startColor = @percentColors[i - 1]
|
367
|
+
endColor = @percentColors[i]
|
368
|
+
rangePct = (pct - startColor.pct) / (endColor.pct - startColor.pct) # How far between both colors
|
369
|
+
color = {
|
370
|
+
r: Math.floor(startColor.color.r * (1 - rangePct) + endColor.color.r * rangePct),
|
371
|
+
g: Math.floor(startColor.color.g * (1 - rangePct) + endColor.color.g * rangePct),
|
372
|
+
b: Math.floor(startColor.color.b * (1 - rangePct) + endColor.color.b * rangePct)
|
373
|
+
}
|
374
|
+
else
|
375
|
+
color = @percentColors[i].color
|
376
|
+
break
|
377
|
+
return 'rgb(' + [color.r, color.g, color.b].join(',') + ')'
|
378
|
+
|
379
|
+
getColorForValue: (val, grad) ->
|
380
|
+
pct = (val - @minValue) / (@maxValue - @minValue)
|
381
|
+
return @getColorForPercentage(pct, grad);
|
234
382
|
|
235
383
|
render: () ->
|
236
384
|
# Draw using canvas
|
@@ -238,14 +386,24 @@ class Gauge extends ValueUpdater
|
|
238
386
|
h = @canvas.height * (1 - @paddingBottom)
|
239
387
|
displayedAngle = @getAngle(@displayedValue)
|
240
388
|
if @textField
|
241
|
-
@textField.
|
389
|
+
@textField.render(@)
|
242
390
|
|
243
|
-
grd = @ctx.createRadialGradient(w, h, 9, w, h, 70)
|
244
391
|
@ctx.lineCap = "butt"
|
392
|
+
if @options.customFillStyle != undefined
|
393
|
+
fillStyle = @options.customFillStyle(@)
|
394
|
+
else if @percentColors != null
|
395
|
+
fillStyle = @getColorForValue(@displayedValue, true)
|
396
|
+
else if @options.colorStop != undefined
|
397
|
+
if @options.gradientType == 0
|
398
|
+
fillStyle = this.ctx.createRadialGradient(w, h, 9, w, h, 70);
|
399
|
+
else
|
400
|
+
fillStyle = this.ctx.createLinearGradient(0, 0, w, 0);
|
401
|
+
fillStyle.addColorStop(0, @options.colorStart)
|
402
|
+
fillStyle.addColorStop(1, @options.colorStop)
|
403
|
+
else
|
404
|
+
fillStyle = @options.colorStart
|
405
|
+
@ctx.strokeStyle = fillStyle
|
245
406
|
|
246
|
-
grd.addColorStop(0, @options.colorStart)
|
247
|
-
grd.addColorStop(1, @options.colorStop)
|
248
|
-
@ctx.strokeStyle = grd
|
249
407
|
@ctx.beginPath()
|
250
408
|
@ctx.arc(w, h, @radius, (1 + @options.angle) * Math.PI, displayedAngle, false)
|
251
409
|
@ctx.lineWidth = @lineWidth
|
@@ -255,41 +413,42 @@ class Gauge extends ValueUpdater
|
|
255
413
|
@ctx.beginPath()
|
256
414
|
@ctx.arc(w, h, @radius, displayedAngle, (2 - @options.angle) * Math.PI, false)
|
257
415
|
@ctx.stroke()
|
258
|
-
@gp
|
416
|
+
for gauge in @gp
|
417
|
+
gauge.update(true)
|
418
|
+
|
259
419
|
|
260
|
-
class
|
420
|
+
class BaseDonut extends BaseGauge
|
261
421
|
lineWidth: 15
|
262
422
|
displayedValue: 0
|
263
423
|
value: 33
|
264
424
|
maxValue: 80
|
425
|
+
minValue: 0
|
265
426
|
|
266
427
|
options:
|
267
428
|
lineWidth: 0.10
|
268
429
|
colorStart: "#6f6ea0"
|
269
430
|
colorStop: "#c0c0db"
|
270
431
|
strokeColor: "#eeeeee"
|
432
|
+
shadowColor: "#d5d5d5"
|
271
433
|
angle: 0.35
|
272
434
|
|
273
|
-
constructor: (@canvas) ->
|
435
|
+
constructor: (@canvas) ->
|
274
436
|
super()
|
437
|
+
if typeof G_vmlCanvasManager != 'undefined'
|
438
|
+
@canvas = window.G_vmlCanvasManager.initElement(@canvas)
|
275
439
|
@ctx = @canvas.getContext('2d')
|
276
|
-
# @canvas = @elem[0]
|
277
440
|
@setOptions()
|
278
441
|
@render()
|
279
442
|
|
280
443
|
getAngle: (value) ->
|
281
|
-
return (1 - @options.angle) * Math.PI + (value / @maxValue) * ((2 + @options.angle) - (1 - @options.angle)) * Math.PI
|
444
|
+
return (1 - @options.angle) * Math.PI + ((value - @minValue) / (@maxValue - @minValue)) * ((2 + @options.angle) - (1 - @options.angle)) * Math.PI
|
282
445
|
|
283
446
|
setOptions: (options=null) ->
|
284
|
-
|
285
|
-
@lineWidth = @canvas.height * @options.lineWidth
|
447
|
+
super(options)
|
448
|
+
@lineWidth = @canvas.height * @options.lineWidth
|
286
449
|
@radius = @canvas.height / 2 - @lineWidth/2
|
287
|
-
if @textField
|
288
|
-
@textField.style.fontSize = options.fontSize + 'px'
|
289
450
|
return @
|
290
451
|
|
291
|
-
setTextField: (@textField) ->
|
292
|
-
|
293
452
|
set: (value) ->
|
294
453
|
@value = value
|
295
454
|
if @value > @maxValue
|
@@ -302,22 +461,16 @@ class Donut extends ValueUpdater
|
|
302
461
|
h = @canvas.height / 2
|
303
462
|
|
304
463
|
if @textField
|
305
|
-
@textField.
|
464
|
+
@textField.render(@)
|
306
465
|
|
307
466
|
grdFill = @ctx.createRadialGradient(w, h, 39, w, h, 70)
|
308
467
|
grdFill.addColorStop(0, @options.colorStart)
|
309
468
|
grdFill.addColorStop(1, @options.colorStop)
|
310
469
|
|
311
|
-
start = @radius - @lineWidth / 2
|
312
|
-
stop = @radius + @lineWidth / 2
|
470
|
+
start = @radius - @lineWidth / 2
|
471
|
+
stop = @radius + @lineWidth / 2
|
313
472
|
|
314
|
-
|
315
|
-
grd.addColorStop(0, "#d5d5d5")
|
316
|
-
grd.addColorStop(0.12, @options.strokeColor)
|
317
|
-
grd.addColorStop(0.88, @options.strokeColor)
|
318
|
-
grd.addColorStop(1, "#d5d5d5")
|
319
|
-
|
320
|
-
@ctx.strokeStyle = grd
|
473
|
+
@ctx.strokeStyle = @options.strokeColor
|
321
474
|
@ctx.beginPath()
|
322
475
|
@ctx.arc(w, h, @radius, (1 - @options.angle) * Math.PI, (2 + @options.angle) * Math.PI, false)
|
323
476
|
@ctx.lineWidth = @lineWidth
|
@@ -330,6 +483,25 @@ class Donut extends ValueUpdater
|
|
330
483
|
@ctx.stroke()
|
331
484
|
|
332
485
|
|
486
|
+
class Donut extends BaseDonut
|
487
|
+
strokeGradient: (w, h, start, stop) ->
|
488
|
+
grd = @ctx.createRadialGradient(w, h, start, w, h, stop)
|
489
|
+
grd.addColorStop(0, @options.shadowColor)
|
490
|
+
grd.addColorStop(0.12, @options._orgStrokeColor)
|
491
|
+
grd.addColorStop(0.88, @options._orgStrokeColor)
|
492
|
+
grd.addColorStop(1, @options.shadowColor)
|
493
|
+
return grd
|
494
|
+
|
495
|
+
setOptions: (options=null) ->
|
496
|
+
super(options)
|
497
|
+
w = @canvas.width / 2
|
498
|
+
h = @canvas.height / 2
|
499
|
+
start = @radius - @lineWidth / 2
|
500
|
+
stop = @radius + @lineWidth / 2
|
501
|
+
@options._orgStrokeColor = @options.strokeColor
|
502
|
+
@options.strokeColor = @strokeGradient(w, h, start, stop)
|
503
|
+
return @
|
504
|
+
|
333
505
|
window.AnimationUpdater =
|
334
506
|
elements: []
|
335
507
|
animId: null
|
@@ -353,4 +525,5 @@ window.AnimationUpdater =
|
|
353
525
|
|
354
526
|
window.Gauge = Gauge
|
355
527
|
window.Donut = Donut
|
356
|
-
|
528
|
+
window.BaseDonut = BaseDonut
|
529
|
+
window.TextRenderer = TextRenderer
|