Upgrade to ExtJS 4.0.2 - Released 06/09/2011
[extjs.git] / src / chart / axis / Radial.js
1 /*
2
3 This file is part of Ext JS 4
4
5 Copyright (c) 2011 Sencha Inc
6
7 Contact:  http://www.sencha.com/contact
8
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
11
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
13
14 */
15 /**
16  * @class Ext.chart.axis.Radial
17  * @extends Ext.chart.axis.Abstract
18  * @ignore
19  */
20 Ext.define('Ext.chart.axis.Radial', {
21
22     /* Begin Definitions */
23
24     extend: 'Ext.chart.axis.Abstract',
25
26     /* End Definitions */
27
28     position: 'radial',
29
30     alias: 'axis.radial',
31
32     drawAxis: function(init) {
33         var chart = this.chart,
34             surface = chart.surface,
35             bbox = chart.chartBBox,
36             store = chart.store,
37             l = store.getCount(),
38             centerX = bbox.x + (bbox.width / 2),
39             centerY = bbox.y + (bbox.height / 2),
40             rho = Math.min(bbox.width, bbox.height) /2,
41             sprites = [], sprite,
42             steps = this.steps,
43             i, j, pi2 = Math.PI * 2,
44             cos = Math.cos, sin = Math.sin;
45
46         if (this.sprites && !chart.resizing) {
47             this.drawLabel();
48             return;
49         }
50
51         if (!this.sprites) {
52             //draw circles
53             for (i = 1; i <= steps; i++) {
54                 sprite = surface.add({
55                     type: 'circle',
56                     x: centerX,
57                     y: centerY,
58                     radius: Math.max(rho * i / steps, 0),
59                     stroke: '#ccc'
60                 });
61                 sprite.setAttributes({
62                     hidden: false
63                 }, true);
64                 sprites.push(sprite);
65             }
66             //draw lines
67             store.each(function(rec, i) {
68                 sprite = surface.add({
69                     type: 'path',
70                     path: ['M', centerX, centerY, 'L', centerX + rho * cos(i / l * pi2), centerY + rho * sin(i / l * pi2), 'Z'],
71                     stroke: '#ccc'
72                 });
73                 sprite.setAttributes({
74                     hidden: false
75                 }, true);
76                 sprites.push(sprite);
77             });
78         } else {
79             sprites = this.sprites;
80             //draw circles
81             for (i = 0; i < steps; i++) {
82                 sprites[i].setAttributes({
83                     x: centerX,
84                     y: centerY,
85                     radius: Math.max(rho * (i + 1) / steps, 0),
86                     stroke: '#ccc'
87                 }, true);
88             }
89             //draw lines
90             store.each(function(rec, j) {
91                 sprites[i + j].setAttributes({
92                     path: ['M', centerX, centerY, 'L', centerX + rho * cos(j / l * pi2), centerY + rho * sin(j / l * pi2), 'Z'],
93                     stroke: '#ccc'
94                 }, true);
95             });
96         }
97         this.sprites = sprites;
98
99         this.drawLabel();
100     },
101
102     drawLabel: function() {
103         var chart = this.chart,
104             surface = chart.surface,
105             bbox = chart.chartBBox,
106             store = chart.store,
107             centerX = bbox.x + (bbox.width / 2),
108             centerY = bbox.y + (bbox.height / 2),
109             rho = Math.min(bbox.width, bbox.height) /2,
110             max = Math.max, round = Math.round,
111             labelArray = [], label,
112             fields = [], nfields,
113             categories = [], xField,
114             aggregate = !this.maximum,
115             maxValue = this.maximum || 0,
116             steps = this.steps, i = 0, j, dx, dy,
117             pi2 = Math.PI * 2,
118             cos = Math.cos, sin = Math.sin,
119             display = this.label.display,
120             draw = display !== 'none',
121             margin = 10;
122
123         if (!draw) {
124             return;
125         }
126
127         //get all rendered fields
128         chart.series.each(function(series) {
129             fields.push(series.yField);
130             xField = series.xField;
131         });
132         
133         //get maxValue to interpolate
134         store.each(function(record, i) {
135             if (aggregate) {
136                 for (i = 0, nfields = fields.length; i < nfields; i++) {
137                     maxValue = max(+record.get(fields[i]), maxValue);
138                 }
139             }
140             categories.push(record.get(xField));
141         });
142         if (!this.labelArray) {
143             if (display != 'categories') {
144                 //draw scale
145                 for (i = 1; i <= steps; i++) {
146                     label = surface.add({
147                         type: 'text',
148                         text: round(i / steps * maxValue),
149                         x: centerX,
150                         y: centerY - rho * i / steps,
151                         'text-anchor': 'middle',
152                         'stroke-width': 0.1,
153                         stroke: '#333'
154                     });
155                     label.setAttributes({
156                         hidden: false
157                     }, true);
158                     labelArray.push(label);
159                 }
160             }
161             if (display != 'scale') {
162                 //draw text
163                 for (j = 0, steps = categories.length; j < steps; j++) {
164                     dx = cos(j / steps * pi2) * (rho + margin);
165                     dy = sin(j / steps * pi2) * (rho + margin);
166                     label = surface.add({
167                         type: 'text',
168                         text: categories[j],
169                         x: centerX + dx,
170                         y: centerY + dy,
171                         'text-anchor': dx * dx <= 0.001? 'middle' : (dx < 0? 'end' : 'start')
172                     });
173                     label.setAttributes({
174                         hidden: false
175                     }, true);
176                     labelArray.push(label);
177                 }
178             }
179         }
180         else {
181             labelArray = this.labelArray;
182             if (display != 'categories') {
183                 //draw values
184                 for (i = 0; i < steps; i++) {
185                     labelArray[i].setAttributes({
186                         text: round((i + 1) / steps * maxValue),
187                         x: centerX,
188                         y: centerY - rho * (i + 1) / steps,
189                         'text-anchor': 'middle',
190                         'stroke-width': 0.1,
191                         stroke: '#333'
192                     }, true);
193                 }
194             }
195             if (display != 'scale') {
196                 //draw text
197                 for (j = 0, steps = categories.length; j < steps; j++) {
198                     dx = cos(j / steps * pi2) * (rho + margin);
199                     dy = sin(j / steps * pi2) * (rho + margin);
200                     if (labelArray[i + j]) {
201                         labelArray[i + j].setAttributes({
202                             type: 'text',
203                             text: categories[j],
204                             x: centerX + dx,
205                             y: centerY + dy,
206                             'text-anchor': dx * dx <= 0.001? 'middle' : (dx < 0? 'end' : 'start')
207                         }, true);
208                     }
209                 }
210             }
211         }
212         this.labelArray = labelArray;
213     }
214 });