]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
[performance] replace helpers.each calls with for-loops (#6301)
authorBen McCann <322311+benmccann@users.noreply.github.com>
Sat, 22 Jun 2019 13:55:46 +0000 (06:55 -0700)
committerEvert Timberg <evert.timberg@gmail.com>
Sat, 22 Jun 2019 13:55:46 +0000 (09:55 -0400)
* [performance] replace helpers.each calls with for-loops

* Use Math.min/max instead of if statement

* Rename variable

src/core/core.helpers.js
src/scales/scale.linear.js
src/scales/scale.logarithmic.js
test/specs/core.ticks.tests.js
test/specs/scale.linear.tests.js

index 52c8aea68a845e8ab0fbd612a225dbda5fc16aee..31748758090704ee661fe9143d21461cf35f6027 100644 (file)
@@ -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) {
index a76f4593c118817345102d78713faa1a0fac32b5..7db13eb46cfa166a1b3028377700d10042c5bad7 100644 (file)
@@ -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();
index 1229e8d40a32a4b11c2c7539edd42efec50f951e..5def62aac554447a4b0c44be0ff333d22e9eed89 100644 (file)
@@ -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;
-                                               }
-
-                                               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);
 
-                                               if (value.min !== 0 && (me.minNotZero === null || value.min < me.minNotZero)) {
-                                                       me.minNotZero = value.min;
+                                               if (value.min !== 0) {
+                                                       me.minNotZero = Math.min(value.min, me.minNotZero);
                                                }
-                                       });
+                                       }
                                }
-                       });
+                       }
                }
 
+               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();
        },
index 01cecc5462ef67e4bad43a756992316ed10a80ea..afc2afda2050b75e94d7d99616bc3d2ef5389ea8 100644 (file)
@@ -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() {
index 383d7480d44b903d0290af8f559eec17605403f0..9af5c9cb950d350e6b333b52a00ae56a9b7f9f69 100644 (file)
@@ -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: {