GraphNG: optimize measureText(), drop estimation for y-axis auto-sizing (#38475)

This commit is contained in:
Leon Sorokin 2021-08-24 00:11:19 -05:00 committed by GitHub
parent 4cb87b6b60
commit 403bbd0144
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 17 deletions

View File

@ -143,8 +143,8 @@ function calculateAxisSize(self: uPlot, values: string[], axisIdx: number) {
if (axis.side === 2) {
axisSize += axis!.gap! + fontSize;
} else if (values?.length) {
let longestValue = values.reduce((acc, value) => (value.length > acc.length ? value : acc), '');
axisSize += axis!.gap! + axis!.labelGap! + measureText('0'.repeat(longestValue.length), fontSize).width;
let maxTextWidth = values.reduce((acc, value) => Math.max(acc, measureText(value, fontSize).width), 0);
axisSize += axis!.gap! + axis!.labelGap! + maxTextWidth;
}
return Math.ceil(axisSize);

View File

@ -1,19 +1,12 @@
let canvas: HTMLCanvasElement | null = null;
const cache: Record<string, TextMetrics> = {};
const context = document.createElement('canvas').getContext('2d')!;
const cache = new Map<string, TextMetrics>();
const cacheLimit = 500;
let ctxFontStyle = '';
/**
* @internal
*/
export function getCanvasContext() {
if (canvas === null) {
canvas = document.createElement('canvas');
}
const context = canvas.getContext('2d');
if (!context) {
throw new Error('Could not create context');
}
return context;
}
@ -23,18 +16,24 @@ export function getCanvasContext() {
export function measureText(text: string, fontSize: number): TextMetrics {
const fontStyle = `${fontSize}px 'Roboto'`;
const cacheKey = text + fontStyle;
const fromCache = cache[cacheKey];
const fromCache = cache.get(cacheKey);
if (fromCache) {
return fromCache;
}
const context = getCanvasContext();
if (ctxFontStyle !== fontStyle) {
context.font = ctxFontStyle = fontStyle;
}
context.font = fontStyle;
const metrics = context.measureText(text);
cache[cacheKey] = metrics;
if (cache.size === cacheLimit) {
cache.clear();
}
cache.set(cacheKey, metrics);
return metrics;
}