|
1 YUI.add('series-bar-stacked', function (Y, NAME) { |
|
2 |
|
3 /** |
|
4 * Provides functionality for creating a stacked bar series. |
|
5 * |
|
6 * @module charts |
|
7 * @submodule series-bar-stacked |
|
8 */ |
|
9 var Y_Lang = Y.Lang; |
|
10 |
|
11 /** |
|
12 * The StackedBarSeries renders bar chart in which series are stacked horizontally to show |
|
13 * their contribution to the cumulative total. |
|
14 * |
|
15 * @class StackedBarSeries |
|
16 * @extends BarSeries |
|
17 * @uses StackingUtil |
|
18 * @constructor |
|
19 * @param {Object} config (optional) Configuration parameters. |
|
20 * @submodule series-bar-stacked |
|
21 */ |
|
22 Y.StackedBarSeries = Y.Base.create("stackedBarSeries", Y.BarSeries, [Y.StackingUtil], { |
|
23 /** |
|
24 * @protected |
|
25 * |
|
26 * Draws the series. |
|
27 * |
|
28 * @method drawSeries |
|
29 */ |
|
30 drawSeries: function() |
|
31 { |
|
32 if(this.get("xcoords").length < 1) |
|
33 { |
|
34 return; |
|
35 } |
|
36 |
|
37 var isNumber = Y_Lang.isNumber, |
|
38 style = this._copyObject(this.get("styles").marker), |
|
39 w = style.width, |
|
40 h = style.height, |
|
41 xcoords = this.get("xcoords"), |
|
42 ycoords = this.get("ycoords"), |
|
43 i = 0, |
|
44 len = xcoords.length, |
|
45 top = ycoords[0], |
|
46 seriesCollection = this.get("seriesTypeCollection"), |
|
47 ratio, |
|
48 order = this.get("order"), |
|
49 graphOrder = this.get("graphOrder"), |
|
50 left, |
|
51 marker, |
|
52 lastCollection, |
|
53 negativeBaseValues, |
|
54 positiveBaseValues, |
|
55 fillColors, |
|
56 borderColors, |
|
57 useOrigin = order === 0, |
|
58 totalHeight = len * h, |
|
59 dimensions = { |
|
60 width: [], |
|
61 height: [] |
|
62 }, |
|
63 xvalues = [], |
|
64 yvalues = [], |
|
65 groupMarkers = this.get("groupMarkers"); |
|
66 if(Y_Lang.isArray(style.fill.color)) |
|
67 { |
|
68 fillColors = style.fill.color.concat(); |
|
69 } |
|
70 if(Y_Lang.isArray(style.border.color)) |
|
71 { |
|
72 borderColors = style.border.color.concat(); |
|
73 } |
|
74 this._createMarkerCache(); |
|
75 if(totalHeight > this.get("height")) |
|
76 { |
|
77 ratio = this.get("height")/totalHeight; |
|
78 h *= ratio; |
|
79 h = Math.max(h, 1); |
|
80 } |
|
81 if(!useOrigin) |
|
82 { |
|
83 lastCollection = seriesCollection[order - 1]; |
|
84 negativeBaseValues = lastCollection.get("negativeBaseValues"); |
|
85 positiveBaseValues = lastCollection.get("positiveBaseValues"); |
|
86 if(!negativeBaseValues || !positiveBaseValues) |
|
87 { |
|
88 useOrigin = true; |
|
89 positiveBaseValues = []; |
|
90 negativeBaseValues = []; |
|
91 } |
|
92 } |
|
93 else |
|
94 { |
|
95 negativeBaseValues = []; |
|
96 positiveBaseValues = []; |
|
97 } |
|
98 this.set("negativeBaseValues", negativeBaseValues); |
|
99 this.set("positiveBaseValues", positiveBaseValues); |
|
100 for(i = 0; i < len; ++i) |
|
101 { |
|
102 top = ycoords[i]; |
|
103 left = xcoords[i]; |
|
104 if(!isNumber(top) || !isNumber(left)) |
|
105 { |
|
106 if(useOrigin) |
|
107 { |
|
108 positiveBaseValues[i] = this._leftOrigin; |
|
109 negativeBaseValues[i] = this._leftOrigin; |
|
110 } |
|
111 this._markers.push(null); |
|
112 continue; |
|
113 } |
|
114 if(useOrigin) |
|
115 { |
|
116 w = Math.abs(left - this._leftOrigin); |
|
117 if(left > this._leftOrigin) |
|
118 { |
|
119 positiveBaseValues[i] = left; |
|
120 negativeBaseValues[i] = this._leftOrigin; |
|
121 left -= w; |
|
122 } |
|
123 else if(left < this._leftOrigin) |
|
124 { |
|
125 positiveBaseValues[i] = this._leftOrigin; |
|
126 negativeBaseValues[i] = left; |
|
127 } |
|
128 else |
|
129 { |
|
130 positiveBaseValues[i] = left; |
|
131 negativeBaseValues[i] = this._leftOrigin; |
|
132 } |
|
133 } |
|
134 else |
|
135 { |
|
136 if(left < this._leftOrigin) |
|
137 { |
|
138 left = negativeBaseValues[i] - (this._leftOrigin - xcoords[i]); |
|
139 w = negativeBaseValues[i] - left; |
|
140 negativeBaseValues[i] = left; |
|
141 } |
|
142 else if(left >= this._leftOrigin) |
|
143 { |
|
144 left += (positiveBaseValues[i] - this._leftOrigin); |
|
145 w = left - positiveBaseValues[i]; |
|
146 positiveBaseValues[i] = left; |
|
147 left -= w; |
|
148 } |
|
149 } |
|
150 if(!isNaN(w) && w > 0) |
|
151 { |
|
152 top -= h/2; |
|
153 if(groupMarkers) |
|
154 { |
|
155 dimensions.width[i] = w; |
|
156 dimensions.height[i] = h; |
|
157 xvalues.push(left); |
|
158 yvalues.push(top); |
|
159 } |
|
160 else |
|
161 { |
|
162 style.width = w; |
|
163 style.height = h; |
|
164 style.x = left; |
|
165 style.y = top; |
|
166 if(fillColors) |
|
167 { |
|
168 style.fill.color = fillColors[i % fillColors.length]; |
|
169 } |
|
170 if(borderColors) |
|
171 { |
|
172 style.border.color = borderColors[i % borderColors.length]; |
|
173 } |
|
174 marker = this.getMarker(style, graphOrder, i); |
|
175 } |
|
176 } |
|
177 else if(!groupMarkers) |
|
178 { |
|
179 this._markers.push(null); |
|
180 } |
|
181 } |
|
182 if(groupMarkers) |
|
183 { |
|
184 this._createGroupMarker({ |
|
185 fill: style.fill, |
|
186 border: style.border, |
|
187 dimensions: dimensions, |
|
188 xvalues: xvalues, |
|
189 yvalues: yvalues, |
|
190 shape: style.shape |
|
191 }); |
|
192 } |
|
193 else |
|
194 { |
|
195 this._clearMarkerCache(); |
|
196 } |
|
197 }, |
|
198 |
|
199 /** |
|
200 * @protected |
|
201 * |
|
202 * Resizes and positions markers based on a mouse interaction. |
|
203 * |
|
204 * @method updateMarkerState |
|
205 * @param {String} type state of the marker |
|
206 * @param {Number} i index of the marker |
|
207 */ |
|
208 updateMarkerState: function(type, i) |
|
209 { |
|
210 if(this._markers[i]) |
|
211 { |
|
212 var state = this._getState(type), |
|
213 ycoords = this.get("ycoords"), |
|
214 marker = this._markers[i], |
|
215 styles = this.get("styles").marker, |
|
216 h = styles.height, |
|
217 markerStyles = state === "off" || !styles[state] ? this._copyObject(styles) : this._copyObject(styles[state]), |
|
218 fillColor, |
|
219 borderColor; |
|
220 markerStyles.y = (ycoords[i] - h/2); |
|
221 markerStyles.x = marker.get("x"); |
|
222 markerStyles.width = marker.get("width"); |
|
223 markerStyles.id = marker.get("id"); |
|
224 fillColor = markerStyles.fill.color; |
|
225 borderColor = markerStyles.border.color; |
|
226 if(Y_Lang.isArray(fillColor)) |
|
227 { |
|
228 markerStyles.fill.color = fillColor[i % fillColor.length]; |
|
229 } |
|
230 else |
|
231 { |
|
232 markerStyles.fill.color = this._getItemColor(markerStyles.fill.color, i); |
|
233 } |
|
234 if(Y_Lang.isArray(borderColor)) |
|
235 { |
|
236 markerStyles.border.color = borderColor[i % borderColor.length]; |
|
237 } |
|
238 else |
|
239 { |
|
240 markerStyles.border.color = this._getItemColor(markerStyles.border.color, i); |
|
241 } |
|
242 marker.set(markerStyles); |
|
243 } |
|
244 }, |
|
245 |
|
246 /** |
|
247 * @protected |
|
248 * |
|
249 * Returns default values for the `styles` attribute. |
|
250 * |
|
251 * @method _getPlotDefaults |
|
252 * @return Object |
|
253 */ |
|
254 _getPlotDefaults: function() |
|
255 { |
|
256 var defs = { |
|
257 fill:{ |
|
258 type: "solid", |
|
259 alpha: 1, |
|
260 colors:null, |
|
261 alphas: null, |
|
262 ratios: null |
|
263 }, |
|
264 border:{ |
|
265 weight: 0, |
|
266 alpha: 1 |
|
267 }, |
|
268 width: 24, |
|
269 height: 24, |
|
270 shape: "rect", |
|
271 |
|
272 padding:{ |
|
273 top: 0, |
|
274 left: 0, |
|
275 right: 0, |
|
276 bottom: 0 |
|
277 } |
|
278 }; |
|
279 defs.fill.color = this._getDefaultColor(this.get("graphOrder"), "fill"); |
|
280 defs.border.color = this._getDefaultColor(this.get("graphOrder"), "border"); |
|
281 return defs; |
|
282 } |
|
283 }, { |
|
284 ATTRS: { |
|
285 /** |
|
286 * Read-only attribute indicating the type of series. |
|
287 * |
|
288 * @attribute type |
|
289 * @type String |
|
290 * @default stackedBar |
|
291 */ |
|
292 type: { |
|
293 value: "stackedBar" |
|
294 }, |
|
295 |
|
296 /** |
|
297 * Direction of the series |
|
298 * |
|
299 * @attribute direction |
|
300 * @type String |
|
301 * @default vertical |
|
302 */ |
|
303 direction: { |
|
304 value: "vertical" |
|
305 }, |
|
306 |
|
307 /** |
|
308 * @private |
|
309 * |
|
310 * @attribute negativeBaseValues |
|
311 * @type Array |
|
312 * @default null |
|
313 */ |
|
314 negativeBaseValues: { |
|
315 value: null |
|
316 }, |
|
317 |
|
318 /** |
|
319 * @private |
|
320 * |
|
321 * @attribute positiveBaseValues |
|
322 * @type Array |
|
323 * @default null |
|
324 */ |
|
325 positiveBaseValues: { |
|
326 value: null |
|
327 } |
|
328 |
|
329 /** |
|
330 * Style properties used for drawing markers. This attribute is inherited from `BarSeries`. Below are the default values: |
|
331 * <dl> |
|
332 * <dt>fill</dt><dd>A hash containing the following values: |
|
333 * <dl> |
|
334 * <dt>color</dt><dd>Color of the fill. The default value is determined by the order of the series on the graph. The color |
|
335 * will be retrieved from the below array:<br/> |
|
336 * `["#66007f", "#a86f41", "#295454", "#996ab2", "#e8cdb7", "#90bdbd","#000000","#c3b8ca", "#968373", "#678585"]` |
|
337 * </dd> |
|
338 * <dt>alpha</dt><dd>Number from 0 to 1 indicating the opacity of the marker fill. The default value is 1.</dd> |
|
339 * </dl> |
|
340 * </dd> |
|
341 * <dt>border</dt><dd>A hash containing the following values: |
|
342 * <dl> |
|
343 * <dt>color</dt><dd>Color of the border. The default value is determined by the order of the series on the graph. The color |
|
344 * will be retrieved from the below array:<br/> |
|
345 * `["#205096", "#b38206", "#000000", "#94001e", "#9d6fa0", "#e55b00", "#5e85c9", "#adab9e", "#6ac291", "#006457"]` |
|
346 * <dt>alpha</dt><dd>Number from 0 to 1 indicating the opacity of the marker border. The default value is 1.</dd> |
|
347 * <dt>weight</dt><dd>Number indicating the width of the border. The default value is 1.</dd> |
|
348 * </dl> |
|
349 * </dd> |
|
350 * <dt>height</dt><dd>indicates the width of the marker. The default value is 24.</dd> |
|
351 * <dt>over</dt><dd>hash containing styles for markers when highlighted by a `mouseover` event. The default |
|
352 * values for each style is null. When an over style is not set, the non-over value will be used. For example, |
|
353 * the default value for `marker.over.fill.color` is equivalent to `marker.fill.color`.</dd> |
|
354 * </dl> |
|
355 * |
|
356 * @attribute styles |
|
357 * @type Object |
|
358 */ |
|
359 } |
|
360 }); |
|
361 |
|
362 |
|
363 |
|
364 }, '@VERSION@', {"requires": ["series-stacked", "series-bar"]}); |