diff --git a/src/core/core.helpers.js b/src/core/core.helpers.js index 07a4488c7..7d677fd27 100644 --- a/src/core/core.helpers.js +++ b/src/core/core.helpers.js @@ -756,13 +756,37 @@ 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) { diff --git a/src/core/core.scale.js b/src/core/core.scale.js index f614cd822..e02e5157b 100644 --- a/src/core/core.scale.js +++ b/src/core/core.scale.js @@ -204,7 +204,10 @@ 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; @@ -289,9 +292,15 @@ 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; @@ -313,7 +322,6 @@ } 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) {