@@ -126,6 +126,57 @@ function computeFlexCategoryTraits(index, ruler, options) {
126
126
} ;
127
127
}
128
128
129
+ function parseFloatBar ( arr , item , vScale , i ) {
130
+ var startValue = vScale . _parse ( arr [ 0 ] , i ) ;
131
+ var endValue = vScale . _parse ( arr [ 1 ] , i ) ;
132
+ var min = Math . min ( startValue , endValue ) ;
133
+ var max = Math . max ( startValue , endValue ) ;
134
+ var barStart = min ;
135
+ var barEnd = max ;
136
+
137
+ if ( Math . abs ( min ) > Math . abs ( max ) ) {
138
+ barStart = max ;
139
+ barEnd = min ;
140
+ }
141
+
142
+ // Store `barEnd` (furthest away from origin) as parsed value,
143
+ // to make stacking straight forward
144
+ item [ vScale . id ] = barEnd ;
145
+
146
+ item . _custom = {
147
+ barStart : barStart ,
148
+ barEnd : barEnd ,
149
+ start : startValue ,
150
+ end : endValue ,
151
+ min : min ,
152
+ max : max
153
+ } ;
154
+ }
155
+
156
+ function parseArrayOrPrimitive ( meta , data , start , count ) {
157
+ var iScale = this . _getIndexScale ( ) ;
158
+ var vScale = this . _getValueScale ( ) ;
159
+ var labels = iScale . _getLabels ( ) ;
160
+ var singleScale = iScale === vScale ;
161
+ var parsed = [ ] ;
162
+ var i , ilen , item , entry ;
163
+
164
+ for ( i = start , ilen = start + count ; i < ilen ; ++ i ) {
165
+ entry = data [ i ] ;
166
+ item = { _index : i } ;
167
+ item [ iScale . id ] = singleScale || iScale . _parse ( labels [ i ] , i ) ;
168
+
169
+ if ( helpers . isArray ( entry ) ) {
170
+ parseFloatBar ( entry , item , vScale , i ) ;
171
+ } else {
172
+ item [ vScale . id ] = vScale . _parse ( entry , i ) ;
173
+ }
174
+
175
+ parsed . push ( item ) ;
176
+ }
177
+ return parsed ;
178
+ }
179
+
129
180
module . exports = DatasetController . extend ( {
130
181
131
182
dataElementType : elements . Rectangle ,
@@ -145,6 +196,36 @@ module.exports = DatasetController.extend({
145
196
'minBarLength'
146
197
] ,
147
198
199
+ /**
200
+ * Parse array of primitive values
201
+ * @param {object } meta - dataset meta
202
+ * @param {array } data - data array. Example [1,3,4]
203
+ * @param {number } start - start index
204
+ * @param {number } count - number of items to parse
205
+ * @returns {object } parsed item - item containing index and a parsed value
206
+ * for each scale id.
207
+ * Example: {index: 1, xScale0: 0, yScale0: 1}
208
+ * @private
209
+ */
210
+ _parsePrimitiveData : function ( ) {
211
+ return parseArrayOrPrimitive . apply ( this , arguments ) ;
212
+ } ,
213
+
214
+ /**
215
+ * Parse array of arrays
216
+ * @param {object } meta - dataset meta
217
+ * @param {array } data - data array. Example [[1,2],[3,4]]
218
+ * @param {number } start - start index
219
+ * @param {number } count - number of items to parse
220
+ * @returns {object } parsed item - item containing index and a parsed value
221
+ * for each scale id.
222
+ * Example: {index: 1, xScale0: 0, yScale0: 1}
223
+ * @private
224
+ */
225
+ _parseArrayData : function ( ) {
226
+ return parseArrayOrPrimitive . apply ( this , arguments ) ;
227
+ } ,
228
+
148
229
initialize : function ( ) {
149
230
var me = this ;
150
231
var meta , scaleOpts ;
@@ -294,7 +375,7 @@ module.exports = DatasetController.extend({
294
375
var i , ilen ;
295
376
296
377
for ( i = 0 , ilen = me . getMeta ( ) . data . length ; i < ilen ; ++ i ) {
297
- pixels . push ( scale . getPixelForValue ( null , i , me . index ) ) ;
378
+ pixels . push ( scale . getPixelForValue ( me . _getParsedValue ( scale , i ) ) ) ;
298
379
}
299
380
300
381
return {
@@ -312,50 +393,36 @@ module.exports = DatasetController.extend({
312
393
*/
313
394
calculateBarValuePixels : function ( datasetIndex , index , options ) {
314
395
var me = this ;
315
- var chart = me . chart ;
316
- var scale = me . _getValueScale ( ) ;
317
- var isHorizontal = scale . isHorizontal ( ) ;
318
- var datasets = chart . data . datasets ;
319
- var metasets = scale . _getMatchingVisibleMetas ( me . _type ) ;
320
- var value = scale . _parseValue ( datasets [ datasetIndex ] . data [ index ] ) ;
396
+ var valueScale = me . _getValueScale ( ) ;
321
397
var minBarLength = options . minBarLength ;
322
- var stacked = scale . options . stacked ;
323
- var stack = me . getMeta ( ) . stack ;
324
- var start = value . start === undefined ? 0 : value . max >= 0 && value . min >= 0 ? value . min : value . max ;
325
- var length = value . start === undefined ? value . end : value . max >= 0 && value . min >= 0 ? value . max - value . min : value . min - value . max ;
326
- var ilen = metasets . length ;
327
- var i , imeta , ivalue , base , head , size , stackLength ;
328
-
329
- if ( stacked || ( stacked === undefined && stack !== undefined ) ) {
330
- for ( i = 0 ; i < ilen ; ++ i ) {
331
- imeta = metasets [ i ] ;
332
-
333
- if ( imeta . index === datasetIndex ) {
334
- break ;
335
- }
336
-
337
- if ( imeta . stack === stack ) {
338
- stackLength = scale . _parseValue ( datasets [ imeta . index ] . data [ index ] ) ;
339
- ivalue = stackLength . start === undefined ? stackLength . end : stackLength . min >= 0 && stackLength . max >= 0 ? stackLength . max : stackLength . min ;
398
+ var start = 0 ;
399
+ var value = me . _getParsedValue ( valueScale , index ) ;
400
+ var custom = me . _getParsedCustom ( index ) ;
401
+ var length = me . _getStackedValue ( valueScale , index ) ;
402
+ var base , head , size ;
403
+
404
+ if ( length !== value ) {
405
+ start = length - value ;
406
+ length = value ;
407
+ }
340
408
341
- if ( ( value . min < 0 && ivalue < 0 ) || ( value . max >= 0 && ivalue > 0 ) ) {
342
- start += ivalue ;
343
- }
344
- }
409
+ if ( custom && custom . barStart !== undefined && custom . barEnd !== undefined ) {
410
+ value = custom . barStart ;
411
+ length = custom . barEnd - custom . barStart ;
412
+ // bars crossing origin are not stacked
413
+ if ( value !== 0 && Math . sign ( value ) !== Math . sign ( custom . barEnd ) ) {
414
+ start = 0 ;
345
415
}
416
+ start += value ;
346
417
}
347
418
348
- base = scale . getPixelForValue ( start ) ;
349
- head = scale . getPixelForValue ( start + length ) ;
419
+ base = valueScale . getPixelForValue ( start ) ;
420
+ head = valueScale . getPixelForValue ( start + length ) ;
350
421
size = head - base ;
351
422
352
423
if ( minBarLength !== undefined && Math . abs ( size ) < minBarLength ) {
353
- size = minBarLength ;
354
- if ( length >= 0 && ! isHorizontal || length < 0 && isHorizontal ) {
355
- head = base - minBarLength ;
356
- } else {
357
- head = base + minBarLength ;
358
- }
424
+ size = size < 0 ? - minBarLength : minBarLength ;
425
+ head = base + size ;
359
426
}
360
427
361
428
return {
@@ -394,15 +461,13 @@ module.exports = DatasetController.extend({
394
461
var chart = me . chart ;
395
462
var scale = me . _getValueScale ( ) ;
396
463
var rects = me . getMeta ( ) . data ;
397
- var dataset = me . getDataset ( ) ;
398
464
var ilen = rects . length ;
399
465
var i = 0 ;
400
466
401
467
helpers . canvas . clipArea ( chart . ctx , chart . chartArea ) ;
402
468
403
469
for ( ; i < ilen ; ++ i ) {
404
- var val = scale . _parseValue ( dataset . data [ i ] ) ;
405
- if ( ! isNaN ( val . min ) && ! isNaN ( val . max ) ) {
470
+ if ( ! isNaN ( me . _getParsedValue ( scale , i ) ) ) {
406
471
rects [ i ] . draw ( ) ;
407
472
}
408
473
}
0 commit comments