@elastic/charts
Version:
Elastic-Charts data visualization library
99 lines • 4.1 kB
JavaScript
;
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