2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
8 YUI.add('series-fill-util', function (Y, NAME) {
11 * Provides functionality for drawing fills in a series.
14 * @submodule series-fill-util
19 * Utility class used for drawing area fills.
23 * @submodule series-fill-util
31 return this._defaults || this._getAreaDefaults();
36 var defaults = this._defaults || this._getAreaDefaults();
37 this._defaults = Y.merge(defaults, val);
44 * Returns a path shape used for drawing fills.
52 var path = this._path;
55 path = this.get("graphic").addShape({type:"path"});
64 * @method _toggleVisible
65 * @param {Boolean} visible indicates visibilitye
68 _toggleVisible: function(visible)
72 this._path.set("visible", visible);
80 * @param {Array} xcoords The x-coordinates for the series.
81 * @param {Array} ycoords The y-coordinates for the series.
84 drawFill: function(xcoords, ycoords)
86 if(xcoords.length < 1)
90 var isNumber = Y_Lang.isNumber,
99 noPointsRendered = true,
101 styles = this.get("styles").area,
102 path = this._getPath(),
103 color = styles.color || this._getDefaultColor(this.get("graphOrder"), "slice");
107 opacity: styles.alpha
109 path.set("stroke", {weight: 0});
110 for(; i < len; i = ++i)
114 pointValid = isNumber(nextX) && isNumber(nextY);
121 this._firstValidX = nextX;
122 this._firstValidY = nextY;
123 noPointsRendered = false;
124 path.moveTo(nextX, nextY);
128 path.lineTo(nextX, nextY);
133 this._lastValidX = lastValidX;
134 this._lastValidY = lastValidY;
139 * Draws a fill for a spline
141 * @method drawAreaSpline
144 drawAreaSpline: function()
146 if(this.get("xcoords").length < 1)
150 var xcoords = this.get("xcoords"),
151 ycoords = this.get("ycoords"),
152 curvecoords = this.getCurveControlPoints(xcoords, ycoords),
153 len = curvecoords.length,
163 styles = this.get("styles").area,
164 path = this._getPath(),
165 color = styles.color || this._getDefaultColor(this.get("graphOrder"), "slice");
168 opacity: styles.alpha
170 path.set("stroke", {weight: 0});
171 path.moveTo(firstX, firstY);
172 for(; i < len; i = ++i)
174 x = curvecoords[i].endx;
175 y = curvecoords[i].endy;
176 cx1 = curvecoords[i].ctrlx1;
177 cx2 = curvecoords[i].ctrlx2;
178 cy1 = curvecoords[i].ctrly1;
179 cy2 = curvecoords[i].ctrly2;
180 path.curveTo(cx1, cy1, cx2, cy2, x, y);
182 if(this.get("direction") === "vertical")
184 path.lineTo(this._leftOrigin, y);
185 path.lineTo(this._leftOrigin, firstY);
189 path.lineTo(x, this._bottomOrigin);
190 path.lineTo(firstX, this._bottomOrigin);
192 path.lineTo(firstX, firstY);
197 * Draws a a stacked area spline
199 * @method drawStackedAreaSpline
202 drawStackedAreaSpline: function()
204 if(this.get("xcoords").length < 1)
208 var xcoords = this.get("xcoords"),
209 ycoords = this.get("ycoords"),
211 order = this.get("order"),
212 seriesCollection = this.get("seriesTypeCollection"),
225 styles = this.get("styles").area,
226 path = this._getPath(),
227 color = styles.color || this._getDefaultColor(this.get("graphOrder"), "slice");
230 curvecoords = this.getCurveControlPoints(xcoords, ycoords);
231 len = curvecoords.length;
234 opacity: styles.alpha
236 path.set("stroke", {weight: 0});
237 path.moveTo(firstX, firstY);
238 for(; i < len; i = ++i)
240 x = curvecoords[i].endx;
241 y = curvecoords[i].endy;
242 cx1 = curvecoords[i].ctrlx1;
243 cx2 = curvecoords[i].ctrlx2;
244 cy1 = curvecoords[i].ctrly1;
245 cy2 = curvecoords[i].ctrly2;
246 path.curveTo(cx1, cy1, cx2, cy2, x, y);
250 prevXCoords = seriesCollection[order - 1].get("xcoords").concat().reverse();
251 prevYCoords = seriesCollection[order - 1].get("ycoords").concat().reverse();
252 curvecoords = this.getCurveControlPoints(prevXCoords, prevYCoords);
254 len = curvecoords.length;
255 path.lineTo(prevXCoords[0], prevYCoords[0]);
256 for(; i < len; i = ++i)
258 x = curvecoords[i].endx;
259 y = curvecoords[i].endy;
260 cx1 = curvecoords[i].ctrlx1;
261 cx2 = curvecoords[i].ctrlx2;
262 cy1 = curvecoords[i].ctrly1;
263 cy2 = curvecoords[i].ctrly2;
264 path.curveTo(cx1, cy1, cx2, cy2, x, y);
269 if(this.get("direction") === "vertical")
271 path.lineTo(this._leftOrigin, ycoords[ycoords.length-1]);
272 path.lineTo(this._leftOrigin, firstY);
276 path.lineTo(xcoords[xcoords.length-1], this._bottomOrigin);
277 path.lineTo(firstX, this._bottomOrigin);
281 path.lineTo(firstX, firstY);
286 * Storage for default area styles.
288 * @property _defaults
295 * Concatenates coordinate array with correct coordinates for closing an area fill.
297 * @method _getClosingPoints
301 _getClosingPoints: function()
303 var xcoords = this.get("xcoords").concat(),
304 ycoords = this.get("ycoords").concat(),
307 if(this.get("direction") === "vertical")
309 lastValidIndex = this._getLastValidIndex(xcoords);
310 firstValidIndex = this._getFirstValidIndex(xcoords);
311 ycoords.push(ycoords[lastValidIndex]);
312 ycoords.push(ycoords[firstValidIndex]);
313 xcoords.push(this._leftOrigin);
314 xcoords.push(this._leftOrigin);
318 lastValidIndex = this._getLastValidIndex(ycoords);
319 firstValidIndex = this._getFirstValidIndex(ycoords);
320 xcoords.push(xcoords[lastValidIndex]);
321 xcoords.push(xcoords[firstValidIndex]);
322 ycoords.push(this._bottomOrigin);
323 ycoords.push(this._bottomOrigin);
325 xcoords.push(xcoords[0]);
326 ycoords.push(ycoords[0]);
327 return [xcoords, ycoords];
331 * Returns the order of the series closest to the current series that has a valid value for the current index.
333 * @method _getHighestValidOrder
334 * @param {Array} seriesCollection Array of series of a given type.
335 * @param {Number} index Index of the series item.
336 * @param {Number} order Index of the the series in the seriesCollection
337 * @param {String} direction Indicates the direction of the series
341 _getHighestValidOrder: function(seriesCollection, index, order, direction)
343 var coords = direction === "vertical" ? "stackedXCoords" : "stackedYCoords",
345 while(isNaN(coord) && order > -1)
350 coord = seriesCollection[order].get(coords)[index];
357 * Returns an array containing the x and y coordinates for a given series and index.
359 * @method _getCoordsByOrderAndIndex
360 * @param {Array} seriesCollection Array of series of a given type.
361 * @param {Number} index Index of the series item.
362 * @param {Number} order Index of the the series in the seriesCollection
363 * @param {String} direction Indicates the direction of the series
367 _getCoordsByOrderAndIndex: function(seriesCollection, index, order, direction)
371 if(direction === "vertical")
373 xcoord = order < 0 ? this._leftOrigin : seriesCollection[order].get("stackedXCoords")[index];
374 ycoord = this.get("stackedYCoords")[index];
378 xcoord = this.get("stackedXCoords")[index];
379 ycoord = order < 0 ? this._bottomOrigin : seriesCollection[order].get("stackedYCoords")[index];
381 return [xcoord, ycoord];
385 * Concatenates coordinate array with the correct coordinates for closing an area stack.
387 * @method _getStackedClosingPoints
391 _getStackedClosingPoints: function()
393 var order = this.get("order"),
394 direction = this.get("direction"),
395 seriesCollection = this.get("seriesTypeCollection"),
398 xcoords = this.get("stackedXCoords"),
399 ycoords = this.get("stackedYCoords"),
402 previousSeriesFirstValidIndex,
403 previousSeriesLastValidIndex,
414 return this._getClosingPoints();
417 previousSeries = seriesCollection[order - 1];
418 previousXCoords = previousSeries.get("stackedXCoords").concat();
419 previousYCoords = previousSeries.get("stackedYCoords").concat();
420 if(direction === "vertical")
422 firstValidIndex = this._getFirstValidIndex(xcoords);
423 lastValidIndex = this._getLastValidIndex(xcoords);
424 previousSeriesFirstValidIndex = previousSeries._getFirstValidIndex(previousXCoords);
425 previousSeriesLastValidIndex = previousSeries._getLastValidIndex(previousXCoords);
429 firstValidIndex = this._getFirstValidIndex(ycoords);
430 lastValidIndex = this._getLastValidIndex(ycoords);
431 previousSeriesFirstValidIndex = previousSeries._getFirstValidIndex(previousYCoords);
432 previousSeriesLastValidIndex = previousSeries._getLastValidIndex(previousYCoords);
434 if(previousSeriesLastValidIndex >= firstValidIndex && previousSeriesFirstValidIndex <= lastValidIndex)
436 previousSeriesFirstValidIndex = Math.max(firstValidIndex, previousSeriesFirstValidIndex);
437 previousSeriesLastValidIndex = Math.min(lastValidIndex, previousSeriesLastValidIndex);
438 previousXCoords = previousXCoords.slice(previousSeriesFirstValidIndex, previousSeriesLastValidIndex + 1);
439 previousYCoords = previousYCoords.slice(previousSeriesFirstValidIndex, previousSeriesLastValidIndex + 1);
440 limit = previousSeriesFirstValidIndex;
444 limit = lastValidIndex;
447 closingXCoords = [xcoords[firstValidIndex]];
448 closingYCoords = [ycoords[firstValidIndex]];
449 currentIndex = firstValidIndex;
450 while((isNaN(highestValidOrder) || highestValidOrder < order - 1) && currentIndex <= limit)
452 oldOrder = highestValidOrder;
453 highestValidOrder = this._getHighestValidOrder(seriesCollection, currentIndex, order, direction);
454 if(!isNaN(oldOrder) && highestValidOrder > oldOrder)
456 coords = this._getCoordsByOrderAndIndex(seriesCollection, currentIndex, oldOrder, direction);
457 closingXCoords.push(coords[0]);
458 closingYCoords.push(coords[1]);
460 coords = this._getCoordsByOrderAndIndex(seriesCollection, currentIndex, highestValidOrder, direction);
461 closingXCoords.push(coords[0]);
462 closingYCoords.push(coords[1]);
463 currentIndex = currentIndex + 1;
465 if(previousXCoords &&
466 previousXCoords.length > 0 &&
467 previousSeriesLastValidIndex > firstValidIndex &&
468 previousSeriesFirstValidIndex < lastValidIndex)
470 closingXCoords = closingXCoords.concat(previousXCoords);
471 closingYCoords = closingYCoords.concat(previousYCoords);
472 highestValidOrder = order -1;
474 currentIndex = Math.max(firstValidIndex, previousSeriesLastValidIndex);
476 highestValidOrder = NaN;
477 while(currentIndex <= lastValidIndex)
479 oldOrder = highestValidOrder;
480 highestValidOrder = this._getHighestValidOrder(seriesCollection, currentIndex, order, direction);
483 if(highestValidOrder > oldOrder)
485 coords = this._getCoordsByOrderAndIndex(seriesCollection, currentIndex, oldOrder, direction);
486 closingXCoords.push(coords[0]);
487 closingYCoords.push(coords[1]);
489 else if(highestValidOrder < oldOrder)
491 coords = this._getCoordsByOrderAndIndex(seriesCollection, currentIndex - 1, highestValidOrder, direction);
492 closingXCoords.push(coords[0]);
493 closingYCoords.push(coords[1]);
496 coords = this._getCoordsByOrderAndIndex(seriesCollection, currentIndex, highestValidOrder, direction);
497 closingXCoords.push(coords[0]);
498 closingYCoords.push(coords[1]);
499 currentIndex = currentIndex + 1;
502 closingXCoords.reverse();
503 closingYCoords.reverse();
504 return [xcoords.concat(closingXCoords), ycoords.concat(closingYCoords)];
508 * Returns default values for area styles.
510 * @method _getAreaDefaults
514 _getAreaDefaults: function()
520 Y.augment(Fills, Y.Attribute);