gaugejs-rails 0.0.1 → 0.0.2

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.
@@ -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