]> git.ipfire.org Git - thirdparty/Chart.js.git/commitdiff
Adds a caching system to expensive measureText() function
authorMathias Küsel <mathiask@hotmail.de>
Fri, 15 Jan 2016 12:05:03 +0000 (13:05 +0100)
committerMathias Küsel <mathiask@hotmail.de>
Fri, 15 Jan 2016 12:05:03 +0000 (13:05 +0100)
src/core/core.helpers.js
src/core/core.scale.js

index 07a4488c775ad8fc422c12ec740dbf685ec6abb3..7d677fd2774df62dc7d46c7f2d203a6ee3c4a423 100644 (file)
        helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
                return fontStyle + " " + pixelSize + "px " + fontFamily;
        };
-       helpers.longestText = function(ctx, font, arrayOfStrings) {
+       helpers.longestText = function(ctx, font, arrayOfStrings, cache) {
+               cache = cache || {};
+               cache.data = cache.data || {};
+               cache.garbageCollect = cache.garbageCollect || [];
+
+               if (cache.font !== font) {
+                       cache.data = {};
+                       cache.garbageCollect = [];
+                       cache.font = font;
+               }
+
                ctx.font = font;
                var longest = 0;
                helpers.each(arrayOfStrings, function(string) {
-                       var textWidth = ctx.measureText(string).width;
-                       longest = (textWidth > longest) ? textWidth : longest;
+                       var textWidth = cache.data[string];
+                       if (!textWidth) {
+                               textWidth = cache.data[string] = ctx.measureText(string).width;
+                               cache.garbageCollect.push(string);
+                       }
+                       if (textWidth > longest)
+                               longest = textWidth;
                });
+
+               var gcLen = cache.garbageCollect.length / 2;
+               if (gcLen > arrayOfStrings.length) {
+                       for (var i = 0; i < gcLen; i++) {
+                               var key = cache.garbageCollect.shift();
+                               delete cache.data[key];
+                       }
+               }
+
                return longest;
        };
        helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {
index f614cd8220de37ce8be38680a2f50013da607e84..e02e5157b2fe16e38d4ea5ac30c635d7349ae61b 100644 (file)
                                        this.paddingRight = lastWidth / 2 + 3;
                                        this.paddingLeft = firstWidth / 2 + 3;
 
-                                       var originalLabelWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
+                                       if (!this.longestTextCache) {
+                                               this.longestTextCache = {};
+                                       }
+                                       var originalLabelWidth = helpers.longestText(this.ctx, labelFont, this.ticks, this.longestTextCache);
                                        var labelWidth = originalLabelWidth;
                                        var cosRotation;
                                        var sinRotation;
                                var labelFont = helpers.fontString(this.options.ticks.fontSize,
                                        this.options.ticks.fontStyle, this.options.ticks.fontFamily);
 
+                               if (!this.longestTextCache) {
+                                       this.longestTextCache = {};
+                               }
+
+                               var largestTextWidth = helpers.longestText(this.ctx, labelFont, this.ticks, this.longestTextCache);
+
                                if (this.isHorizontal()) {
                                        // A horizontal axis is more constrained by the height.
-                                       this.longestLabelWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
+                                       this.longestLabelWidth = largestTextWidth;
 
                                        // TODO - improve this calculation
                                        var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * this.longestLabelWidth) + 1.5 * this.options.ticks.fontSize;
                                } else {
                                        // A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first
                                        var maxLabelWidth = this.maxWidth - this.minSize.width;
-                                       var largestTextWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
 
                                        // Account for padding
                                        if (!this.options.ticks.mirror) {