UNPKG

@elastic/charts

Version:

Elastic-Charts data visualization library

99 lines 4.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.wrapText = wrapText; const text_utils_1 = require("../../common/text_utils"); const monotonic_hill_climb_1 = require("../../solvers/monotonic_hill_climb"); function wrapText(text, font, fontSize, maxLineWidth, maxLines, measure, locale, granularity = 'word') { const lines = []; lines.meta = { truncated: false, }; if (maxLines <= 0) { return lines; } const segmenter = textSegmenter(locale, granularity); const cleanedText = text.replaceAll('\n', ' ').replaceAll(/ +(?= )/g, ''); const segments = Array.from(segmenter(cleanedText)).map((d) => ({ ...d, width: measure(d.segment, font, fontSize).width, })); const ellipsisWidth = measure(text_utils_1.ELLIPSIS, font, fontSize).width; let currentLineWidth = 0; for (const segment of segments) { if (currentLineWidth + segment.width > maxLineWidth && segment.segment.trimStart().length > 0) { const multilineText = breakLongTextIntoLines(segment.segment, font, fontSize, maxLineWidth, Infinity, measure); if (multilineText.length === 0) { break; } lines.push(...multilineText); currentLineWidth = multilineText.length > 0 ? measure(multilineText.at(-1) ?? '', font, fontSize).width : 0; } else { const lineIndex = lines.length > 0 ? lines.length - 1 : 0; lines[lineIndex] = (lines[lineIndex] ?? '') + segment.segment; currentLineWidth += segment.width; } } if (lines.length > maxLines) { lines.meta.truncated = true; const lastLineMaxLineWidth = maxLineWidth - ellipsisWidth; const lineToTruncate = lines[maxLines - 1] ?? ''; const lastLine = clipTextToWidth(lineToTruncate, font, fontSize, lastLineMaxLineWidth, measure); if (lastLine.length > 0) { lines.splice(maxLines - 1, Infinity, `${lastLine}${text_utils_1.ELLIPSIS}`); } else { if (lastLineMaxLineWidth > 0) { lines.splice(maxLines - 1, Infinity, maxLines > 1 ? text_utils_1.ELLIPSIS : lineToTruncate.slice(0, 1)); } else { lines.splice(maxLines, Infinity); } } } return lines; } function textSegmenter(locale, granularity) { if ('Segmenter' in Intl) { const fn = new Intl.Segmenter(locale, { granularity }); return (text) => Array.from(fn.segment(text)); } else { return (text) => { return text .split(' ') .reduce((acc, segment, index, array) => { const currentSegment = { segment, index: index === 0 ? 0 : (acc.at(-1)?.index ?? 0) + 1, isWordLike: true, }; acc.push(currentSegment); if (index < array.length - 1) { acc.push({ segment: ' ', index: currentSegment.index + segment.length, isWordLike: false }); } return acc; }, []); }; } } function breakLongTextIntoLines(text, font, fontSize, lineWidth, maxLines, measure) { const lines = []; let remainingText = text; while (maxLines > lines.length && remainingText.length > 0) { const lineClippedText = clipTextToWidth(remainingText, font, fontSize, lineWidth, measure); if (lineClippedText.length === 0) { break; } else { lines.push(lineClippedText.trimStart()); remainingText = remainingText.slice(lineClippedText.length, Infinity); } } return lines; } function clipTextToWidth(text, font, fontSize, width, measure) { const maxCharsInLine = (0, monotonic_hill_climb_1.monotonicHillClimb)((chars) => measure(text.slice(0, chars), font, fontSize).width, text.length, width, (n) => Math.floor(n), 0); return text.slice(0, maxCharsInLine || 0); } //# sourceMappingURL=wrap.js.map