Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a564802

Browse files
committed
Early data parsing + stacking by value
determineDataLimits: simplify/fix for object data Add test for object data Make CC happier Review comments far far away some fixes Rebase, comments, cc warnings Some more cleanup get rid of _index
1 parent 21da5be commit a564802

18 files changed

+949
-577
lines changed

src/controllers/controller.bar.js

Lines changed: 105 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,57 @@ function computeFlexCategoryTraits(index, ruler, options) {
126126
};
127127
}
128128

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+
129180
module.exports = DatasetController.extend({
130181

131182
dataElementType: elements.Rectangle,
@@ -145,6 +196,36 @@ module.exports = DatasetController.extend({
145196
'minBarLength'
146197
],
147198

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+
148229
initialize: function() {
149230
var me = this;
150231
var meta, scaleOpts;
@@ -294,7 +375,7 @@ module.exports = DatasetController.extend({
294375
var i, ilen;
295376

296377
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)));
298379
}
299380

300381
return {
@@ -312,50 +393,36 @@ module.exports = DatasetController.extend({
312393
*/
313394
calculateBarValuePixels: function(datasetIndex, index, options) {
314395
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();
321397
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+
}
340408

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;
345415
}
416+
start += value;
346417
}
347418

348-
base = scale.getPixelForValue(start);
349-
head = scale.getPixelForValue(start + length);
419+
base = valueScale.getPixelForValue(start);
420+
head = valueScale.getPixelForValue(start + length);
350421
size = head - base;
351422

352423
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;
359426
}
360427

361428
return {
@@ -394,15 +461,13 @@ module.exports = DatasetController.extend({
394461
var chart = me.chart;
395462
var scale = me._getValueScale();
396463
var rects = me.getMeta().data;
397-
var dataset = me.getDataset();
398464
var ilen = rects.length;
399465
var i = 0;
400466

401467
helpers.canvas.clipArea(chart.ctx, chart.chartArea);
402468

403469
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))) {
406471
rects[i].draw();
407472
}
408473
}

src/controllers/controller.bubble.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,13 @@ module.exports = DatasetController.extend({
6363
'rotation'
6464
],
6565

66+
/**
67+
* @private
68+
*/
69+
_parseCustomObjectData: function(obj) {
70+
return obj && obj.r && +obj.r;
71+
},
72+
6673
/**
6774
* @protected
6875
*/
@@ -87,11 +94,10 @@ module.exports = DatasetController.extend({
8794
var xScale = me.getScaleForId(meta.xAxisID);
8895
var yScale = me.getScaleForId(meta.yAxisID);
8996
var options = me._resolveDataElementOptions(point, index);
90-
var data = me.getDataset().data[index];
9197
var dsIndex = me.index;
9298

93-
var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(typeof data === 'object' ? data : NaN, index, dsIndex);
94-
var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(data, index, dsIndex);
99+
var x = reset ? xScale.getPixelForDecimal(0.5) : xScale.getPixelForValue(me._getParsedValue(xScale, index));
100+
var y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(me._getParsedValue(yScale, index));
95101

96102
point._xScale = xScale;
97103
point._yScale = yScale;

src/controllers/controller.doughnut.js

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,19 @@ module.exports = DatasetController.extend({
137137
'hoverBorderWidth',
138138
],
139139

140+
/**
141+
* Override data parsing, since we are not using scales
142+
* @private
143+
*/
144+
_parse: function(start, count) {
145+
var data = this.getDataset().data;
146+
var metaData = this.getMeta().data;
147+
var i, ilen;
148+
for (i = start, ilen = start + count; i < ilen; ++i) {
149+
metaData[i]._val = +data[i];
150+
}
151+
},
152+
140153
// Get index of the dataset in relation to the visible datasets. This allows determining the inner and outer radius correctly
141154
getRingIndex: function(datasetIndex) {
142155
var ringIndex = 0;
@@ -223,7 +236,7 @@ module.exports = DatasetController.extend({
223236
var startAngle = opts.rotation; // non reset case handled later
224237
var endAngle = opts.rotation; // non reset case handled later
225238
var dataset = me.getDataset();
226-
var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(dataset.data[index]) * (opts.circumference / DOUBLE_PI);
239+
var circumference = reset && animationOpts.animateRotate ? 0 : arc.hidden ? 0 : me.calculateCircumference(arc._val * opts.circumference / DOUBLE_PI);
227240
var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;
228241
var outerRadius = reset && animationOpts.animateScale ? 0 : me.outerRadius;
229242
var options = arc._options || {};
@@ -267,14 +280,13 @@ module.exports = DatasetController.extend({
267280
},
268281

269282
calculateTotal: function() {
270-
var dataset = this.getDataset();
271-
var meta = this.getMeta();
283+
var metaData = this.getMeta().data;
272284
var total = 0;
273285
var value;
274286

275-
helpers.each(meta.data, function(element, index) {
276-
value = dataset.data[index];
277-
if (!isNaN(value) && !element.hidden) {
287+
helpers.each(metaData, function(arc) {
288+
value = arc ? arc._val : NaN;
289+
if (!isNaN(value) && !arc.hidden) {
278290
total += Math.abs(value);
279291
}
280292
});

src/controllers/controller.line.js

Lines changed: 16 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -117,18 +117,16 @@ module.exports = DatasetController.extend({
117117
var me = this;
118118
var meta = me.getMeta();
119119
var custom = point.custom || {};
120-
var dataset = me.getDataset();
121120
var datasetIndex = me.index;
122-
var value = dataset.data[index];
123121
var xScale = me._xScale;
124122
var yScale = me._yScale;
125123
var lineModel = meta.dataset._model;
126124
var x, y;
127125

128126
var options = me._resolveDataElementOptions(point, index);
129127

130-
x = xScale.getPixelForValue(typeof value === 'object' ? value : NaN, index, datasetIndex);
131-
y = reset ? yScale.getBasePixel() : me.calculatePointY(value, index, datasetIndex);
128+
x = xScale.getPixelForValue(me._getParsedValue(xScale, index));
129+
y = reset ? yScale.getBasePixel() : yScale.getPixelForValue(me._getStackedValue(yScale, index));
132130

133131
// Utility
134132
point._xScale = xScale;
@@ -177,42 +175,6 @@ module.exports = DatasetController.extend({
177175
return values;
178176
},
179177

180-
calculatePointY: function(value, index, datasetIndex) {
181-
var me = this;
182-
var chart = me.chart;
183-
var yScale = me._yScale;
184-
var sumPos = 0;
185-
var sumNeg = 0;
186-
var rightValue = +yScale.getRightValue(value);
187-
var metasets = chart._getSortedVisibleDatasetMetas();
188-
var ilen = metasets.length;
189-
var i, ds, dsMeta, stackedRightValue;
190-
191-
if (yScale.options.stacked) {
192-
for (i = 0; i < ilen; ++i) {
193-
dsMeta = metasets[i];
194-
if (dsMeta.index === datasetIndex) {
195-
break;
196-
}
197-
198-
ds = chart.data.datasets[dsMeta.index];
199-
if (dsMeta.type === 'line' && dsMeta.yAxisID === yScale.id) {
200-
stackedRightValue = +yScale.getRightValue(ds.data[index]);
201-
if (stackedRightValue < 0) {
202-
sumNeg += stackedRightValue || 0;
203-
} else {
204-
sumPos += stackedRightValue || 0;
205-
}
206-
}
207-
}
208-
209-
if (rightValue < 0) {
210-
return yScale.getPixelForValue(sumNeg + rightValue);
211-
}
212-
}
213-
return yScale.getPixelForValue(sumPos + rightValue);
214-
},
215-
216178
updateBezierControlPoints: function() {
217179
var me = this;
218180
var chart = me.chart;
@@ -319,4 +281,18 @@ module.exports = DatasetController.extend({
319281
model.borderWidth = valueOrDefault(options.hoverBorderWidth, options.borderWidth);
320282
model.radius = valueOrDefault(options.hoverRadius, options.radius);
321283
},
284+
285+
// DEPRECATIONS
286+
287+
/**
288+
* Provided for backward compatibility
289+
* @deprecated since version 2.9.0
290+
* @todo remove at version 3
291+
*/
292+
calculatePointY: function(value, index, datasetIndex) {
293+
var me = this;
294+
var chart = me.chart;
295+
var controller = datasetIndex === me.index ? me : chart.getDatasetMeta(datasetIndex).controller;
296+
return controller._getStackedValue(me._yScale, index);
297+
},
322298
});

0 commit comments

Comments
 (0)