source: Dev/branches/jQueryUI/client/RGraph/libraries/RGraph.vprogress.js @ 281

Last change on this file since 281 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: 23.4 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 progress bar constructor
19    *
20    * @param int id    The ID of the canvas tag
21    * @param int value The indicated value of the meter.
22    * @param int max   The end value (the upper most) of the meter
23    */
24    RGraph.VProgress = function (id, value, max)
25    {
26        this.id                = id;
27        this.max               = max;
28        this.value             = value;
29        this.canvas            = document.getElementById(id);
30        this.context           = this.canvas.getContext('2d');
31        this.canvas.__object__ = this;
32        this.type              = 'vprogress';
33        this.coords            = [];
34        this.isRGraph          = true;
35
36
37        /**
38        * Compatibility with older browsers
39        */
40        RGraph.OldBrowserCompat(this.context);
41
42        this.properties = {
43            'chart.colors':             ['#0c0'],
44            'chart.tickmarks':          true,
45            'chart.tickmarks.zerostart':false,
46            'chart.tickmarks.color':    'black',
47            'chart.tickmarks.inner':    false,
48            'chart.gutter.left':        25,
49            'chart.gutter.right':       25,
50            'chart.gutter.top':         25,
51            'chart.gutter.bottom':      25,
52            'chart.numticks':           10,
53            'chart.numticks.inner':     50,
54            'chart.background.color':   '#eee',
55            'chart.shadow':             false,
56            'chart.shadow.color':       'rgba(0,0,0,0.5)',
57            'chart.shadow.blur':        3,
58            'chart.shadow.offsetx':     3,
59            'chart.shadow.offsety':     3,
60            'chart.title':              '',
61            'chart.title.background':   null,
62            'chart.title.hpos':         null,
63            'chart.title.vpos':         null,
64            'chart.width':              0,
65            'chart.height':             0,
66            'chart.text.size':          10,
67            'chart.text.color':         'black',
68            'chart.text.font':          'Verdana',
69            'chart.contextmenu':        null,
70            'chart.units.pre':          '',
71            'chart.units.post':         '',
72            'chart.tooltips':           [],
73            'chart.tooltips.effect':    'fade',
74            'chart.tooltips.css.class': 'RGraph_tooltip',
75            'chart.tooltips.highlight': true,
76            'chart.tooltips.coords.adjust': [0,0],
77            'chart.highlight.stroke':   'black',
78            'chart.highlight.fill':     'rgba(255,255,255,0.5)',
79            'chart.annotatable':        false,
80            'chart.annotate.color':     'black',
81            'chart.zoom.mode':          'canvas',
82            'chart.zoom.factor':        1.5,
83            'chart.zoom.fade.in':       true,
84            'chart.zoom.fade.out':      true,
85            'chart.zoom.hdir':          'right',
86            'chart.zoom.vdir':          'down',
87            'chart.zoom.frames':        10,
88            'chart.zoom.delay':         50,
89            'chart.zoom.shadow':        true,
90            'chart.zoom.background':    true,
91            'chart.zoom.action':        'zoom',
92            'chart.arrows':             false,
93            'chart.margin':             0,
94            'chart.resizable':              false,
95            'chart.resize.handle.adjust':   [0,0],
96            'chart.resize.handle.background': null,
97            'chart.label.inner':        false,
98            'chart.labels.count':       10,
99            'chart.labels.position':    'right',
100            'chart.adjustable':         false,
101            'chart.min':                0,
102            'chart.scale.decimals':     0,
103            'chart.key':                [],
104            'chart.key.background':     'white',
105            'chart.key.position':       'graph',
106            'chart.key.halign':             'right',
107            'chart.key.shadow':         false,
108            'chart.key.shadow.color':   '#666',
109            'chart.key.shadow.blur':    3,
110            'chart.key.shadow.offsetx': 2,
111            'chart.key.shadow.offsety': 2,
112            'chart.key.position.gutter.boxed': true,
113            'chart.key.position.x':     null,
114            'chart.key.position.y':     null,
115            'chart.key.color.shape':    'square',
116            'chart.key.rounded':        true,
117            'chart.key.linewidth':      1
118        }
119
120        // Check for support
121        if (!this.canvas) {
122            alert('[PROGRESS] No canvas support');
123            return;
124        }
125    }
126
127
128    /**
129    * A generic setter
130    *
131    * @param string name  The name of the property to set
132    * @param string value The value of the poperty
133    */
134    RGraph.VProgress.prototype.Set = function (name, value)
135    {
136        this.properties[name.toLowerCase()] = value;
137    }
138
139
140    /**
141    * A generic getter
142    *
143    * @param string name  The name of the property to get
144    */
145    RGraph.VProgress.prototype.Get = function (name)
146    {
147        return this.properties[name.toLowerCase()];
148    }
149
150
151    /**
152    * Draws the progress bar
153    */
154    RGraph.VProgress.prototype.Draw = function ()
155    {
156        /**
157        * Fire the onbeforedraw event
158        */
159        RGraph.FireCustomEvent(this, 'onbeforedraw');
160
161        /**
162        * Clear all of this canvases event handlers (the ones installed by RGraph)
163        */
164        RGraph.ClearEventListeners(this.id);
165       
166        /**
167        * This is new in May 2011 and facilitates indiviual gutter settings,
168        * eg chart.gutter.left
169        */
170        this.gutterLeft   = this.Get('chart.gutter.left');
171        this.gutterRight  = this.Get('chart.gutter.right');
172        this.gutterTop    = this.Get('chart.gutter.top');
173        this.gutterBottom = this.Get('chart.gutter.bottom');
174
175        // Figure out the width and height
176        this.width  = RGraph.GetWidth(this) - this.gutterLeft - this.gutterRight;
177        this.height = RGraph.GetHeight(this) - this.gutterTop - this.gutterBottom;
178        this.coords = [];
179
180        this.Drawbar();
181        this.DrawTickMarks();
182        this.DrawLabels();
183
184        this.context.stroke();
185        this.context.fill();
186
187        /**
188        * Setup the context menu if required
189        */
190        if (this.Get('chart.contextmenu')) {
191            RGraph.ShowContext(this);
192        }
193       
194        /**
195        * Alternatively, show the tooltip if requested
196        */
197        if (typeof(this.Get('chart.tooltips')) == 'function' || this.Get('chart.tooltips').length) {
198
199            // Need to register this object for redrawing
200            RGraph.Register(this);
201
202            /**
203            * Install the window onclick handler
204            */
205            var window_onclick = function ()
206            {
207                RGraph.Redraw();
208            }
209            window.addEventListener('click', window_onclick, false);
210            RGraph.AddEventListener('window_' + this.id, 'click', window_onclick);
211
212
213            /**
214            * Install the onclick event handler for the tooltips
215            */
216            //this.canvas.onclick = function (e)
217            var canvas_onclick_func = function (e)
218            {
219                e = RGraph.FixEventObject(e);
220
221                var canvas = document.getElementById(this.id);
222                var obj = canvas.__object__;
223
224                /**
225                * Redraw the graph first, in effect resetting the graph to as it was when it was first drawn
226                * This "deselects" any already selected bar
227                */
228                RGraph.Redraw();
229   
230                /**
231                * Get the mouse X/Y coordinates
232                */
233                var mouseCoords = RGraph.getMouseXY(e);
234
235                /**
236                * Loop through the bars determining if the mouse is over a bar
237                */
238                for (var i=0; i<obj.coords.length; i++) {
239
240                    var mouseX = mouseCoords[0] - obj.Get('chart.tooltips.coords.adjust')[0];
241                    var mouseY = mouseCoords[1] - obj.Get('chart.tooltips.coords.adjust')[1];
242                    var left   = obj.coords[i][0];
243                    var top    = obj.coords[i][1];
244                    var width  = obj.coords[i][2];
245                    var height = obj.coords[i][3];
246                    var idx    = i;
247
248                    if (mouseX >= left && mouseX <= (left + width) && mouseY >= top && mouseY <= (top + height) ) {
249   
250                        /**
251                        * Get the tooltip text
252                        */
253                        if (typeof(obj.Get('chart.tooltips')) == 'function') {
254                            var text = obj.Get('chart.tooltips')(idx);
255                       
256                        } else if (typeof(obj.Get('chart.tooltips')) == 'object' && typeof(obj.Get('chart.tooltips')[idx]) == 'function') {
257                            var text = obj.Get('chart.tooltips')[idx](idx);
258                       
259                        } else if (typeof(obj.Get('chart.tooltips')) == 'object') {
260                            var text = obj.Get('chart.tooltips')[idx];
261
262                        } else {
263                            var text = null;
264                        }
265
266                        /**
267                        * Show a tooltip if it's defined
268                        */
269                        if (text) {
270
271                            obj.context.beginPath();
272                            obj.context.strokeStyle = obj.Get('chart.highlight.stroke');
273                            obj.context.fillStyle   = obj.Get('chart.highlight.fill');
274                            obj.context.strokeRect(left, top, width, height);
275                            obj.context.fillRect(left, top, width, height);
276       
277                            obj.context.stroke();
278                            obj.context.fill();
279
280                            RGraph.Tooltip(canvas, text, e.pageX, e.pageY, i);
281                        }
282                    }
283                }
284
285                /**
286                * Stop the event bubbling
287                */
288                e.stopPropagation();
289            }
290            this.canvas.addEventListener('click', canvas_onclick_func, false);
291            RGraph.AddEventListener(this.id, 'click', canvas_onclick_func);
292
293
294            /**
295            * If the cursor is over a hotspot, change the cursor to a hand
296            */
297            //this.canvas.onmousemove = function (e)
298            var canvas_onmousemove_func = function (e)
299            {
300                e = RGraph.FixEventObject(e);
301
302                var canvas = document.getElementById(this.id);
303                var obj = canvas.__object__;
304
305                /**
306                * Get the mouse X/Y coordinates
307                */
308                var mouseCoords = RGraph.getMouseXY(e);
309
310                /**
311                * Loop through the bars determining if the mouse is over a bar
312                */
313                for (var i=0; i<obj.coords.length; i++) {
314
315                    var mouseX = mouseCoords[0] - obj.Get('chart.tooltips.coords.adjust')[0];  // In relation to the canvas
316                    var mouseY = mouseCoords[1] - obj.Get('chart.tooltips.coords.adjust')[1];  // In relation to the canvas
317                    var left   = obj.coords[i][0];
318                    var top    = obj.coords[i][1];
319                    var width  = obj.coords[i][2];
320                    var height = obj.coords[i][3];
321
322                    if (mouseX >= left && mouseX <= (left + width) && mouseY >= top && mouseY <= (top + height) ) {
323                        canvas.style.cursor = 'pointer';
324                        break;
325                    }
326                   
327                    canvas.style.cursor = 'default';
328                }
329            }
330            this.canvas.addEventListener('mousemove', canvas_onmousemove_func, false);
331            RGraph.AddEventListener(this.id, 'mousemove', canvas_onmousemove_func);
332        }
333       
334        /**
335        * If the canvas is annotatable, do install the event handlers
336        */
337        if (this.Get('chart.annotatable')) {
338            RGraph.Annotate(this);
339        }
340       
341        /**
342        * This bit shows the mini zoom window if requested
343        */
344        if (this.Get('chart.zoom.mode') == 'thumbnail' || this.Get('chart.zoom.mode') == 'area') {
345            RGraph.ShowZoomWindow(this);
346        }
347       
348        // Draw a key if necessary
349        if (this.Get('chart.key').length) {
350            RGraph.DrawKey(this, this.Get('chart.key'), this.Get('chart.colors'));
351        }
352
353
354       
355        /**
356        * This function enables resizing
357        */
358        if (this.Get('chart.resizable')) {
359            RGraph.AllowResizing(this);
360        }
361       
362        /**
363        * Instead of using RGraph.common.adjusting.js, handle them here
364        */
365        if (this.Get('chart.adjustable')) {
366            RGraph.AllowAdjusting(this);
367        }
368       
369        /**
370        * Fire the RGraph ondraw event
371        */
372        RGraph.FireCustomEvent(this, 'ondraw');
373    }
374
375
376    /**
377    * Draw the bar itself
378    */
379    RGraph.VProgress.prototype.Drawbar = function ()
380    {
381        // Set a shadow if requested
382        if (this.Get('chart.shadow')) {
383            RGraph.SetShadow(this, this.Get('chart.shadow.color'), this.Get('chart.shadow.offsetx'), this.Get('chart.shadow.offsety'), this.Get('chart.shadow.blur'));
384        }
385
386        // Draw the shadow for MSIE
387        if (RGraph.isIE8() && this.Get('chart.shadow')) {
388            this.context.fillStyle = this.Get('chart.shadow.color');
389            this.context.fillRect(this.gutterLeft + this.Get('chart.shadow.offsetx'), this.gutterTop + this.Get('chart.shadow.offsety'), this.width, this.height);
390        }
391
392        // Draw the outline
393        this.context.fillStyle   = this.Get('chart.background.color');
394        this.context.strokeStyle = 'black';
395        this.context.strokeRect(this.gutterLeft, this.gutterTop, this.width, this.height);
396        this.context.fillRect(this.gutterLeft, this.gutterTop, this.width, this.height);
397
398        // Turn off any shadow
399        RGraph.NoShadow(this);
400
401        this.context.strokeStyle = 'black';
402        this.context.fillStyle   = this.Get('chart.colors')[0];
403        var margin = this.Get('chart.margin');
404        var barHeight = RGraph.GetHeight(this) - this.gutterTop - this.gutterBottom;
405
406        // Draw the actual bar itself
407        if (typeof(this.value) == 'number') {
408
409            this.context.lineWidth   = 1;
410            this.context.strokeStyle = '#999';
411
412        } else if (typeof(this.value) == 'object') {
413
414            this.context.beginPath();
415            this.context.strokeStyle = '#999';
416
417            var startPoint = RGraph.GetHeight(this) - this.gutterBottom;
418           
419            for (var i=0; i<this.value.length; ++i) {
420
421                var segmentHeight = ( (this.value[i] - this.Get('chart.min')) / (this.max - this.Get('chart.min')) ) * barHeight;
422
423                this.context.fillStyle = this.Get('chart.colors')[i];
424
425                this.context.fillRect(this.gutterLeft + margin, startPoint - segmentHeight, this.width - margin - margin, segmentHeight);
426                this.context.strokeRect(this.gutterLeft + margin, startPoint - segmentHeight, this.width - margin - margin, segmentHeight);
427
428
429                // Store the coords
430                this.coords.push([this.gutterLeft + margin, startPoint - segmentHeight, this.width - margin - margin, segmentHeight]);
431
432                startPoint -= segmentHeight;
433            }
434
435        }
436
437        /**
438        * Inner tickmarks
439        */
440        if (this.Get('chart.tickmarks.inner')) {
441       
442            var spacing = (RGraph.GetHeight(this) - this.gutterTop - this.gutterBottom) / this.Get('chart.numticks.inner');
443
444            this.context.lineWidth   = 1;
445            this.context.strokeStyle = '#999';
446
447            this.context.beginPath();
448
449            for (var y = this.gutterTop; y<RGraph.GetHeight(this) - this.gutterBottom; y+=spacing) {
450                this.context.moveTo(this.gutterLeft, y);
451                this.context.lineTo(this.gutterLeft + 3, y);
452
453                this.context.moveTo(RGraph.GetWidth(this) - this.gutterRight, y);
454                this.context.lineTo(RGraph.GetWidth(this) - this.gutterRight - 3, y);
455            }
456
457            this.context.stroke();
458        }
459
460        /**
461        * Draw the actual bar
462        */
463        var barHeight = Math.min(this.height, ( (this.value - this.Get('chart.min')) / (this.max - this.Get('chart.min')) ) * this.height);
464
465        this.context.beginPath();
466        this.context.strokeStyle = 'black';
467
468        if (typeof(this.value) == 'number') {
469            this.context.strokeRect(this.gutterLeft + margin, this.gutterTop + this.height - barHeight, this.width - margin - margin, barHeight);
470            this.context.fillRect(this.gutterLeft + margin, this.gutterTop + this.height - barHeight, this.width - margin - margin, barHeight);
471        }
472
473
474        /**
475        * Draw the arrows indicating the level if requested
476        */
477        if (this.Get('chart.arrows')) {
478            var x = this.gutterLeft - 4;
479            var y = RGraph.GetHeight(this) - this.gutterBottom - barHeight;
480           
481            this.context.lineWidth = 1;
482            this.context.fillStyle = 'black';
483            this.context.strokeStyle = 'black';
484
485            this.context.beginPath();
486                this.context.moveTo(x, y);
487                this.context.lineTo(x - 4, y - 2);
488                this.context.lineTo(x - 4, y + 2);
489            this.context.closePath();
490
491            this.context.stroke();
492            this.context.fill();
493
494            x +=  this.width + 8;
495
496            this.context.beginPath();
497                this.context.moveTo(x, y);
498                this.context.lineTo(x + 4, y - 2);
499                this.context.lineTo(x + 4, y + 2);
500            this.context.closePath();
501
502            this.context.stroke();
503            this.context.fill();
504        }
505
506
507
508
509        /**
510        * Draw the "in-bar" label
511        */
512        if (this.Get('chart.label.inner')) {
513            this.context.beginPath();
514            this.context.fillStyle = 'black';
515            RGraph.Text(this.context, this.Get('chart.text.font'), this.Get('chart.text.size') + 2, RGraph.GetWidth(this) / 2, RGraph.GetHeight(this) - this.gutterBottom - barHeight - 5, String(this.Get('chart.units.pre') + this.value + this.Get('chart.units.post')), 'bottom', 'center');
516            this.context.fill();
517        }
518
519
520        // Store the coords
521        this.coords.push([this.gutterLeft + margin, this.gutterTop + this.height - barHeight, this.width - margin - margin, barHeight]);
522    }
523
524    /**
525    * The function that draws the tick marks. Apt name...
526    */
527    RGraph.VProgress.prototype.DrawTickMarks = function ()
528    {
529        this.context.strokeStyle = this.Get('chart.tickmarks.color');
530
531        if (this.Get('chart.tickmarks')) {
532            this.context.beginPath();
533                for (var i=0; this.Get('chart.tickmarks.zerostart') ? i<=this.Get('chart.numticks') : i<this.Get('chart.numticks'); i++) {
534                   
535                    var startX = this.Get('chart.labels.position') == 'left' ? this.gutterLeft : this.canvas.width - this.Get('chart.gutter.right');
536                    var endX   = this.Get('chart.labels.position') == 'left' ? startX - 4 : startX + 4;
537                    var yPos   = (this.height * (i / this.Get('chart.numticks'))) + this.gutterTop
538
539                    this.context.moveTo(startX, yPos);
540                    this.context.lineTo(endX, yPos);
541                }
542            this.context.stroke();
543        }
544    }
545
546
547    /**
548    * The function that draws the labels
549    */
550    RGraph.VProgress.prototype.DrawLabels = function ()
551    {
552        this.context.fillStyle = this.Get('chart.text.color');
553
554        var context    = this.context;
555        var position   = this.Get('chart.labels.position');
556        var xAlignment = position == 'left' ? 'right' : 'left';
557        var yAlignment = 'center';
558        var count      = this.Get('chart.labels.count');
559        var units_pre  = this.Get('chart.units.pre');
560        var units_post = this.Get('chart.units.post');
561        var text_size  = this.Get('chart.text.size');
562        var text_font  = this.Get('chart.text.font');
563       
564        if (this.Get('chart.tickmarks')) {
565           
566            for (var i=0; i<count ; ++i) {
567
568                var text = String(
569                                  ((( (this.max - this.Get('chart.min')) / count) * (count - i)) + this.Get('chart.min')).toFixed(this.Get('chart.scale.decimals'))
570                                 );
571
572                RGraph.Text(context,
573                            text_font,
574                            text_size,
575                            position == 'left' ? (this.gutterLeft - 5) : (RGraph.GetWidth(this) - this.gutterRight + 5),
576                            (((RGraph.GetHeight(this) - this.gutterTop - this.gutterBottom) / count) * i) + this.gutterTop,
577                            units_pre + text + units_post,
578                            yAlignment,
579                            xAlignment);
580            }
581           
582            /**
583            * Show zero?
584            */           
585            if (this.Get('chart.tickmarks.zerostart') && this.Get('chart.min') == 0) {
586                RGraph.Text(context,
587                            text_font,
588                            text_size,
589                            position == 'left' ? (this.gutterLeft - 5) : (RGraph.GetWidth(this) - this.gutterRight + 5),
590                            RGraph.GetHeight(this) - this.gutterBottom, units_pre + String(this.Get('chart.min').toFixed(this.Get('chart.scale.decimals'))) + units_post,
591                            yAlignment,
592                            xAlignment);
593            }
594
595            /**
596            * chart.ymin is set
597            */
598            if (this.Get('chart.min') != 0) {
599                RGraph.Text(context,
600                            text_font,
601                            text_size,
602                            position == 'left' ? (this.gutterLeft - 5) : (RGraph.GetWidth(this) - this.gutterRight + 5),
603                            RGraph.GetHeight(this) - this.gutterBottom, units_pre + String(this.Get('chart.min').toFixed(this.Get('chart.scale.decimals'))) + units_post,
604                            yAlignment,
605                            xAlignment);
606            }
607        }
608
609        // Draw the title text
610        if (this.Get('chart.title')) {
611            RGraph.Text(context,
612                        text_font,
613                        text_size + 2,
614                        this.gutterLeft + ((this.canvas.width - this.gutterLeft - this.gutterRight) / 2), // X
615                        this.gutterTop - text_size, // Y
616                        this.Get('chart.title'),
617                        null,
618                        'center',null, null, null, true);
619        }
620    }
Note: See TracBrowser for help on using the repository browser.