Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
YUI.add('series-stacked', function (Y, NAME) {
2
 
3
/**
4
 * Provides functionality for creating stacked series.
5
 *
6
 * @module charts
7
 * @submodule series-stacked
8
 */
9
var Y_Lang = Y.Lang;
10
 
11
/**
12
 * Utility class used for creating stacked series.
13
 *
14
 * @module charts
15
 * @class StackingUtil
16
 * @constructor
17
 * @submodule series-stacked
18
 */
19
function StackingUtil(){}
20
 
21
StackingUtil.prototype = {
22
    /**
23
     * Indicates whether the series is stacked.
24
     *
25
     * @property _stacked
26
     * @private
27
     */
28
    _stacked: true,
29
 
30
    /**
31
     * @protected
32
     *
33
     * Adjusts coordinate values for stacked series.
34
     *
35
     * @method _stackCoordinates
36
     */
37
    _stackCoordinates: function()
38
    {
39
        if(this.get("direction") === "vertical")
40
        {
41
            this._stackXCoords();
42
        }
43
        else
44
        {
45
            this._stackYCoords();
46
        }
47
    },
48
 
49
    /**
50
     * Stacks coordinates for a stacked vertical series.
51
     *
52
     * @method _stackXCoords
53
     * @protected
54
     */
55
    _stackXCoords: function()
56
    {
57
        var order = this.get("order"),
58
            seriesCollection = this.get("seriesTypeCollection"),
59
            i = 0,
60
            xcoords = this.get("xcoords"),
61
            ycoords = this.get("ycoords"),
62
            len,
63
            coord,
64
            prevCoord,
65
            prevOrder,
66
            stackedXCoords = xcoords.concat(),
67
            prevXCoords,
68
            prevYCoords,
69
            nullIndices = [],
70
            nullIndex;
71
        if(order > 0)
72
        {
73
            prevXCoords = seriesCollection[order - 1].get("stackedXCoords");
74
            prevYCoords = seriesCollection[order - 1].get("stackedYCoords");
75
            len = prevXCoords.length;
76
        }
77
        else
78
        {
79
            len = xcoords.length;
80
        }
81
        for(; i < len; i = i + 1)
82
        {
83
            if(Y_Lang.isNumber(xcoords[i]))
84
            {
85
                if(order > 0)
86
                {
87
                    prevCoord = prevXCoords[i];
88
                    if(!Y_Lang.isNumber(prevCoord))
89
                    {
90
                        prevOrder = order;
91
                        while(prevOrder >  - 1 && !Y_Lang.isNumber(prevCoord))
92
                        {
93
                            prevOrder = prevOrder - 1;
94
                            if(prevOrder > -1)
95
                            {
96
                                prevCoord = seriesCollection[prevOrder].get("stackedXCoords")[i];
97
                            }
98
                            else
99
                            {
100
                                prevCoord = this._leftOrigin;
101
                            }
102
                        }
103
                    }
104
                    xcoords[i] = xcoords[i] + prevCoord;
105
                }
106
                stackedXCoords[i] = xcoords[i];
107
            }
108
            else
109
            {
110
                nullIndices.push(i);
111
            }
112
        }
113
        this._cleanXNaN(stackedXCoords, ycoords);
114
        len = nullIndices.length;
115
        if(len > 0)
116
        {
117
            for(i = 0; i < len; i = i + 1)
118
            {
119
                nullIndex = nullIndices[i];
120
                coord = order > 0 ? prevXCoords[nullIndex] : this._leftOrigin;
121
                stackedXCoords[nullIndex] =  Math.max(stackedXCoords[nullIndex], coord);
122
            }
123
        }
124
        this.set("stackedXCoords", stackedXCoords);
125
        this.set("stackedYCoords", ycoords);
126
    },
127
 
128
    /**
129
     * Stacks coordinates for a stacked horizontal series.
130
     *
131
     * @method _stackYCoords
132
     * @protected
133
     */
134
    _stackYCoords: function()
135
    {
136
        var order = this.get("order"),
137
            graphic = this.get("graphic"),
138
            h = graphic.get("height"),
139
            seriesCollection = this.get("seriesTypeCollection"),
140
            i = 0,
141
            xcoords = this.get("xcoords"),
142
            ycoords = this.get("ycoords"),
143
            len,
144
            coord,
145
            prevCoord,
146
            prevOrder,
147
            stackedYCoords = ycoords.concat(),
148
            prevXCoords,
149
            prevYCoords,
150
            nullIndices = [],
151
            nullIndex;
152
        if(order > 0)
153
        {
154
            prevXCoords = seriesCollection[order - 1].get("stackedXCoords");
155
            prevYCoords = seriesCollection[order - 1].get("stackedYCoords");
156
            len = prevYCoords.length;
157
        }
158
        else
159
        {
160
            len = ycoords.length;
161
        }
162
        for(; i < len; i = i + 1)
163
        {
164
            if(Y_Lang.isNumber(ycoords[i]))
165
            {
166
                if(order > 0)
167
                {
168
                    prevCoord = prevYCoords[i];
169
                    if(!Y_Lang.isNumber(prevCoord))
170
                    {
171
                        prevOrder = order;
172
                        while(prevOrder >  - 1 && !Y_Lang.isNumber(prevCoord))
173
                        {
174
                            prevOrder = prevOrder - 1;
175
                            if(prevOrder > -1)
176
                            {
177
                                prevCoord = seriesCollection[prevOrder].get("stackedYCoords")[i];
178
                            }
179
                            else
180
                            {
181
                                prevCoord = this._bottomOrigin;
182
                            }
183
                        }
184
                    }
185
                    ycoords[i] = prevCoord - (h - ycoords[i]);
186
                }
187
                stackedYCoords[i] = ycoords[i];
188
            }
189
            else
190
            {
191
                nullIndices.push(i);
192
            }
193
        }
194
        this._cleanYNaN(xcoords, stackedYCoords);
195
        len = nullIndices.length;
196
        if(len > 0)
197
        {
198
            for(i = 0; i < len; i = i + 1)
199
            {
200
                nullIndex = nullIndices[i];
201
                coord = order > 0 ? prevYCoords[nullIndex] : h;
202
                stackedYCoords[nullIndex] =  Math.min(stackedYCoords[nullIndex], coord);
203
            }
204
        }
205
        this.set("stackedXCoords", xcoords);
206
        this.set("stackedYCoords", stackedYCoords);
207
    },
208
 
209
    /**
210
     * Cleans invalid x-coordinates by calculating their value based on the corresponding y-coordinate, the
211
     * previous valid x-coordinate with its corresponding y-coordinate and the next valid x-coordinate with
212
     * its corresponding y-coordinate. If there is no previous or next valid x-coordinate, the value will not
213
     * be altered.
214
     *
215
     * @method _cleanXNaN
216
     * @param {Array} xcoords An array of x-coordinate values
217
     * @param {Array} ycoords An arry of y-coordinate values
218
     * @private
219
     */
220
    _cleanXNaN: function(xcoords, ycoords)
221
    {
222
        var previousValidIndex,
223
            nextValidIndex,
224
            previousValidX,
225
            previousValidY,
226
            x,
227
            y,
228
            nextValidX,
229
            nextValidY,
230
            isNumber = Y_Lang.isNumber,
231
            m,
232
            i = 0,
233
            len = ycoords.length;
234
        for(; i < len; ++i)
235
        {
236
            x = xcoords[i];
237
            y = ycoords[i];
238
            //if x is invalid, calculate where it should be
239
            if(!isNumber(x) && i > 0 && i < len - 1)
240
            {
241
                previousValidY = ycoords[i - 1];
242
                //check to see if the previous value is valid
243
                previousValidX = this._getPreviousValidCoordValue(xcoords, i);
244
                nextValidY = ycoords[i + 1];
245
                nextValidX = this._getNextValidCoordValue(xcoords, i);
246
                //check to see if the next value is valid
247
                if(isNumber(previousValidX) && isNumber(nextValidX))
248
                {
249
                    //calculate slope and solve for x
250
                    m = (nextValidY - previousValidY) / (nextValidX - previousValidX);
251
                    xcoords[i] = (y + (m * previousValidX) - previousValidY)/m;
252
                }
253
                previousValidIndex = NaN;
254
                nextValidIndex = NaN;
255
            }
256
        }
257
    },
258
 
259
    /**
260
     * Returns the previous valid (numeric) value in an array if available.
261
     *
262
     * @method _getPreviousValidCoordValue
263
     * @param {Array} coords Array of values
264
     * @param {Number} index The index in the array in which to begin searching.
265
     * @return Number
266
     * @private
267
     */
268
    _getPreviousValidCoordValue: function(coords, index)
269
    {
270
        var coord,
271
            isNumber = Y_Lang.isNumber,
272
            limit = -1;
273
        while(!isNumber(coord) && index > limit)
274
        {
275
            index = index - 1;
276
            coord = coords[index];
277
        }
278
        return coord;
279
    },
280
 
281
    /**
282
     * Returns the next valid (numeric) value in an array if available.
283
     *
284
     * @method _getNextValidCoordValue
285
     * @param {Array} coords Array of values
286
     * @param {Number} index The index in the array in which to begin searching.
287
     * @return Number
288
     * @private
289
     */
290
    _getNextValidCoordValue: function(coords, index)
291
    {
292
        var coord,
293
            isNumber = Y_Lang.isNumber,
294
            limit = coords.length;
295
        while(!isNumber(coord) && index < limit)
296
        {
297
            index = index + 1;
298
            coord = coords[index];
299
        }
300
        return coord;
301
    },
302
 
303
    /**
304
     * Cleans invalid y-coordinates by calculating their value based on the corresponding x-coordinate, the
305
     * previous valid y-coordinate with its corresponding x-coordinate and the next valid y-coordinate with
306
     * its corresponding x-coordinate. If there is no previous or next valid y-coordinate, the value will not
307
     * be altered.
308
     *
309
     * @method _cleanYNaN
310
     * @param {Array} xcoords An array of x-coordinate values
311
     * @param {Array} ycoords An arry of y-coordinate values
312
     * @private
313
     */
314
    _cleanYNaN: function(xcoords, ycoords)
315
    {
316
        var previousValidIndex,
317
            nextValidIndex,
318
            previousValidX,
319
            previousValidY,
320
            x,
321
            y,
322
            nextValidX,
323
            nextValidY,
324
            isNumber = Y_Lang.isNumber,
325
            m,
326
            i = 0,
327
            len = xcoords.length;
328
        for(; i < len; ++i)
329
        {
330
            x = xcoords[i];
331
            y = ycoords[i];
332
            //if y is invalid, calculate where it should be
333
            if(!isNumber(y) && i > 0 && i < len - 1)
334
            {
335
                //check to see if the previous value is valid
336
                previousValidX = xcoords[i - 1];
337
                previousValidY = this._getPreviousValidCoordValue(ycoords, i);
338
                //check to see if the next value is valid
339
                nextValidX = xcoords[i + 1];
340
                nextValidY = this._getNextValidCoordValue(ycoords, i);
341
                if(isNumber(previousValidY) && isNumber(nextValidY))
342
                {
343
                    //calculate slope and solve for y
344
                    m = (nextValidY - previousValidY) / (nextValidX - previousValidX);
345
                    ycoords[i] = previousValidY + ((m * x) - (m * previousValidX));
346
                }
347
                previousValidIndex = NaN;
348
                nextValidIndex = NaN;
349
            }
350
        }
351
    }
352
};
353
Y.StackingUtil = StackingUtil;
354
 
355
 
356
}, '3.18.1', {"requires": ["axis-stacked"]});