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.
@@ -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
@@ -1,5 +1,5 @@
1
1
  module GaugeJS
2
2
  module Rails
3
- VERSION = '0.0.1'
3
+ VERSION = '0.0.2'
4
4
  end
5
5
  end
@@ -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
- addCommas =(nStr) ->
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
- AnimationUpdater.add(@)
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
- strokeWidth: 3
127
- length: 76
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
- constructor: (@ctx, @canvas) ->
132
- # @length = @canvas.height * @options.length
133
- # @strokeWidth = @canvas.height * @options.strokeWidth
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: (angle) ->
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 = "black"
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
- # alert(valPercent)
262
+
186
263
  $(".bar-value", @elem).css({"width": valPercent + "%"})
187
264
  $(".typical-value", @elem).css({"width": avgPercent + "%"})
188
265
 
189
- class Gauge extends ValueUpdater
266
+ class Gauge extends BaseGauge
190
267
  elem: null
191
- value: 20
268
+ value: [20] # we support multiple pointers
192
269
  maxValue: 80
193
- # angle: 1.45 * Math.PI
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: "#8fc0da"
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(@ctx, @canvas)
300
+ @gp = [new GaugePointer(@)]
212
301
  @setOptions()
213
302
  @render()
214
303
 
215
304
  setOptions: (options=null) ->
216
- updateObjectValues(@options, options)
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
- @gp.setOptions(@options.pointer)
220
- if @textField
221
- @textField.style.fontSize = options.fontSize + 'px'
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
- @value = value
226
- if @value > @maxValue
227
- @maxValue = @value * 1.1
228
- AnimationUpdater.run()
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
- setTextField: (@textField) ->
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.innerHTML = formatNumber(@displayedValue)
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.render(displayedAngle)
416
+ for gauge in @gp
417
+ gauge.update(true)
418
+
259
419
 
260
- class Donut extends ValueUpdater
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) -> #, @color=["#6fadcf", "#8fc0da"]) ->
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
- updateObjectValues(@options, options)
285
- @lineWidth = @canvas.height * @options.lineWidth #0.10
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.innerHTML = formatNumber(@displayedValue)
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
- grd = @ctx.createRadialGradient(w, h, start, w, h, stop)
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