source: Dev/branches/Cartis/Tiles preview/js/RGraph/libraries/RGraph.rose.js @ 283

Last change on this file since 283 was 283, checked in by tjcschipper, 13 years ago

Cartis Mockup werkt!

W
I
N
N
I
N
G

File size: 37.1 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 rose chart constuctor
19    *
20    * @param object canvas
21    * @param array data
22    */
23    RGraph.Rose = function (id, data)
24    {
25        this.id                = id;
26        this.canvas            = document.getElementById(id);
27        this.context           = this.canvas.getContext('2d');
28        this.data              = data;
29        this.canvas.__object__ = this;
30        this.type              = 'rose';
31        this.isRGraph          = true;
32
33
34        /**
35        * Compatibility with older browsers
36        */
37        RGraph.OldBrowserCompat(this.context);
38
39
40        this.centerx = 0;
41        this.centery = 0;
42        this.radius  = 0;
43        this.max     = 0;
44       
45        this.properties = {
46            'chart.radius':                 null,
47            'chart.colors':                 ['red', 'rgb(0,255,255)', 'rgb(0,255,0)', 'gray', 'blue', 'rgb(255,128,255)','green', 'pink', 'gray', 'aqua'],
48            'chart.colors.sequential':      false,
49            'chart.colors.alpha':           null,
50            'chart.strokestyle':            'rgba(0,0,0,0.5)',
51            'chart.gutter.left':            25,
52            'chart.gutter.right':           25,
53            'chart.gutter.top':             25,
54            'chart.gutter.bottom':          25,
55            'chart.title':                  '',
56            'chart.title.background':       null,
57            'chart.title.hpos':             null,
58            'chart.title.vpos':             null,
59            'chart.labels':                 null,
60            'chart.labels.position':       'center',
61            'chart.labels.axes':            'nsew',
62            'chart.labels.offset':          0,
63            'chart.text.color':             'black',
64            'chart.text.font':              'Verdana',
65            'chart.text.size':              10,
66            'chart.key':                    null,
67            'chart.key.background':         'white',
68            'chart.key.position':           'graph',
69            'chart.key.halign':             'right',
70            'chart.key.shadow':             false,
71            'chart.key.shadow.color':       '#666',
72            'chart.key.shadow.blur':        3,
73            'chart.key.shadow.offsetx':     2,
74            'chart.key.shadow.offsety':     2,
75            'chart.key.position.gutter.boxed': true,
76            'chart.key.position.x':         null,
77            'chart.key.position.y':         null,
78            'chart.key.color.shape':        'square',
79            'chart.key.rounded':            true,
80            'chart.key.linewidth':          1,
81            'chart.contextmenu':            null,
82            'chart.tooltips':               null,
83            'chart.tooltips.event':         'onclick',
84            'chart.tooltips.effect':        'fade',
85            'chart.tooltips.css.class':     'RGraph_tooltip',
86            'chart.tooltips.highlight':     true,
87            'chart.highlight.stroke':       'black',
88            'chart.highlight.fill':         'rgba(255,255,255,0.5)',
89            'chart.annotatable':            false,
90            'chart.annotate.color':         'black',
91            'chart.zoom.factor':            1.5,
92            'chart.zoom.fade.in':           true,
93            'chart.zoom.fade.out':          true,
94            'chart.zoom.hdir':              'right',
95            'chart.zoom.vdir':              'down',
96            'chart.zoom.frames':            10,
97            'chart.zoom.delay':             50,
98            'chart.zoom.shadow':            true,
99            'chart.zoom.mode':              'canvas',
100            'chart.zoom.thumbnail.width':   75,
101            'chart.zoom.thumbnail.height':  75,
102            'chart.zoom.background':        true,
103            'chart.zoom.action':            'zoom',
104            'chart.resizable':              false,
105            'chart.resize.handle.adjust':   [0,0],
106            'chart.resize.handle.background': null,
107            'chart.adjustable':             false,
108            'chart.ymax':                   null,
109            'chart.ymin':                   0,
110            'chart.scale.decimals':         null,
111            'chart.variant':                'stacked'
112        }
113
114
115        /**
116        * Set the .getShape commonly named method
117        */
118        this.getShape = this.getSegment;
119    }
120
121
122    /**
123    * A simple setter
124    *
125    * @param string name  The name of the property to set
126    * @param string value The value of the property
127    */
128    RGraph.Rose.prototype.Set = function (name, value)
129    {
130        this.properties[name.toLowerCase()] = value;
131    }
132   
133   
134    /**
135    * A simple getter
136    *
137    * @param string name The name of the property to get
138    */
139    RGraph.Rose.prototype.Get = function (name)
140    {
141        return this.properties[name.toLowerCase()];
142    }
143
144   
145    /**
146    * This method draws the rose chart
147    */
148    RGraph.Rose.prototype.Draw = function ()
149    {
150        /**
151        * Fire the onbeforedraw event
152        */
153        RGraph.FireCustomEvent(this, 'onbeforedraw');
154       
155        /**
156        * Clear all of this canvases event handlers (the ones installed by RGraph)
157        */
158        RGraph.ClearEventListeners(this.id);
159
160       
161        /**
162        * This doesn't affect the chart, but is used for compatibility
163        */
164        this.gutterLeft   = this.Get('chart.gutter.left');
165        this.gutterRight  = this.Get('chart.gutter.right');
166        this.gutterTop    = this.Get('chart.gutter.top');
167        this.gutterBottom = this.Get('chart.gutter.bottom');
168
169        // Calculate the radius
170        this.radius       = (Math.min(RGraph.GetWidth(this) - this.gutterLeft - this.gutterRight, RGraph.GetHeight(this) - this.gutterTop - this.gutterBottom) / 2);
171        this.centerx      = RGraph.GetWidth(this) / 2;
172        this.centery      = RGraph.GetHeight(this) / 2;
173        this.angles       = [];
174        this.total        = 0;
175        this.startRadians = 0;
176       
177        // User specified radius
178        if (typeof(this.Get('chart.radius')) == 'number') {
179            this.radius = this.Get('chart.radius');
180        }
181       
182        /**
183        * Change the centerx marginally if the key is defined
184        */
185        if (this.Get('chart.key') && this.Get('chart.key').length > 0 && this.Get('chart.key').length >= 3) {
186            this.centerx = this.centerx - this.Get('chart.gutter.right') + 5;
187        }
188
189        this.DrawBackground();
190        this.DrawRose();
191        this.DrawLabels();
192
193        /**
194        * Setup the context menu if required
195        */
196        if (this.Get('chart.contextmenu')) {
197            RGraph.ShowContext(this);
198        }
199
200        /**
201        * Tooltips
202        */
203        if (this.Get('chart.tooltips')) {
204
205            /**
206            * Register this object for redrawing
207            */
208            RGraph.Register(this);
209       
210            /**
211            * The onclick event
212            */
213            var canvas_onclick_func = function (e)
214            {
215                var obj     = e.target.__object__;
216                var canvas  = e.target;
217                var context = canvas.getContext('2d');
218
219                e = RGraph.FixEventObject(e);
220
221                RGraph.Redraw();
222               
223                var segment = obj.getSegment(e);
224
225                if (segment && obj.Get('chart.tooltips')) {
226
227                    /**
228                    * Get the tooltip text
229                    */
230                    if (typeof(obj.Get('chart.tooltips')) == 'function') {
231                        var text = String(obj.Get('chart.tooltips')(segment[6]));
232                    } else if (typeof(obj.Get('chart.tooltips')) == 'object' && typeof(obj.Get('chart.tooltips')[segment[6]]) == 'function') {
233                        var text = String(obj.Get('chart.tooltips')[segment[6]](segment[6]));
234                    } else if (typeof(obj.Get('chart.tooltips')) == 'object' && (typeof(obj.Get('chart.tooltips')[segment[6]]) == 'string' || typeof(obj.Get('chart.tooltips')[segment[6]]) == 'number')) {
235                        var text = String(obj.Get('chart.tooltips')[segment[6]]);
236                    } else {
237                        var text = null;
238                    }
239
240                    if (text) {
241                        context.beginPath();
242                            context.strokeStyle = obj.Get('chart.highlight.stroke');
243                            context.fillStyle   = obj.Get('chart.highlight.fill');
244                           
245                            // This highlights the chart
246                            context.arc(obj.centerx, obj.centery, segment[3], segment[4] / 57.3, segment[5] / 57.3, false);
247                            context.arc(obj.centerx, obj.centery, segment[2] + 0.01, segment[5] / 57.3, segment[4] / 57.3, true);
248   
249                        context.closePath();
250   
251                        context.fill();
252                        context.stroke();
253   
254                        context.strokeStyle = 'rgba(0,0,0,0)';
255
256                        // Taken out on 12th June 2011
257                        //obj.DrawLabels();
258                       
259                        /**
260                        * Show the tooltip
261                        */
262                        RGraph.Tooltip(canvas, text, e.pageX, e.pageY, segment[6]);
263   
264                        e.stopPropagation();
265                    }
266
267                    return;
268                }
269            }
270            this.canvas.addEventListener('click', canvas_onclick_func, false);
271            RGraph.AddEventListener(this.id, 'click', canvas_onclick_func);
272
273
274            /**
275            * The onmousemove event
276            */
277            var canvas_onmousemove_func = function (e)
278            {
279
280                var obj     = e.target.__object__;
281                var canvas  = e.target;
282                var context = canvas.getContext('2d');
283
284                e = RGraph.FixEventObject(e);
285
286                var segment = obj.getSegment(e);
287
288                if (segment && obj.Get('chart.tooltips')) {
289
290                    /**
291                    * Get the tooltip text
292                    */
293                    if (typeof(obj.Get('chart.tooltips')) == 'function') {
294                        var text = String(obj.Get('chart.tooltips')(segment[6]));
295                    } else if (typeof(obj.Get('chart.tooltips')) == 'object' && typeof(obj.Get('chart.tooltips')[segment[6]]) == 'function') {
296                        var text = String(obj.Get('chart.tooltips')[segment[6]](segment[6]));
297                    } else if (typeof(obj.Get('chart.tooltips')) == 'object' && (typeof(obj.Get('chart.tooltips')[segment[6]]) == 'string' || typeof(obj.Get('chart.tooltips')[segment[6]]) == 'number')) {
298                        var text = String(obj.Get('chart.tooltips')[segment[6]]);
299                    } else {
300                        var text = null;
301                    }
302
303                    if (text) {
304                        canvas.style.cursor = 'pointer';
305               
306                        /*******************************************************
307                        * This is here in case tooltips are using the
308                        * onmousemove event
309                        *******************************************************/
310                        if (obj.Get('chart.tooltips.event') == 'onmousemove') {
311                            if (!RGraph.Registry.Get('chart.tooltip') || RGraph.Registry.Get('chart.tooltip').__index__ != segment[6]) {
312                                canvas_onclick_func(e);
313                            }
314                        }
315
316                    } else {
317                        canvas.style.cursor = 'default';
318                    }
319
320                    return;
321                }
322
323                canvas.style.cursor = 'default';
324            }
325            this.canvas.addEventListener('mousemove', canvas_onmousemove_func, false);
326            RGraph.AddEventListener(this.id, 'mousemove', canvas_onmousemove_func);
327        }
328       
329        /**
330        * If the canvas is annotatable, do install the event handlers
331        */
332        if (this.Get('chart.annotatable')) {
333            RGraph.Annotate(this);
334        }
335       
336        /**
337        * This bit shows the mini zoom window if requested
338        */
339        if (this.Get('chart.zoom.mode') == 'thumbnail' || this.Get('chart.zoom.mode') == 'area') {
340            RGraph.ShowZoomWindow(this);
341        }
342
343       
344        /**
345        * This function enables resizing
346        */
347        if (this.Get('chart.resizable')) {
348            RGraph.AllowResizing(this);
349        }
350
351       
352        /**
353        * This function enables adjusting
354        */
355        if (this.Get('chart.adjustable')) {
356            RGraph.AllowAdjusting(this);
357        }
358       
359        /**
360        * Fire the RGraph ondraw event
361        */
362        RGraph.FireCustomEvent(this, 'ondraw');
363    }
364
365    /**
366    * This method draws the rose charts background
367    */
368    RGraph.Rose.prototype.DrawBackground = function ()
369    {
370        this.context.lineWidth = 1;
371   
372        // Draw the background grey circles
373        this.context.strokeStyle = '#ccc';
374        for (var i=15; i<this.radius - (RGraph.isIE8() ? 5 : 0); i+=15) {// Radius must be greater than 0 for Opera to work
375            //this.context.moveTo(this.centerx + i, this.centery);
376   
377            // Radius must be greater than 0 for Opera to work
378            this.context.arc(this.centerx, this.centery, i, 0, (2 * Math.PI), 0);
379        }
380        this.context.stroke();
381
382        // Draw the background lines that go from the center outwards
383        this.context.beginPath();
384        for (var i=15; i<360; i+=15) {
385       
386            // Radius must be greater than 0 for Opera to work
387            this.context.arc(this.centerx, this.centery, this.radius, i / 57.3, (i + 0.1) / 57.3, 0); // The 0.1 avoids a bug in Chrome 6
388       
389            this.context.lineTo(this.centerx, this.centery);
390        }
391        this.context.stroke();
392       
393        this.context.beginPath();
394        this.context.strokeStyle = 'black';
395   
396        // Draw the X axis
397        this.context.moveTo(this.centerx - this.radius, this.centery);
398        this.context.lineTo(this.centerx + this.radius, this.centery);
399   
400        // Draw the X ends
401        this.context.moveTo(this.centerx - this.radius, this.centery - 5);
402        this.context.lineTo(this.centerx - this.radius, this.centery + 5);
403        this.context.moveTo(this.centerx + this.radius, this.centery - 5);
404        this.context.lineTo(this.centerx + this.radius, this.centery + 5);
405       
406        // Draw the X check marks
407        for (var i=(this.centerx - this.radius); i<(this.centerx + this.radius); i+=20) {
408            this.context.moveTo(i,  this.centery - 3);
409            this.context.lineTo(i,  this.centery + 3);
410        }
411       
412        // Draw the Y check marks
413        for (var i=(this.centery - this.radius); i<(this.centery + this.radius); i+=20) {
414            this.context.moveTo(this.centerx - 3, i);
415            this.context.lineTo(this.centerx + 3, i);
416        }
417   
418        // Draw the Y axis
419        this.context.moveTo(this.centerx, this.centery - this.radius);
420        this.context.lineTo(this.centerx, this.centery + this.radius);
421   
422        // Draw the Y ends
423        this.context.moveTo(this.centerx - 5, this.centery - this.radius);
424        this.context.lineTo(this.centerx + 5, this.centery - this.radius);
425   
426        this.context.moveTo(this.centerx - 5, this.centery + this.radius);
427        this.context.lineTo(this.centerx + 5, this.centery + this.radius);
428       
429        // Stroke it
430        this.context.closePath();
431        this.context.stroke();
432    }
433
434
435    /**
436    * This method draws the data on the graph
437    */
438    RGraph.Rose.prototype.DrawRose = function ()
439    {
440        var max  = 0;
441        var data = this.data;
442
443        // Must be at least two data points
444        if (data.length < 2) {
445            alert('[ROSE] Must be at least two data points! [' + data + ']');
446            return;
447        }
448   
449        // Work out the maximum value and the sum
450        if (!this.Get('chart.ymax')) {
451            // Work out the max
452            for (var i=0; i<data.length; ++i) {
453                if (typeof(data[i]) == 'number') {
454                    max = Math.max(max, data[i]);
455                } else if (typeof(data[i]) == 'object' && this.Get('chart.variant') == 'non-equi-angular') {
456                    max = Math.max(max, data[i][0]);
457               
458                // Fallback is stacked
459                } else {
460                    max = Math.max(max, RGraph.array_sum(data[i]));
461                }
462            }
463
464            this.scale = RGraph.getScale(max, this);
465            this.max = this.scale[4];
466        } else {
467            var ymax = this.Get('chart.ymax');
468            var ymin = this.Get('chart.ymin');
469
470            this.scale = [
471                          ((ymax - ymin) * 0.2) + ymin,
472                          ((ymax - ymin) * 0.4) + ymin,
473                          ((ymax - ymin) * 0.6) + ymin,
474                          ((ymax - ymin) * 0.8) + ymin,
475                          ((ymax - ymin) * 1.0) + ymin
476                         ];
477            this.max = this.scale[4];
478        }
479       
480        this.sum = RGraph.array_sum(data);
481       
482        // Move to the centre
483        this.context.moveTo(this.centerx, this.centery);
484   
485        this.context.stroke(); // Stroke the background so it stays grey
486   
487        // Transparency
488        if (this.Get('chart.colors.alpha')) {
489            this.context.globalAlpha = this.Get('chart.colors.alpha');
490        }
491
492        /*******************************************************
493        * A non-equi-angular Rose chart
494        *******************************************************/
495        if (typeof(this.Get('chart.variant')) == 'string' && this.Get('chart.variant') == 'non-equi-angular') {
496            /*******************************************************
497            * NON-EQUI-ANGULAR GOES HERE
498            *******************************************************/
499            var total=0;
500            for (var i=0; i<data.length; ++i) {
501                total += data[i][1];
502            }
503           
504           
505            for (var i=0; i<this.data.length; ++i) {
506           
507                var segmentRadians = (this.data[i][1] / total) * (2 * Math.PI);
508                var radius         = ((this.data[i][0] - this.Get('chart.ymin')) / (this.max - this.Get('chart.ymin'))) * (this.radius - 10);
509               
510                this.context.strokeStyle = this.Get('chart.strokestyle');
511                this.context.fillStyle = this.Get('chart.colors')[0];
512               
513                if (this.Get('chart.colors.sequential')) {
514                    this.context.fillStyle = this.Get('chart.colors')[i];
515                }
516           
517                this.context.beginPath(); // Begin the segment
518                    this.context.arc(this.centerx, this.centery, radius, this.startRadians - (Math.PI / 2), this.startRadians + segmentRadians - (Math.PI / 2), 0);
519                    this.context.lineTo(this.centerx, this.centery);
520                this.context.closePath(); // End the segment
521               
522                this.context.stroke();
523                this.context.fill();
524               
525                // Store the start and end angles
526                this.angles.push([
527                                  ((this.startRadians - (Math.PI / 2)) * 57.3) + 90,
528                                  (((this.startRadians + segmentRadians) - (Math.PI / 2)) * 57.3) + 90,
529                                  0,
530                                  radius
531                                 ]);
532
533                this.startRadians += segmentRadians;
534            }
535        } else {
536            /*******************************************************
537            * Draw the segments
538            *******************************************************/
539            for (var i=0; i<this.data.length; ++i) {
540   
541                this.context.strokeStyle = this.Get('chart.strokestyle');
542                this.context.fillStyle = this.Get('chart.colors')[0];
543               
544                /*******************************************************
545                * This allows sequential colors
546                *******************************************************/
547                if (this.Get('chart.colors.sequential')) {
548                    this.context.fillStyle = this.Get('chart.colors')[i];
549                }
550       
551                var segmentRadians = (1 / this.data.length) * (2 * Math.PI);
552   
553                if (typeof(this.data[i]) == 'number') {
554                    this.context.beginPath(); // Begin the segment
555                        var radius = ((this.data[i] - this.Get('chart.ymin')) / (this.max - this.Get('chart.ymin'))) * (this.radius - 10);
556       
557                        this.context.arc(this.centerx, this.centery, radius, this.startRadians - (Math.PI / 2), this.startRadians + segmentRadians - (Math.PI / 2), 0);
558                        this.context.lineTo(this.centerx, this.centery);
559                    this.context.closePath(); // End the segment
560                    this.context.stroke();
561                    this.context.fill();
562                   
563                    // Store the start and end angles
564                    this.angles.push([
565                                      ((this.startRadians - (Math.PI / 2)) * 57.3) + 90,
566                                      (((this.startRadians + segmentRadians) - (Math.PI / 2)) * 57.3) + 90,
567                                      0,
568                                      radius
569                                     ]);
570                /*******************************************************
571                * Draw a stacked segment
572                *******************************************************/
573                } else if (typeof(this.data[i]) == 'object') {
574
575                    for (var j=0; j<this.data[i].length; ++j) {
576   
577                        this.context.fillStyle = this.Get('chart.colors')[j];
578                        if (j == 0) {
579                            this.context.beginPath(); // Begin the segment
580                                var startRadius = 0;
581                                var endRadius = ((this.data[i][j] - this.Get('chart.ymin')) / (this.max - this.Get('chart.ymin'))) * (this.radius - 10);
582                   
583                                this.context.arc(this.centerx,
584                                                 this.centery,
585                                                 endRadius,
586                                                 this.startRadians - (Math.PI / 2),
587                                                 this.startRadians + segmentRadians - (Math.PI / 2),
588                                                 0);
589                                this.context.lineTo(this.centerx, this.centery);
590                            this.context.closePath(); // End the segment
591                            this.context.stroke();
592                            this.context.fill();
593   
594                            this.angles.push([
595                                              ((this.startRadians - (Math.PI / 2)) * 57.3) + 90,
596                                              (((this.startRadians + segmentRadians) - (Math.PI / 2)) * 57.3) + 90,
597                                              0,
598                                              endRadius
599                                             ]);
600                       
601                        } else {
602               
603                            this.context.beginPath(); // Begin the segment
604                                var startRadius = endRadius; // This comes from the prior iteration of this loop
605                                var endRadius = (((this.data[i][j] - this.Get('chart.ymin')) / (this.max - this.Get('chart.ymin'))) * (this.radius - 10)) + startRadius;
606               
607                                this.context.arc(this.centerx,
608                                                 this.centery,
609                                                 startRadius,
610                                                 this.startRadians - (Math.PI / 2),
611                                                 this.startRadians + segmentRadians - (Math.PI / 2),
612                                                 0);
613               
614                                this.context.arc(this.centerx,
615                                                 this.centery,
616                                                 endRadius,
617                                                 this.startRadians + segmentRadians - (Math.PI / 2),
618                                                 this.startRadians - (Math.PI / 2),
619                                                 true);
620               
621                            this.context.closePath(); // End the segment
622                            this.context.stroke();
623                            this.context.fill();
624   
625                            this.angles.push([
626                                              ((this.startRadians - (Math.PI / 2)) * 57.3) + 90,
627                                              ((this.startRadians + segmentRadians - (Math.PI / 2)) * 57.3) + 90,
628                                              startRadius,
629                                              endRadius
630                                             ]);
631                        }
632                    }
633                }
634   
635                this.startRadians += segmentRadians;
636            }
637        }
638
639        // Turn off the transparency
640        if (this.Get('chart.colors.alpha')) {
641            this.context.globalAlpha = 1;
642        }
643
644        // Draw the title if any has been set
645        if (this.Get('chart.title')) {
646            RGraph.DrawTitle(this.canvas,
647                             this.Get('chart.title'),
648                             (this.canvas.height / 2) - this.radius,
649                             this.centerx,
650                             this.Get('chart.text.size') + 2);
651        }
652    }
653
654
655    /**
656    * Unsuprisingly, draws the labels
657    */
658    RGraph.Rose.prototype.DrawLabels = function ()
659    {
660        this.context.lineWidth = 1;
661        var key = this.Get('chart.key');
662
663        if (key && key.length) {
664            RGraph.DrawKey(this, key, this.Get('chart.colors'));
665        }
666       
667        // Set the color to black
668        this.context.fillStyle = 'black';
669        this.context.strokeStyle = 'black';
670       
671        var r         = this.radius - 10;
672        var font_face = this.Get('chart.text.font');
673        var font_size = this.Get('chart.text.size');
674        var context   = this.context;
675        var axes      = this.Get('chart.labels.axes').toLowerCase();
676
677        // Draw any labels
678
679        if (typeof(this.Get('chart.labels')) == 'object' && this.Get('chart.labels')) {
680            this.DrawCircularLabels(context, this.Get('chart.labels'), font_face, font_size, r + 10);
681        }
682
683
684        var color = 'rgba(255,255,255,0.8)';
685
686        // The "North" axis labels
687        if (axes.indexOf('n') > -1) {
688            RGraph.Text(context, font_face, font_size, this.centerx, this.centery - (r * 0.2), String(Number(this.scale[0]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
689            RGraph.Text(context, font_face, font_size, this.centerx, this.centery - (r * 0.4), String(Number(this.scale[1]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
690            RGraph.Text(context, font_face, font_size, this.centerx, this.centery - (r * 0.6), String(Number(this.scale[2]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
691            RGraph.Text(context, font_face, font_size, this.centerx, this.centery - (r * 0.8), String(Number(this.scale[3]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
692            RGraph.Text(context, font_face, font_size, this.centerx, this.centery - r, String(Number(this.scale[4]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
693        }
694
695        // The "South" axis labels
696        if (axes.indexOf('s') > -1) {
697            RGraph.Text(context, font_face, font_size, this.centerx, this.centery + (r * 0.2), String(Number(this.scale[0]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
698            RGraph.Text(context, font_face, font_size, this.centerx, this.centery + (r * 0.4), String(Number(this.scale[1]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
699            RGraph.Text(context, font_face, font_size, this.centerx, this.centery + (r * 0.6), String(Number(this.scale[2]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
700            RGraph.Text(context, font_face, font_size, this.centerx, this.centery + (r * 0.8), String(Number(this.scale[3]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
701            RGraph.Text(context, font_face, font_size, this.centerx, this.centery + r, String(Number(this.scale[4]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
702        }
703       
704        // The "East" axis labels
705        if (axes.indexOf('e') > -1) {
706            RGraph.Text(context, font_face, font_size, this.centerx + (r * 0.2), this.centery, String(Number(this.scale[0]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
707            RGraph.Text(context, font_face, font_size, this.centerx + (r * 0.4), this.centery, String(Number(this.scale[1]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
708            RGraph.Text(context, font_face, font_size, this.centerx + (r * 0.6), this.centery, String(Number(this.scale[2]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
709            RGraph.Text(context, font_face, font_size, this.centerx + (r * 0.8), this.centery, String(Number(this.scale[3]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
710            RGraph.Text(context, font_face, font_size, this.centerx + r, this.centery, String(Number(this.scale[4]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
711        }
712
713        // The "West" axis labels
714        if (axes.indexOf('w') > -1) {
715            RGraph.Text(context, font_face, font_size, this.centerx - (r * 0.2), this.centery, String(Number(this.scale[0]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
716            RGraph.Text(context, font_face, font_size, this.centerx - (r * 0.4), this.centery, String(Number(this.scale[1]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
717            RGraph.Text(context, font_face, font_size, this.centerx - (r * 0.6), this.centery, String(Number(this.scale[2]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
718            RGraph.Text(context, font_face, font_size, this.centerx - (r * 0.8), this.centery, String(Number(this.scale[3]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
719            RGraph.Text(context, font_face, font_size, this.centerx - r, this.centery, String(Number(this.scale[4]).toFixed(this.Get('chart.scale.decimals'))), 'center', 'center', true, false, color);
720        }
721
722        RGraph.Text(context, font_face, font_size, this.centerx,  this.centery, typeof(this.Get('chart.ymin')) == 'number' ? String(Number(this.Get('chart.ymin')).toFixed(this.Get('chart.scale.decimals'))) : '0', 'center', 'center', true, false, color);
723    }
724
725
726    /**
727    * Draws the circular labels that go around the charts
728    *
729    * @param labels array The labels that go around the chart
730    */
731    RGraph.Rose.prototype.DrawCircularLabels = function (context, labels, font_face, font_size, r)
732    {
733        var variant = this.Get('chart.variant');
734        var position = this.Get('chart.labels.position');
735        var r        = r + 10 + this.Get('chart.labels.offset');
736
737        for (var i=0; i<labels.length; ++i) {
738           
739            if (typeof(variant) == 'string' && variant == 'non-equi-angular') {
740
741                var a = Number(this.angles[i][0]) + ((this.angles[i][1] - this.angles[i][0]) / 2);
742                    a -= 90;
743                var halign = 'center'; // Default halign
744
745                var x = Math.cos(a / 57.29577866666) * (r + 10);
746                var y = Math.sin(a / 57.29577866666) * (r + 10);
747               
748                RGraph.Text(context, font_face, font_size, this.centerx + x, this.centery + y, String(labels[i]), 'center', halign);
749               
750            } else {
751
752                var a = (360 / labels.length) * (i + 1) - (360 / (labels.length * 2));
753                var a = a - 90 + (this.Get('chart.labels.position') == 'edge' ? ((360 / labels.length) / 2) : 0);
754                var halign = 'center'; // Default halign
755   
756                // Horizontal alignment
757                //if (a == 0) {
758                //    var halign = 'left';
759                //} else if (a == 180) {
760                //    var halign = 'right';
761                //}
762   
763                var x = Math.cos(a / 57.29577866666) * (r + 10);
764                var y = Math.sin(a / 57.29577866666) * (r + 10);
765   
766                RGraph.Text(context, font_face, font_size, this.centerx + x, this.centery + y, String(labels[i]), 'center', halign);
767            }
768        }
769    }
770
771
772    /**
773    * This function is for use with circular graph types, eg the Pie or Rose. Pass it your event object
774    * and it will pass you back the corresponding segment details as an array:
775    *
776    * [x, y, r, startAngle, endAngle]
777    *
778    * Angles are measured in degrees, and are measured from the "east" axis (just like the canvas).
779    *
780    * @param object e   Your event object
781    */
782    RGraph.Rose.prototype.getSegment = function (e)
783    {
784        RGraph.FixEventObject(e);
785
786        // The optional arg provides a way of allowing some accuracy (pixels)
787        var accuracy = arguments[1] ? arguments[1] : 0;
788
789        var obj         = e.target.__object__;
790        var canvas      = obj.canvas;
791        var context     = obj.context;
792        var mouseCoords = RGraph.getMouseXY(e);
793        var x           = mouseCoords[0] - obj.centerx;
794        var y           = mouseCoords[1] - obj.centery;
795        var r           = obj.radius;
796        var theta       = Math.atan(y / x); // RADIANS
797        var hyp         = y / Math.sin(theta);
798        var angles      = obj.angles;
799        var ret         = [];
800        var hyp         = (hyp < 0) ? hyp + accuracy : hyp - accuracy;
801
802
803
804        // Put theta in DEGREES
805        theta *= 57.3
806
807        // hyp should not be greater than radius if it's a Rose chart
808        if (obj.type == 'rose') {
809            if (   (isNaN(hyp) && Math.abs(mouseCoords[0]) < (obj.centerx - r) )
810                || (isNaN(hyp) && Math.abs(mouseCoords[0]) > (obj.centerx + r))
811                || (!isNaN(hyp) && Math.abs(hyp) > r)) {
812                return;
813            }
814        }
815
816        /**
817        * Account for the correct quadrant
818        */
819        if (x < 0 && y >= 0) {
820            theta += 180;
821        } else if (x < 0 && y < 0) {
822            theta += 180;
823        } else if (x > 0 && y < 0) {
824            theta += 360;
825        }
826
827        /**
828        * Account for the rose chart angle displacement
829        */
830        theta += 90;
831
832        if (theta > 360) {
833            theta -= 360;
834        }
835
836        hyp = Math.abs(hyp);
837
838        for (var i=0; i<angles.length; ++i) {
839            if (theta >= angles[i][0] && theta < angles[i][1] && hyp > angles[i][2] && hyp < angles[i][3]) {
840
841                if (!(hyp > angles[i][2] && hyp < angles[i][3])) {
842                    return null;
843                }
844
845                if (!hyp) {
846                    return null;
847                }
848
849                ret[0] = obj.centerx;
850                ret[1] = obj.centery;
851                ret[2] = angles[i][2]; // Start angle
852                ret[3] = angles[i][3]; // End angle
853
854                ret[4] = angles[i][0]; // Start radius
855                ret[5] = angles[i][1]; // End radius
856                ret[6] = i;
857
858                ret[4] -= 90;
859                ret[5] -= 90;
860           
861                if (x > 0 && y < 0) {
862                    ret[4] += 360;
863                    ret[5] += 360;
864                }
865               
866                if (ret[4] < 0) ret[4] += 360;
867                if (ret[5] > 360) ret[5] -= 360;
868
869                return ret;
870            }
871        }
872       
873        return null;
874    }
Note: See TracBrowser for help on using the repository browser.