]> git.pond.sub.org Git - eow/blob - static/dojo-release-1.1.1/dojox/charting/plot2d/Pie.js
add Dojo 1.1.1
[eow] / static / dojo-release-1.1.1 / dojox / charting / plot2d / Pie.js
1 if(!dojo._hasResource["dojox.charting.plot2d.Pie"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2 dojo._hasResource["dojox.charting.plot2d.Pie"] = true;
3 dojo.provide("dojox.charting.plot2d.Pie");
4
5 dojo.require("dojox.charting.Element");
6 dojo.require("dojox.charting.axis2d.common");
7 dojo.require("dojox.charting.plot2d.common");
8
9 dojo.require("dojox.lang.functional");
10 dojo.require("dojox.gfx");
11
12 (function(){
13         var df = dojox.lang.functional, du = dojox.lang.utils,
14                 dc = dojox.charting.plot2d.common,
15                 da = dojox.charting.axis2d.common,
16                 g = dojox.gfx;
17
18         dojo.declare("dojox.charting.plot2d.Pie", dojox.charting.Element, {
19                 defaultParams: {
20                         labels:                 true,
21                         ticks:                  false,
22                         fixed:                  true,
23                         precision:              1,
24                         labelOffset:    20,
25                         labelStyle:             "default",      // default/rows/auto
26                         htmlLabels:             true            // use HTML to draw labels
27                 },
28                 optionalParams: {
29                         font:           "",
30                         fontColor:      "",
31                         radius:         0
32                 },
33
34                 constructor: function(chart, kwArgs){
35                         this.opt = dojo.clone(this.defaultParams);
36                         du.updateWithObject(this.opt, kwArgs);
37                         du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
38                         this.run = null;
39                         this.dyn = [];
40                 },
41                 clear: function(){
42                         this.dirty = true;
43                         this.dyn = [];
44                         return this;
45                 },
46                 setAxis: function(axis){
47                         // nothing
48                         return this;
49                 },
50                 addSeries: function(run){
51                         this.run = run;
52                         return this;
53                 },
54                 calculateAxes: function(dim){
55                         // nothing
56                         return this;
57                 },
58                 getRequiredColors: function(){
59                         return this.run ? this.run.data.length : 0;
60                 },
61                 render: function(dim, offsets){
62                         if(!this.dirty){ return this; }
63                         this.dirty = false;
64                         this.cleanGroup();
65                         var s = this.group, color, t = this.chart.theme;
66
67                         // calculate the geometry
68                         var rx = (dim.width  - offsets.l - offsets.r) / 2,
69                                 ry = (dim.height - offsets.t - offsets.b) / 2,
70                                 r  = Math.min(rx, ry),
71                                 taFont = "font" in this.opt ? this.opt.font : t.axis.font,
72                                 size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
73                                 taFontColor = "fontColor" in this.opt ? this.opt.fontColor : t.axis.fontColor,
74                                 start = 0, step, sum, slices, labels, shift, labelR,
75                                 run = this.run.data;
76                         if(typeof run[0] == "number"){
77                                 sum = df.foldl1(run, "+");
78                                 slices = dojo.map(run, function(x){ return x / sum; });
79                                 if(this.opt.labels){
80                                         labels = dojo.map(slices, function(x){
81                                                 return this._getLabel(x * 100) + "%";
82                                         }, this);
83                                 }
84                         }else{
85                                 sum = df.foldl1(run, function(a, b){ return {y: a.y + b.y}; }).y;
86                                 slices = df.map(run, function(x){ return x.y / sum; });
87                                 if(this.opt.labels){
88                                         labels = dojo.map(slices, function(x, i){
89                                                 var v = run[i];
90                                                 return "text" in v ? v.text : this._getLabel(x * 100) + "%";
91                                         }, this);
92                                 }
93                         }
94                         if(this.opt.labels){
95                                 shift = df.foldl1(df.map(labels, function(label){
96                                         return dojox.gfx._base._getTextBox(label, {font: taFont}).w;
97                                 }, this), "Math.max(a, b)") / 2;
98                                 if(this.opt.labelOffset < 0){
99                                         r = Math.min(rx - 2 * shift, ry - size) + this.opt.labelOffset;
100                                 }
101                                 labelR = r - this.opt.labelOffset;
102                         }
103                         if("radius" in this.opt){
104                                 r = this.opt.radius;
105                                 labelR = r - this.opt.labelOffset;
106                         }
107                         var     circle = {
108                                         cx: offsets.l + rx,
109                                         cy: offsets.t + ry,
110                                         r:  r
111                                 };
112
113                         this.dyn = [];                  
114                         if(!this.run || !run.length){
115                                 return this;
116                         }
117                         if(run.length == 1){
118                                 // need autogenerated color
119                                 color = new dojo.Color(t.next("color"));
120                                 var shape = s.createCircle(circle).
121                                                 setFill(dc.augmentFill(t.run.fill, color)).
122                                                 setStroke(dc.augmentStroke(t.series.stroke, color));
123                                 this.dyn.push({color: color, fill: shape.getFill(), stroke: shape.getStroke()});
124                                 if(this.opt.labels){
125                                         // draw the label
126                                         var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"]
127                                                                         (this.chart, s, circle.cx, circle.cy + size / 2, "middle",
128                                                                                 "100%", taFont, taFontColor);
129                                         if(this.opt.htmlLabels){ this.htmlElements.push(elem); }
130                                 }
131                                 return this;
132                         }
133                         // draw slices
134                         dojo.forEach(slices, function(x, i){
135                                 // calculate the geometry of the slice
136                                 var end = start + x * 2 * Math.PI, v = run[i];
137                                 if(i + 1 == slices.length){
138                                         end = 2 * Math.PI;
139                                 }
140                                 var     step = end - start,
141                                         x1 = circle.cx + r * Math.cos(start),
142                                         y1 = circle.cy + r * Math.sin(start),
143                                         x2 = circle.cx + r * Math.cos(end),
144                                         y2 = circle.cy + r * Math.sin(end);
145                                 // draw the slice
146                                 var color, fill, stroke;
147                                 if(typeof v == "object"){
148                                         color  = "color"  in v ? v.color  : new dojo.Color(t.next("color"));
149                                         fill   = "fill"   in v ? v.fill   : dc.augmentFill(t.series.fill, color);
150                                         stroke = "stroke" in v ? v.stroke : dc.augmentStroke(t.series.stroke, color);
151                                 }else{
152                                         color  = new dojo.Color(t.next("color"));
153                                         fill   = dc.augmentFill(t.series.fill, color);
154                                         stroke = dc.augmentStroke(t.series.stroke, color);
155                                 }
156                                 var shape = s.createPath({}).
157                                                 moveTo(circle.cx, circle.cy).
158                                                 lineTo(x1, y1).
159                                                 arcTo(r, r, 0, step > Math.PI, true, x2, y2).
160                                                 lineTo(circle.cx, circle.cy).
161                                                 closePath().
162                                                 setFill(fill).
163                                                 setStroke(stroke);
164                                 this.dyn.push({color: color, fill: fill, stroke: stroke});
165                                 start = end;
166                         }, this);
167                         // draw labels
168                         if(this.opt.labels){
169                                 start = 0;
170                                 dojo.forEach(slices, function(slice, i){
171                                         // calculate the geometry of the slice
172                                         var end = start + slice * 2 * Math.PI, v = run[i];
173                                         if(i + 1 == slices.length){
174                                                 end = 2 * Math.PI;
175                                         }
176                                         var     labelAngle = (start + end) / 2,
177                                                 x = circle.cx + labelR * Math.cos(labelAngle),
178                                                 y = circle.cy + labelR * Math.sin(labelAngle) + size / 2;
179                                         // draw the label
180                                         var elem = da.createText[this.opt.htmlLabels && dojox.gfx.renderer != "vml" ? "html" : "gfx"]
181                                                                         (this.chart, s, x, y, "middle",
182                                                                                 labels[i], taFont, 
183                                                                                 (typeof v == "object" && "fontColor" in v) 
184                                                                                         ? v.fontColor : taFontColor);
185                                         if(this.opt.htmlLabels){ this.htmlElements.push(elem); }
186                                         start = end;
187                                 }, this);
188                         }
189                         return this;
190                 },
191                 
192                 // utilities
193                 _getLabel: function(number){
194                         return this.opt.fixed ? number.toFixed(this.opt.precision) : number.toString();
195                 }
196         });
197 })();
198
199 }