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