mirror of
https://github.com/chartjs/Chart.js.git
synced 2025-12-08 20:36:08 +00:00
[performance] replace helpers.each calls with for-loops (#6301)
* [performance] replace helpers.each calls with for-loops * Use Math.min/max instead of if statement * Rename variable
This commit is contained in:
parent
db6a6d5989
commit
07109b674b
@ -553,25 +553,30 @@ module.exports = function() {
|
||||
|
||||
ctx.font = font;
|
||||
var longest = 0;
|
||||
helpers.each(arrayOfThings, function(thing) {
|
||||
var ilen = arrayOfThings.length;
|
||||
var i, j, jlen, thing, nestedThing;
|
||||
for (i = 0; i < ilen; i++) {
|
||||
thing = arrayOfThings[i];
|
||||
|
||||
// Undefined strings and arrays should not be measured
|
||||
if (thing !== undefined && thing !== null && helpers.isArray(thing) !== true) {
|
||||
longest = helpers.measureText(ctx, data, gc, longest, thing);
|
||||
} else if (helpers.isArray(thing)) {
|
||||
// if it is an array lets measure each element
|
||||
// to do maybe simplify this function a bit so we can do this more recursively?
|
||||
helpers.each(thing, function(nestedThing) {
|
||||
for (j = 0, jlen = thing.length; j < jlen; j++) {
|
||||
nestedThing = thing[j];
|
||||
// Undefined strings and arrays should not be measured
|
||||
if (nestedThing !== undefined && nestedThing !== null && !helpers.isArray(nestedThing)) {
|
||||
longest = helpers.measureText(ctx, data, gc, longest, nestedThing);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var gcLen = gc.length / 2;
|
||||
if (gcLen > arrayOfThings.length) {
|
||||
for (var i = 0; i < gcLen; i++) {
|
||||
for (i = 0; i < gcLen; i++) {
|
||||
delete data[gc[i]];
|
||||
}
|
||||
gc.splice(0, gcLen);
|
||||
@ -589,6 +594,10 @@ module.exports = function() {
|
||||
}
|
||||
return longest;
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
helpers.numberOfLabelLines = function(arrayOfThings) {
|
||||
var numberOfLines = 1;
|
||||
helpers.each(arrayOfThings, function(thing) {
|
||||
|
||||
@ -16,40 +16,36 @@ module.exports = LinearScaleBase.extend({
|
||||
var me = this;
|
||||
var opts = me.options;
|
||||
var chart = me.chart;
|
||||
var data = chart.data;
|
||||
var datasets = data.datasets;
|
||||
var datasets = chart.data.datasets;
|
||||
var isHorizontal = me.isHorizontal();
|
||||
var DEFAULT_MIN = 0;
|
||||
var DEFAULT_MAX = 1;
|
||||
var datasetIndex, meta, value, data, i, ilen;
|
||||
|
||||
function IDMatches(meta) {
|
||||
return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
|
||||
function IDMatches(datasetMeta) {
|
||||
return isHorizontal ? datasetMeta.xAxisID === me.id : datasetMeta.yAxisID === me.id;
|
||||
}
|
||||
|
||||
// First Calculate the range
|
||||
me.min = null;
|
||||
me.max = null;
|
||||
me.min = Number.POSITIVE_INFINITY;
|
||||
me.max = Number.NEGATIVE_INFINITY;
|
||||
|
||||
var hasStacks = opts.stacked;
|
||||
if (hasStacks === undefined) {
|
||||
helpers.each(datasets, function(dataset, datasetIndex) {
|
||||
if (hasStacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
var meta = chart.getDatasetMeta(datasetIndex);
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
|
||||
meta.stack !== undefined) {
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) && meta.stack !== undefined) {
|
||||
hasStacks = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.stacked || hasStacks) {
|
||||
var valuesPerStack = {};
|
||||
|
||||
helpers.each(datasets, function(dataset, datasetIndex) {
|
||||
var meta = chart.getDatasetMeta(datasetIndex);
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
var key = [
|
||||
meta.type,
|
||||
// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
|
||||
@ -69,64 +65,59 @@ module.exports = LinearScaleBase.extend({
|
||||
var negativeValues = valuesPerStack[key].negativeValues;
|
||||
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
|
||||
helpers.each(dataset.data, function(rawValue, index) {
|
||||
var value = me._parseValue(rawValue);
|
||||
data = datasets[datasetIndex].data;
|
||||
for (i = 0, ilen = data.length; i < ilen; i++) {
|
||||
value = me._parseValue(data[i]);
|
||||
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[index].hidden) {
|
||||
return;
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
positiveValues[index] = positiveValues[index] || 0;
|
||||
negativeValues[index] = negativeValues[index] || 0;
|
||||
positiveValues[i] = positiveValues[i] || 0;
|
||||
negativeValues[i] = negativeValues[i] || 0;
|
||||
|
||||
if (value.min === 0 && !opts.ticks.beginAtZero) {
|
||||
value.min = value.max;
|
||||
}
|
||||
|
||||
if (opts.relativePoints) {
|
||||
positiveValues[index] = 100;
|
||||
positiveValues[i] = 100;
|
||||
} else if (value.min < 0 || value.max < 0) {
|
||||
negativeValues[index] += value.min;
|
||||
negativeValues[i] += value.min;
|
||||
} else {
|
||||
positiveValues[index] += value.max;
|
||||
positiveValues[i] += value.max;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
helpers.each(valuesPerStack, function(valuesForType) {
|
||||
var values = valuesForType.positiveValues.concat(valuesForType.negativeValues);
|
||||
var minVal = helpers.min(values);
|
||||
var maxVal = helpers.max(values);
|
||||
me.min = me.min === null ? minVal : Math.min(me.min, minVal);
|
||||
me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
|
||||
me.min = Math.min(me.min, helpers.min(values));
|
||||
me.max = Math.max(me.max, helpers.max(values));
|
||||
});
|
||||
|
||||
} else {
|
||||
helpers.each(datasets, function(dataset, datasetIndex) {
|
||||
var meta = chart.getDatasetMeta(datasetIndex);
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
|
||||
helpers.each(dataset.data, function(rawValue, index) {
|
||||
var value = me._parseValue(rawValue);
|
||||
data = datasets[datasetIndex].data;
|
||||
for (i = 0, ilen = data.length; i < ilen; i++) {
|
||||
value = me._parseValue(data[i]);
|
||||
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[index].hidden) {
|
||||
return;
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (me.min === null || value.min < me.min) {
|
||||
me.min = value.min;
|
||||
}
|
||||
|
||||
if (me.max === null || me.max < value.max) {
|
||||
me.max = value.max;
|
||||
}
|
||||
});
|
||||
me.min = Math.min(value.min, me.min);
|
||||
me.max = Math.max(value.max, me.max);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
me.min = isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;
|
||||
me.max = isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;
|
||||
me.min = helpers.isFinite(me.min) && !isNaN(me.min) ? me.min : DEFAULT_MIN;
|
||||
me.max = helpers.isFinite(me.max) && !isNaN(me.max) ? me.max : DEFAULT_MAX;
|
||||
|
||||
// Common base implementation to handle ticks.min, ticks.max, ticks.beginAtZero
|
||||
this.handleTickRangeOptions();
|
||||
|
||||
@ -72,38 +72,35 @@ module.exports = Scale.extend({
|
||||
var me = this;
|
||||
var opts = me.options;
|
||||
var chart = me.chart;
|
||||
var data = chart.data;
|
||||
var datasets = data.datasets;
|
||||
var datasets = chart.data.datasets;
|
||||
var isHorizontal = me.isHorizontal();
|
||||
function IDMatches(meta) {
|
||||
return isHorizontal ? meta.xAxisID === me.id : meta.yAxisID === me.id;
|
||||
}
|
||||
var datasetIndex, meta, value, data, i, ilen;
|
||||
|
||||
// Calculate Range
|
||||
me.min = null;
|
||||
me.max = null;
|
||||
me.minNotZero = null;
|
||||
me.min = Number.POSITIVE_INFINITY;
|
||||
me.max = Number.NEGATIVE_INFINITY;
|
||||
me.minNotZero = Number.POSITIVE_INFINITY;
|
||||
|
||||
var hasStacks = opts.stacked;
|
||||
if (hasStacks === undefined) {
|
||||
helpers.each(datasets, function(dataset, datasetIndex) {
|
||||
if (hasStacks) {
|
||||
return;
|
||||
}
|
||||
|
||||
var meta = chart.getDatasetMeta(datasetIndex);
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta) &&
|
||||
meta.stack !== undefined) {
|
||||
hasStacks = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.stacked || hasStacks) {
|
||||
var valuesPerStack = {};
|
||||
|
||||
helpers.each(datasets, function(dataset, datasetIndex) {
|
||||
var meta = chart.getDatasetMeta(datasetIndex);
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
var key = [
|
||||
meta.type,
|
||||
// we have a separate stack for stack=undefined datasets when the opts.stacked is undefined
|
||||
@ -116,55 +113,56 @@ module.exports = Scale.extend({
|
||||
valuesPerStack[key] = [];
|
||||
}
|
||||
|
||||
helpers.each(dataset.data, function(rawValue, index) {
|
||||
data = datasets[datasetIndex].data;
|
||||
for (i = 0, ilen = data.length; i < ilen; i++) {
|
||||
var values = valuesPerStack[key];
|
||||
var value = me._parseValue(rawValue);
|
||||
value = me._parseValue(data[i]);
|
||||
// invalid, hidden and negative values are ignored
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[index].hidden || value.min < 0 || value.max < 0) {
|
||||
return;
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden || value.min < 0 || value.max < 0) {
|
||||
continue;
|
||||
}
|
||||
values[index] = values[index] || 0;
|
||||
values[index] += value.max;
|
||||
});
|
||||
values[i] = values[i] || 0;
|
||||
values[i] += value.max;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
helpers.each(valuesPerStack, function(valuesForType) {
|
||||
if (valuesForType.length > 0) {
|
||||
var minVal = helpers.min(valuesForType);
|
||||
var maxVal = helpers.max(valuesForType);
|
||||
me.min = me.min === null ? minVal : Math.min(me.min, minVal);
|
||||
me.max = me.max === null ? maxVal : Math.max(me.max, maxVal);
|
||||
me.min = Math.min(me.min, minVal);
|
||||
me.max = Math.max(me.max, maxVal);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
helpers.each(datasets, function(dataset, datasetIndex) {
|
||||
var meta = chart.getDatasetMeta(datasetIndex);
|
||||
for (datasetIndex = 0; datasetIndex < datasets.length; datasetIndex++) {
|
||||
meta = chart.getDatasetMeta(datasetIndex);
|
||||
if (chart.isDatasetVisible(datasetIndex) && IDMatches(meta)) {
|
||||
helpers.each(dataset.data, function(rawValue, index) {
|
||||
var value = me._parseValue(rawValue);
|
||||
data = datasets[datasetIndex].data;
|
||||
for (i = 0, ilen = data.length; i < ilen; i++) {
|
||||
value = me._parseValue(data[i]);
|
||||
// invalid, hidden and negative values are ignored
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[index].hidden || value.min < 0 || value.max < 0) {
|
||||
return;
|
||||
if (isNaN(value.min) || isNaN(value.max) || meta.data[i].hidden || value.min < 0 || value.max < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (me.min === null || value.min < me.min) {
|
||||
me.min = value.min;
|
||||
}
|
||||
me.min = Math.min(value.min, me.min);
|
||||
me.max = Math.max(value.max, me.max);
|
||||
|
||||
if (me.max === null || me.max < value.max) {
|
||||
me.max = value.max;
|
||||
if (value.min !== 0) {
|
||||
me.minNotZero = Math.min(value.min, me.minNotZero);
|
||||
}
|
||||
|
||||
if (value.min !== 0 && (me.minNotZero === null || value.min < me.minNotZero)) {
|
||||
me.minNotZero = value.min;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
me.min = helpers.isFinite(me.min) ? me.min : null;
|
||||
me.max = helpers.isFinite(me.max) ? me.max : null;
|
||||
me.minNotZero = helpers.isFinite(me.minNotZero) ? me.minNotZero : null;
|
||||
|
||||
// Common base implementation to handle ticks.min, ticks.max
|
||||
this.handleTickRangeOptions();
|
||||
},
|
||||
|
||||
@ -45,8 +45,8 @@ describe('Test tick generators', function() {
|
||||
var xAxis = chart.scales['x-axis-0'];
|
||||
var yAxis = chart.scales['y-axis-0'];
|
||||
|
||||
expect(xAxis.ticks).toEqual(['-1', '-0.8', '-0.6', '-0.4', '-0.2', '0', '0.2', '0.4', '0.6', '0.8', '1']);
|
||||
expect(yAxis.ticks).toEqual(['1', '0.8', '0.6', '0.4', '0.2', '0', '-0.2', '-0.4', '-0.6', '-0.8', '-1']);
|
||||
expect(xAxis.ticks).toEqual(['0', '0.1', '0.2', '0.3', '0.4', '0.5', '0.6', '0.7', '0.8', '0.9', '1']);
|
||||
expect(yAxis.ticks).toEqual(['1', '0.9', '0.8', '0.7', '0.6', '0.5', '0.4', '0.3', '0.2', '0.1', '0']);
|
||||
});
|
||||
|
||||
it('Should generate logarithmic spaced ticks with correct precision', function() {
|
||||
|
||||
@ -453,7 +453,7 @@ describe('Linear Scale', function() {
|
||||
});
|
||||
|
||||
expect(chart.scales.yScale0).not.toEqual(undefined); // must construct
|
||||
expect(chart.scales.yScale0.min).toBe(-1);
|
||||
expect(chart.scales.yScale0.min).toBe(0);
|
||||
expect(chart.scales.yScale0.max).toBe(1);
|
||||
});
|
||||
|
||||
@ -829,10 +829,11 @@ describe('Linear Scale', function() {
|
||||
var chart = window.acquireChart({
|
||||
type: 'line',
|
||||
data: {
|
||||
labels: [-1, 1],
|
||||
datasets: [{
|
||||
xAxisID: 'xScale0',
|
||||
yAxisID: 'yScale0',
|
||||
data: []
|
||||
data: [-1, 1]
|
||||
}],
|
||||
},
|
||||
options: {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user