Adds a caching system to expensive measureText() function

This commit is contained in:
Mathias Küsel 2016-01-15 13:05:03 +01:00
parent 25d6c2f064
commit 4f6e86640f
2 changed files with 38 additions and 6 deletions

View File

@ -756,13 +756,37 @@
helpers.fontString = function(pixelSize, fontStyle, fontFamily) { helpers.fontString = function(pixelSize, fontStyle, fontFamily) {
return fontStyle + " " + pixelSize + "px " + 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; ctx.font = font;
var longest = 0; var longest = 0;
helpers.each(arrayOfStrings, function(string) { helpers.each(arrayOfStrings, function(string) {
var textWidth = ctx.measureText(string).width; var textWidth = cache.data[string];
longest = (textWidth > longest) ? textWidth : longest; 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; return longest;
}; };
helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) { helpers.drawRoundedRectangle = function(ctx, x, y, width, height, radius) {

View File

@ -204,7 +204,10 @@
this.paddingRight = lastWidth / 2 + 3; this.paddingRight = lastWidth / 2 + 3;
this.paddingLeft = firstWidth / 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 labelWidth = originalLabelWidth;
var cosRotation; var cosRotation;
var sinRotation; var sinRotation;
@ -289,9 +292,15 @@
var labelFont = helpers.fontString(this.options.ticks.fontSize, var labelFont = helpers.fontString(this.options.ticks.fontSize,
this.options.ticks.fontStyle, this.options.ticks.fontFamily); 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()) { if (this.isHorizontal()) {
// A horizontal axis is more constrained by the height. // 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 // TODO - improve this calculation
var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * this.longestLabelWidth) + 1.5 * this.options.ticks.fontSize; var labelHeight = (Math.sin(helpers.toRadians(this.labelRotation)) * this.longestLabelWidth) + 1.5 * this.options.ticks.fontSize;
@ -313,7 +322,6 @@
} else { } else {
// A vertical axis is more constrained by the width. Labels are the dominant factor here, so get that length first // 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 maxLabelWidth = this.maxWidth - this.minSize.width;
var largestTextWidth = helpers.longestText(this.ctx, labelFont, this.ticks);
// Account for padding // Account for padding
if (!this.options.ticks.mirror) { if (!this.options.ticks.mirror) {