source: Dev/branches/rest-dojo-ui/jQueryUI/client/RGraph/libraries/RGraph.meter.js @ 312

Last change on this file since 312 was 312, checked in by jkraaijeveld, 13 years ago
File size: 20.0 KB
Line 
1    /**
2    * o------------------------------------------------------------------------------o
3    * | This file is part of the RGraph package - you can learn more at:             |
4    * |                                                                              |
5    * |                          http://www.rgraph.net                               |
6    * |                                                                              |
7    * | This package is licensed under the RGraph license. For all kinds of business |
8    * | purposes there is a small one-time licensing fee to pay and for non          |
9    * | commercial  purposes it is free to use. You can read the full license here:  |
10    * |                                                                              |
11    * |                      http://www.rgraph.net/LICENSE.txt                       |
12    * o------------------------------------------------------------------------------o
13    */
14   
15    if (typeof(RGraph) == 'undefined') RGraph = {};
16
17    /**
18    * The bar chart constructor
19    *
20    * @param string canvas The canvas ID
21    * @param min    integer The minimum value
22    * @param max    integer The maximum value
23    * @param value  integer The indicated value
24    */
25    RGraph.Meter = function (id, min, max, value)
26    {
27        // Get the canvas and context objects
28        this.id                = id;
29        this.canvas            = document.getElementById(id);
30        this.context           = this.canvas.getContext ? this.canvas.getContext("2d") : null;
31        this.canvas.__object__ = this;
32        this.type              = 'meter';
33        this.min               = min;
34        this.max               = max;
35        this.value             = value;
36        this.centerx           = null;
37        this.centery           = null;
38        this.radius            = null;
39        this.isRGraph          = true;
40
41
42        /**
43        * Compatibility with older browsers
44        */
45        RGraph.OldBrowserCompat(this.context);
46
47
48        // Various config type stuff
49        this.properties = {
50            'chart.gutter.left':            25,
51            'chart.gutter.right':           25,
52            'chart.gutter.top':             25,
53            'chart.gutter.bottom':          25,
54            'chart.linewidth':              2,
55            'chart.border.color':           'black',
56            'chart.text.font':              'Verdana',
57            'chart.text.size':              10,
58            'chart.text.color':             'black',
59            'chart.value.label':            false,
60            'chart.value.text.decimals':    0,
61            'chart.value.text.units.pre':   '',
62            'chart.value.text.units.post':  '',
63            'chart.title':                  '',
64            'chart.title.background':       null,
65            'chart.title.hpos':             null,
66            'chart.title.vpos':             null,
67            'chart.title.color':            'black',
68            'chart.green.start':            ((this.max - this.min) * 0.35) + this.min,
69            'chart.green.end':              this.max,
70            'chart.green.color':            '#207A20',
71            'chart.yellow.start':           ((this.max - this.min) * 0.1) + this.min,
72            'chart.yellow.end':             ((this.max - this.min) * 0.35) + this.min,
73            'chart.yellow.color':           '#D0AC41',
74            'chart.red.start':              this.min,
75            'chart.red.end':                ((this.max - this.min) * 0.1) + this.min,
76            'chart.red.color':              '#9E1E1E',
77            'chart.units.pre':              '',
78            'chart.units.post':             '',
79            'chart.contextmenu':            null,
80            'chart.zoom.factor':            1.5,
81            'chart.zoom.fade.in':           true,
82            'chart.zoom.fade.out':          true,
83            'chart.zoom.hdir':              'right',
84            'chart.zoom.vdir':              'down',
85            'chart.zoom.frames':            15,
86            'chart.zoom.delay':             33,
87            'chart.zoom.shadow':            true,
88            'chart.zoom.mode':              'canvas',
89            'chart.zoom.thumbnail.width':   75,
90            'chart.zoom.thumbnail.height':  75,
91            'chart.zoom.background':        true,
92            'chart.zoom.action':            'zoom',
93            'chart.annotatable':            false,
94            'chart.annotate.color':         'black',
95            'chart.shadow':                 false,
96            'chart.shadow.color':           'rgba(0,0,0,0.5)',
97            'chart.shadow.blur':            3,
98            'chart.shadow.offsetx':         3,
99            'chart.shadow.offsety':         3,
100            'chart.resizable':              false,
101            'chart.resize.handle.adjust':   [0,0],
102            'chart.resize.handle.background': null,
103            'chart.tickmarks.small.num':      100,
104            'chart.tickmarks.big.num':        10,
105            'chart.tickmarks.small.color':    '#bbb',
106            'chart.tickmarks.big.color':      'black',
107            'chart.scale.decimals':           0
108        }
109
110
111        // Check for support
112        if (!this.canvas) {
113            alert('[METER] No canvas support');
114            return;
115        }
116       
117        /**
118        * Constrain the value to be within the min and max
119        */
120        if (this.value > this.max) this.value = this.max;
121        if (this.value < this.min) this.value = this.min;
122    }
123
124
125    /**
126    * A setter
127    *
128    * @param name  string The name of the property to set
129    * @param value mixed  The value of the property
130    */
131    RGraph.Meter.prototype.Set = function (name, value)
132    {
133        this.properties[name.toLowerCase()] = value;
134    }
135
136
137    /**
138    * A getter
139    *
140    * @param name  string The name of the property to get
141    */
142    RGraph.Meter.prototype.Get = function (name)
143    {
144        return this.properties[name];
145    }
146
147
148    /**
149    * The function you call to draw the bar chart
150    */
151    RGraph.Meter.prototype.Draw = function ()
152    {
153        /**
154        * Fire the onbeforedraw event
155        */
156        RGraph.FireCustomEvent(this, 'onbeforedraw');
157
158       
159        /**
160        * This is new in May 2011 and facilitates indiviual gutter settings,
161        * eg chart.gutter.left
162        */
163        this.gutterLeft   = this.Get('chart.gutter.left');
164        this.gutterRight  = this.Get('chart.gutter.right');
165        this.gutterTop    = this.Get('chart.gutter.top');
166        this.gutterBottom = this.Get('chart.gutter.bottom');
167
168        this.centerx = this.canvas.width / 2;
169        this.centery = this.canvas.height    - this.gutterBottom;
170        this.radius  = Math.min(
171                                this.canvas.width - this.gutterLeft - this.gutterRight,
172                                this.canvas.height - this.gutterTop - this.gutterBottom
173                               );
174
175        this.DrawBackground();
176        this.DrawNeedle();
177        this.DrawLabels();
178        this.DrawReadout();
179       
180        /**
181        * Draw the title
182        */
183        RGraph.DrawTitle(this.canvas, this.Get('chart.title'), this.gutterTop);
184
185        /**
186        * Setup the context menu if required
187        */
188        if (this.Get('chart.contextmenu')) {
189            RGraph.ShowContext(this);
190        }
191       
192        /**
193        * If the canvas is annotatable, do install the event handlers
194        */
195        if (this.Get('chart.annotatable')) {
196            RGraph.Annotate(this);
197        }
198       
199        /**
200        * This bit shows the mini zoom window if requested
201        */
202        if (this.Get('chart.zoom.mode') == 'thumbnail' || this.Get('chart.zoom.mode') == 'area') {
203            RGraph.ShowZoomWindow(this);
204        }
205
206       
207        /**
208        * This function enables resizing
209        */
210        if (this.Get('chart.resizable')) {
211            RGraph.AllowResizing(this);
212        }
213
214       
215        /**
216        * For MSIE only, to cover the spurious lower ends of the circle
217        */
218        if (RGraph.isIE8()) {
219            // Cover the left tail
220            this.context.beginPath();
221            this.context.moveTo(this.gutterLeft, RGraph.GetHeight(this) - this.gutterBottom);
222            this.context.fillStyle = 'white';
223            this.context.fillRect(this.centerx - this.radius - 5, RGraph.GetHeight(this) - this.gutterBottom + 1, 10, this.gutterBottom);
224            this.context.fill();
225
226            // Cover the right tail
227            this.context.beginPath();
228            this.context.moveTo(RGraph.GetWidth(this) - this.gutterRight, RGraph.GetHeight(this) - this.gutterBottom);
229            this.context.fillStyle = 'white';
230            this.context.fillRect(this.centerx + this.radius - 5, RGraph.GetHeight(this) - this.gutterBottom + 1, 10, this.gutterBottom);
231            this.context.fill();
232        }
233       
234        /**
235        * Fire the RGraph ondraw event
236        */
237        RGraph.FireCustomEvent(this, 'ondraw');
238    }
239
240
241    /**
242    * Draws the background of the chart
243    */
244    RGraph.Meter.prototype.DrawBackground = function ()
245    {
246        // Draw the shadow
247        if (this.Get('chart.shadow')) {
248            this.context.beginPath();
249                this.context.fillStyle     = 'white';
250                this.context.shadowColor   = this.Get('chart.shadow.color');
251                this.context.shadowBlur    = this.Get('chart.shadow.blur');
252                this.context.shadowOffsetX = this.Get('chart.shadow.offsetx');
253                this.context.shadowOffsetY = this.Get('chart.shadow.offsety');
254               
255                this.context.arc(this.centerx, this.centery, this.radius, 3.14, 6.28, false);
256                //this.context.arc(this.centerx, this.centery, , 0, 6.28, false);
257            this.context.fill();
258
259
260            this.context.beginPath();
261                var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
262                this.context.arc(this.centerx, this.centery, r, 0, 6.28, 0);
263            this.context.fill();
264
265            RGraph.NoShadow(this);
266        }
267
268        // First, draw the grey tickmarks
269        this.context.beginPath();
270        this.context.strokeStyle = this.Get('chart.tickmarks.small.color');
271        for (var i=0; i<3.14; i+=(3.14 / this.Get('chart.tickmarks.small.num'))) {
272            this.context.arc(this.centerx, this.centery, this.radius, 3.14 + i, 3.1415 + i, 0);
273            this.context.lineTo(this.centerx, this.centery);
274        }
275        this.context.stroke();
276
277        // Draw the white semi-circle that makes the tickmarks
278        this.context.beginPath();
279        this.context.fillStyle = 'white'
280        this.context.arc(this.centerx, this.centery, this.radius - 4, 3.1415927, 6.28, false);
281        this.context.closePath();
282        this.context.fill();
283
284
285
286        // Second, draw the darker tickmarks. First run draws them in white to get rid of the existing tickmark,
287        // then the second run draws them in the requested color
288        var colors = ['white','white',this.Get('chart.tickmarks.big.color')];
289        for (var j=0; j<colors.length; ++j) {
290            for (var i=0; i<3.14; i+=(3.1415927 / this.Get('chart.tickmarks.big.num'))) {
291                this.context.beginPath();
292                this.context.strokeStyle = colors[j];
293                this.context.arc(this.centerx, this.centery, this.radius, 3.14 + i, 3.1415 + i, 0);
294                this.context.lineTo(this.centerx, this.centery)
295                this.context.stroke();
296            }
297        }
298
299        // Draw the white circle that makes the tickmarks
300        this.context.beginPath();
301        this.context.fillStyle = 'white';
302        this.context.arc(this.centerx, this.centery, this.radius - 7, 3.1415927, 6.28, false);
303        this.context.closePath();
304        this.context.fill();
305
306        // Draw the green area
307        this.context.strokeStyle = this.Get('chart.green.color');
308        this.context.fillStyle = this.Get('chart.green.color');
309        this.context.beginPath();
310        this.context.arc(this.centerx,this.centery,this.radius * 0.85,(((this.Get('chart.green.start') - this.min) / (this.max - this.min)) * 3.1415927) + 3.1415927,(((this.Get('chart.green.end') - this.min) / (this.max - this.min)) * 3.1415927) + 3.1415927,false);
311        this.context.lineTo(this.centerx, this.centery);
312        this.context.closePath();
313        this.context.stroke();
314        this.context.fill();
315       
316        // Draw the yellow area
317        this.context.strokeStyle = this.Get('chart.yellow.color');
318        this.context.fillStyle = this.Get('chart.yellow.color');
319        this.context.beginPath();        this.context.arc(this.centerx,this.centery,this.radius * 0.85,(((this.Get('chart.yellow.start') - this.min) / (this.max - this.min)) * 3.1415927) + 3.1415927,(((this.Get('chart.yellow.end') - this.min) / (this.max - this.min)) * 3.1415927) + 3.1415927,false)
320        this.context.lineTo(this.centerx, this.centery);
321        this.context.closePath();
322        this.context.stroke();
323        this.context.fill();
324       
325        // Draw the yellow area
326        this.context.strokeStyle = this.Get('chart.red.color');
327        this.context.fillStyle = this.Get('chart.red.color');
328        this.context.beginPath();
329        this.context.arc(this.centerx,this.centery,this.radius * 0.85,(((this.Get('chart.red.start') - this.min) / (this.max - this.min)) * 3.1415927) + 3.1415927,(((this.Get('chart.red.end') - this.min) / (this.max - this.min)) * 3.1415927) + 3.1415927,false);
330        this.context.lineTo(this.centerx, this.centery);
331        this.context.closePath();
332        this.context.stroke();
333        this.context.fill();
334
335        // Draw the outline
336        this.context.strokeStyle = this.Get('chart.border.color');
337        this.context.lineWidth   = this.Get('chart.linewidth');
338
339        this.context.beginPath();
340        this.context.moveTo(this.centerx, this.centery);
341        this.context.arc(this.centerx, this.centery, this.radius, 3.1415927, 6.2831854, false);
342        this.context.closePath();
343
344        this.context.stroke();
345       
346        // Reset the linewidth back to 1
347        this.context.lineWidth = 1;
348    }
349
350
351    /**
352    * Draws the pointer
353    */
354    RGraph.Meter.prototype.DrawNeedle = function ()
355    {
356        // First draw the circle at the bottom
357        this.context.fillStyle = 'black';
358        this.context.lineWidth = this.radius >= 200 ? 7 : 3;
359        this.context.lineCap = 'round';
360
361        // Now, draw the pointer
362        this.context.beginPath();
363        this.context.strokeStyle = 'black';
364        var a = (((this.value - this.min) / (this.max - this.min)) * 3.14) + 3.14;
365        this.context.arc(this.centerx, this.centery, this.radius * 0.7, a, a + 0.001, false);
366        this.context.lineTo(this.centerx, this.centery);
367        this.context.stroke();
368       
369        // Draw the triangular needle head
370        this.context.beginPath();
371            this.context.lineWidth = 1;
372            //this.context.moveTo(this.centerx, this.centery);
373            this.context.arc(this.centerx, this.centery, (this.radius * 0.7) + 15, a, a + 0.001, 0);
374            this.context.arc(this.centerx, this.centery, (this.radius * 0.7) - 15, a + 0.087, a + 0.087999, 0);
375            this.context.arc(this.centerx, this.centery, (this.radius * 0.7) - 15, a - 0.087, a - 0.087999, 1);
376        this.context.fill();
377
378        // Draw the center circle
379        var r = (this.radius * 0.06) > 40 ? 40 : (this.radius * 0.06);
380
381        this.context.beginPath();
382        this.context.arc(this.centerx, this.centery, r, 0, 6.28, 0);
383        this.context.fill();
384       
385        // Draw the centre bit of the circle
386        this.context.fillStyle = 'white';
387        this.context.beginPath();
388        this.context.arc(this.centerx, this.centery, r - 2, 0, 6.28, 0);
389        this.context.fill();
390    }
391
392
393    /**
394    * Draws the labels
395    */
396    RGraph.Meter.prototype.DrawLabels = function ()
397    {
398        var context    = this.context;
399        var radius     = this.radius;
400        var text_size  = this.Get('chart.text.size');
401        var text_font  = this.Get('chart.text.font');
402        var units_post = this.Get('chart.units.post');
403        var units_pre  = this.Get('chart.units.pre');
404        var centerx    = this.centerx;
405        var centery    = this.centery;
406        var min        = this.min;
407        var max        = this.max;
408        var decimals   = this.Get('chart.scale.decimals');
409
410        context.fillStyle = this.Get('chart.text.color');
411        context.lineWidth = 1;
412
413        context.beginPath();
414
415
416        RGraph.Text(context, text_font, text_size, centerx - radius + (0.075 * radius), centery - 10, units_pre + (min).toFixed(decimals) + units_post, 'center', 'left', false, 270);
417        RGraph.Text(context,text_font,text_size,centerx - (Math.cos(0.62819 / 2) * (radius - (0.075 * radius)) ),centery - (Math.sin(0.682819 / 2) * (radius - (0.1587 * radius)) ),units_pre + (((max - min) * (1/10)) + min).toFixed(decimals) + units_post,'center','center', false, 288);
418        RGraph.Text(context,text_font,text_size,centerx - (Math.cos(0.62819) * (radius - (0.07 * radius)) ),centery - (Math.sin(0.682819) * (radius - (0.15 * radius)) ),units_pre + (((max - min) * (2/10)) + min).toFixed(decimals) + units_post,'center','center', false, 306);
419        RGraph.Text(context, text_font, text_size,centerx - (Math.cos(0.95) * (radius - (0.085 * radius)) ),centery - (Math.sin(0.95) * (radius - (0.0785 * radius)) ),units_pre + (((max - min) * (3/10)) + min).toFixed(decimals) + units_post,'center', 'center', false, 320);
420        RGraph.Text(context, text_font, text_size,centerx - (Math.cos(1.2566) * (radius - (0.085 * radius)) ),centery - (Math.sin(1.2566) * (radius - (0.0785 * radius)) ),units_pre + (((max - min) * (4/10)) + min).toFixed(decimals) + units_post,'center', 'center', false, 342);
421        RGraph.Text(context,text_font,text_size,centerx - (Math.cos(1.57) * (radius - (0.075 * radius)) ),centery - (Math.sin(1.57) * (radius - (0.075 * radius)) ),units_pre + (((max - min) * (5/10)) + min).toFixed(decimals) + units_post,'center','center', false, 0);
422        RGraph.Text(context,text_font,text_size,centerx - (Math.cos(1.88495562) * (radius - (0.075 * radius)) ),centery - (Math.sin(1.88495562) * (radius - (0.075 * radius)) ),units_pre + (((max - min)* (6/10)) + min).toFixed(decimals) + units_post,'center','center', false, 18);
423        RGraph.Text(context,text_font,text_size,centerx - (Math.cos(2.1989) * (radius - (0.075 * radius)) ),centery - (Math.sin(2.1989) * (radius - (0.075 * radius)) ),units_pre + (((max - min)* (7/10)) + min).toFixed(decimals) + units_post,'center','center', false, 36);
424        RGraph.Text(context,text_font,text_size,centerx - (Math.cos(2.51327416) * (radius - (0.075 * radius)) ),centery - (Math.sin(2.51327416) * (radius - (0.075 * radius)) ), units_pre + (((max - min) * (8/10)) + min).toFixed(decimals) + units_post,'center','center', false, 54);
425        RGraph.Text(context,text_font,text_size,centerx - (Math.cos(2.82764832) * (radius - (0.075 * radius)) ),centery - (Math.sin(2.82764832) * (radius - (0.075 * radius)) ),units_pre + (((max - min) * (9/10)) + min).toFixed(decimals) + units_post,'center','center', false, 72);
426        RGraph.Text(context, text_font, text_size,centerx + radius - (0.075 * radius),centery - 10,units_pre + (max).toFixed(decimals) + units_post, 'center', 'right', false, 90);
427
428        context.fill();
429        context.stroke();
430    }
431
432   
433    /**
434    * This function draws the text readout if specified
435    */
436    RGraph.Meter.prototype.DrawReadout  = function ()
437    {
438        if (this.Get('chart.value.text')) {
439            this.context.beginPath();
440            RGraph.Text(this.context,
441                        this.Get('chart.text.font'),
442                        this.Get('chart.text.size'),
443                        this.centerx,
444                        this.centery - this.Get('chart.text.size') - 15,
445                        this.Get('chart.value.text.units.pre') + (this.value).toFixed(this.Get('chart.value.text.decimals')) + this.Get('chart.value.text.units.post'),
446                         'center',
447                         'center',
448                         true,
449                         null,
450                         'white');
451
452            this.context.stroke();
453            this.context.fill();
454        }
455    }
Note: See TracBrowser for help on using the repository browser.