mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-09-22 12:58:12 +08:00
accurately compute largest possible string
This commit is contained in:
@@ -31,26 +31,94 @@ export default class Truncate extends Component {
|
||||
return this.fontIsLoaded ? "Roboto Condensed" : "Helvetica Neue";
|
||||
}
|
||||
|
||||
computeLargestTruncatedString = (
|
||||
str,
|
||||
maxSize,
|
||||
params,
|
||||
length = str.length - 1,
|
||||
lastLength = 0,
|
||||
close = -1
|
||||
) => {
|
||||
// Generate the truncated string with ellipses(not if full string)
|
||||
const shortenedString =
|
||||
length === str.length - 1
|
||||
? str
|
||||
: `${str.slice(0, length)}…${str.slice(-length / 2)}`;
|
||||
// Measure the size of that string
|
||||
const renderedSize = pixelWidth(shortenedString, params);
|
||||
|
||||
// If that full length string is smaller than the maxSize don't return a truncated string
|
||||
if (renderedSize < maxSize && length === str.length - 1) {
|
||||
return null;
|
||||
}
|
||||
// Base case: If we've narrowed down to a length, return the closest string
|
||||
if (length === lastLength) {
|
||||
console.log("RETURNING", { length, lastLength, renderedSize });
|
||||
return `${str.slice(0, close)}…${str.slice(-close / 2)}`;
|
||||
}
|
||||
// If the current size is longer than max
|
||||
if (renderedSize > maxSize) {
|
||||
console.log({
|
||||
length,
|
||||
lastLength,
|
||||
renderedSize,
|
||||
close,
|
||||
size: "big",
|
||||
});
|
||||
// If we're only one off from the closest string so far, just return the closest string
|
||||
if (length - close === 1) {
|
||||
console.log("RETURNING", { length, lastLength, renderedSize });
|
||||
|
||||
return `${str.slice(0, close)}…${str.slice(-close / 2)}`;
|
||||
}
|
||||
// Otherwise recursively call with half the current length
|
||||
return this.computeLargestTruncatedString(
|
||||
str,
|
||||
maxSize,
|
||||
params,
|
||||
length < lastLength
|
||||
? length / 2
|
||||
: Math.floor(Math.floor((length - lastLength) / 2) + lastLength),
|
||||
length,
|
||||
close
|
||||
);
|
||||
}
|
||||
// If the current size is smaller than the max
|
||||
if (renderedSize < maxSize) {
|
||||
console.log({
|
||||
length,
|
||||
lastLength,
|
||||
renderedSize,
|
||||
close,
|
||||
size: "small",
|
||||
});
|
||||
// Save this length as the closest so far
|
||||
close = length;
|
||||
// Recursively call with a larger string
|
||||
return this.computeLargestTruncatedString(
|
||||
str,
|
||||
maxSize,
|
||||
params,
|
||||
Math.floor((lastLength - length) / 2) + length,
|
||||
length,
|
||||
close
|
||||
);
|
||||
}
|
||||
console.log("RETURNING", { length, lastLength, renderedSize });
|
||||
|
||||
return shortenedString;
|
||||
};
|
||||
|
||||
maybeTruncateString = (str, maxSize, fontSize, bold, italic) => {
|
||||
const activeFont = Truncate.getLoadedFont();
|
||||
|
||||
const renderedSize = pixelWidth(str, {
|
||||
console.log({ activeFont });
|
||||
return this.computeLargestTruncatedString(str, maxSize, {
|
||||
font: activeFont,
|
||||
size: fontSize,
|
||||
map: widthsMap,
|
||||
bold,
|
||||
italic,
|
||||
});
|
||||
let truncatedString = null;
|
||||
if (renderedSize > maxSize) {
|
||||
const percentage = renderedSize / maxSize;
|
||||
const newLength = str.length / percentage;
|
||||
truncatedString = `${str.slice(0, newLength / 2)}…${str.slice(
|
||||
-newLength / 2
|
||||
)}`;
|
||||
}
|
||||
|
||||
return truncatedString;
|
||||
};
|
||||
|
||||
render() {
|
||||
@@ -69,6 +137,8 @@ export default class Truncate extends Component {
|
||||
bold,
|
||||
italic
|
||||
);
|
||||
console.log({ truncatedString });
|
||||
|
||||
// Only make tooltip if string has to be truncated
|
||||
if (truncatedString) {
|
||||
// clone children, changing the children(text) to the truncated string
|
||||
|
||||
Reference in New Issue
Block a user