source: Dev/branches/jQueryUI/client/RGraph/libraries/RGraph.meter.js @ 249

Last change on this file since 249 was 249, checked in by hendrikvanantwerpen, 13 years ago

This one's for Subversion, because it's so close...

First widget (stripped down sequencer).
Seperated client and server code in two direcotry trees.

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.