]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Cache data limits to ensure they are only computed once per update (#8234)
authorEvert Timberg <evert.timberg+github@gmail.com>
Sat, 26 Dec 2020 19:37:23 +0000 (14:37 -0500)
committerGitHub <noreply@github.com>
Sat, 26 Dec 2020 19:37:23 +0000 (14:37 -0500)
* Cache data limits to ensure they are only computed once per updaet
* Replace `invalidateCaches` on scales with `beforeLayout`

src/core/core.datasetController.js
src/core/core.layouts.js
src/core/core.scale.js
src/scales/scale.time.js
types/index.esm.d.ts

index bbd98de471438a4f7c58c6b3f1ff5441adf50b23..8fbe026319869d86ee5fa59a6078a23682744ca6 100644 (file)
@@ -415,7 +415,7 @@ export default class DatasetController {
        parse(start, count) {
                const me = this;
                const {_cachedMeta: meta, _data: data} = me;
-               const {iScale, vScale, _stacked} = meta;
+               const {iScale, _stacked} = meta;
                const iAxis = iScale.axis;
                let sorted = true;
                let i, parsed, cur, prev;
@@ -453,9 +453,6 @@ export default class DatasetController {
                if (_stacked) {
                        updateStacks(me, parsed);
                }
-
-               iScale.invalidateCaches();
-               vScale.invalidateCaches();
        }
 
        /**
index 1e7005fe265ebf37297dbc5dad889b0f726960d1..5002f0b5f2678d56de7af157a844faf4a76fe49e 100644 (file)
@@ -319,6 +319,14 @@ export default {
                const verticalBoxes = boxes.vertical;
                const horizontalBoxes = boxes.horizontal;
 
+               // Before any changes are made, notify boxes that an update is about to being
+               // This is used to clear any cached data (e.g. scale limits)
+               each(chart.boxes, box => {
+                       if (typeof box.beforeLayout === 'function') {
+                               box.beforeLayout();
+                       }
+               });
+
                // Essentially we now have any number of boxes on each of the 4 sides.
                // Our canvas looks like the following.
                // The areas L1 and L2 are the left axes. R1 is the right axis, T1 is the top axis and
index 66c890b4ceb6d3540a4a79a5fbc0dd8c3fa79e2e..4bcabe0224fd7322ddfa7b22b44c1631d2288c65 100644 (file)
@@ -384,6 +384,7 @@ export default class Scale extends Element {
                this._ticksLength = 0;
                this._borderValue = 0;
                this._cache = {};
+               this._dataLimitsCached = false;
                this.$context = undefined;
        }
 
@@ -466,10 +467,6 @@ export default class Scale extends Element {
                };
        }
 
-       invalidateCaches() {
-               this._cache = {};
-       }
-
        /**
         * Get the padding needed for the scale
         * @return {{top: number, left: number, bottom: number, right: number}} the necessary padding
@@ -502,6 +499,12 @@ export default class Scale extends Element {
                return this.options.labels || (this.isHorizontal() ? data.xLabels : data.yLabels) || data.labels || [];
        }
 
+       // When a new layout is created, reset the data limits cache
+       beforeLayout() {
+               this._cache = {};
+               this._dataLimitsCached = false;
+       }
+
        // These methods are ordered by lifecycle. Utilities then follow.
        // Any function defined here is inherited by all scale types.
        // Any function can be extended by the scale type
@@ -547,9 +550,12 @@ export default class Scale extends Element {
                me.afterSetDimensions();
 
                // Data min/max
-               me.beforeDataLimits();
-               me.determineDataLimits();
-               me.afterDataLimits();
+               if (!me._dataLimitsCached) {
+                       me.beforeDataLimits();
+                       me.determineDataLimits();
+                       me.afterDataLimits();
+                       me._dataLimitsCached = true;
+               }
 
                me.beforeBuildTicks();
 
index f8ad236b1661df531784f5ab51b46724b2162e63..1a371f70ae6ad008b04fd73ddb027478aff37452 100644 (file)
@@ -249,7 +249,8 @@ export default class TimeScale extends Scale {
                return parse(this, raw);
        }
 
-       invalidateCaches() {
+       beforeLayout() {
+               super.beforeLayout();
                this._cache = {
                        data: [],
                        labels: [],
index b6df557a7a67c6648b95d88130266c004d7e2514..075a51eb2b57178be047ac8020907c10c8f55f72 100644 (file)
@@ -718,7 +718,12 @@ export interface LayoutItem {
        /**
         * Returns an object with padding on the edges
         */
-       getPadding?(): ChartArea;
+  getPadding?(): ChartArea;
+  
+  /**
+   * Called before the layout process starts
+   */
+  beforeLayout?(): void;
 
        /**
         *  Width of item. Must be valid after update()
@@ -1255,7 +1260,7 @@ export interface Scale<O extends CoreScaleOptions = CoreScaleOptions> extends El
        parse(raw: any, index: number): any;
        getUserBounds(): { min: number; max: number; minDefined: boolean; maxDefined: boolean };
        getMinMax(canStack: boolean): { min: number; max: number };
-       invalidateCaches(): void;
+       beforeLayout(): void;
        getPadding(): ChartArea;
        getTicks(): Tick[];
        getLabels(): string[];