UNPKG

@mui/x-charts

Version:

The community edition of MUI X Charts components.

53 lines (52 loc) 1.81 kB
import { getGraphemeCount } from "./getGraphemeCount.js"; import { degToRad } from "./degToRad.js"; import { sliceUntil } from "./sliceUntil.js"; const ELLIPSIS = '…'; export function doesTextFitInRect(text, config) { const { width, height, measureText } = config; const angle = degToRad(config.angle); const textSize = measureText(text); const angledWidth = Math.abs(textSize.width * Math.cos(angle)) + Math.abs(textSize.height * Math.sin(angle)); const angledHeight = Math.abs(textSize.width * Math.sin(angle)) + Math.abs(textSize.height * Math.cos(angle)); return angledWidth <= width && angledHeight <= height; } /** This function finds the best place to clip the text to add an ellipsis. * This function assumes that the {@link doesTextFit} never returns true for longer text after returning false for * shorter text. * * @param text Text to ellipsize if needed * @param doesTextFit a function that returns whether a string fits inside a container. */ export function ellipsize(text, doesTextFit) { if (doesTextFit(text)) { return text; } let shortenedText = text; let step = 1; let by = 1 / 2; const graphemeCount = getGraphemeCount(text); let newLength = graphemeCount; let lastLength = graphemeCount; let longestFittingText = null; do { lastLength = newLength; newLength = Math.floor(graphemeCount * by); if (newLength === 0) { break; } shortenedText = sliceUntil(text, newLength).trim(); const fits = doesTextFit(shortenedText + ELLIPSIS); step += 1; if (fits) { longestFittingText = shortenedText; by += 1 / 2 ** step; } else { by -= 1 / 2 ** step; } } while (Math.abs(newLength - lastLength) !== 1); return longestFittingText ? longestFittingText + ELLIPSIS : ''; }