mirror of
https://github.com/chanzuckerberg/cellxgene.git
synced 2026-10-05 00:08: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";
|
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) => {
|
maybeTruncateString = (str, maxSize, fontSize, bold, italic) => {
|
||||||
const activeFont = Truncate.getLoadedFont();
|
const activeFont = Truncate.getLoadedFont();
|
||||||
|
console.log({ activeFont });
|
||||||
const renderedSize = pixelWidth(str, {
|
return this.computeLargestTruncatedString(str, maxSize, {
|
||||||
font: activeFont,
|
font: activeFont,
|
||||||
size: fontSize,
|
size: fontSize,
|
||||||
map: widthsMap,
|
map: widthsMap,
|
||||||
bold,
|
bold,
|
||||||
italic,
|
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() {
|
render() {
|
||||||
@@ -69,6 +137,8 @@ export default class Truncate extends Component {
|
|||||||
bold,
|
bold,
|
||||||
italic
|
italic
|
||||||
);
|
);
|
||||||
|
console.log({ truncatedString });
|
||||||
|
|
||||||
// Only make tooltip if string has to be truncated
|
// Only make tooltip if string has to be truncated
|
||||||
if (truncatedString) {
|
if (truncatedString) {
|
||||||
// clone children, changing the children(text) to the truncated string
|
// clone children, changing the children(text) to the truncated string
|
||||||
|
|||||||
Reference in New Issue
Block a user