github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/packages/pyroscope-flamegraph/src/fitMode/fitMode.ts (about) 1 export const TailMode = 'TAIL'; 2 export const HeadMode = 'HEAD'; 3 4 export type FitModes = typeof TailMode | typeof HeadMode; 5 6 const margin = 3; 7 8 /** 9 * Returns a text and margin left used to write text into a canvas rectangle 10 * 11 * @param {FitModes} mode - 12 * @param {number} charSize - Size in pixels of an individual character. Assumes it's a monospace font. 13 * @param {number} rectWidth - Width in pixels of the rectangle 14 * @param {string} fullText - The text that will be first tried. 15 * @param {string} shortText - The text that willbe used when fullText can't fit. It's normally a substring of the original text. 16 */ 17 18 interface fitToCanvasRectProps { 19 mode: FitModes; 20 21 /** charSize - Size in pixels of an individual character. Assumes it's a monospace font. */ 22 charSize: number; 23 24 /** Width in pixels of the rectangle */ 25 rectWidth: number; 26 27 /** The text that will be first tried to fit */ 28 fullText: string; 29 30 /** The text that willbe used when fullText can't fit. It's normally a substring of the original text. */ 31 shortText: string; 32 } 33 34 export function fitToCanvasRect({ 35 mode, 36 charSize, 37 rectWidth, 38 fullText, 39 shortText, 40 }: fitToCanvasRectProps) { 41 switch (mode) { 42 case TailMode: 43 // Case 1: 44 // content fits rectangle width 45 // | rectangle | 46 // | text | 47 if (charSize * fullText.length <= rectWidth) { 48 // assume it's a monospaced font 49 return { 50 mode, 51 text: fullText, 52 marginLeft: margin, 53 }; 54 } 55 56 // assume it's a monospaced font 57 // if not the case, use 58 // ctx.measureText(shortName).width 59 const shortTextWidth = charSize * shortText.length; 60 61 // Case 2: 62 // short text fits rectangle width 63 // | rectangle | 64 // | long_text_text | 65 // | shorttext | 66 if (shortTextWidth <= rectWidth) { 67 // assume it's a monospaced font 68 return { 69 mode, 70 text: shortText, 71 marginLeft: margin, 72 }; 73 } 74 75 // Case 3: 76 // short text is bigger than rectangle width 77 // add a negative margin left 78 // so that the 'tail' of the string is visible 79 // | rectangle | 80 // | my_short_text | 81 return { 82 mode, 83 text: shortText, 84 marginLeft: -(shortTextWidth - rectWidth + margin), 85 }; 86 87 // Case 3: 88 // Normal 89 case HeadMode: 90 default: 91 return { 92 mode, 93 text: fullText, 94 marginLeft: margin, 95 }; 96 } 97 } 98 99 /** 100 * Returns an inline style in React format 101 * used to fit the content into a table cell 102 * or an empty object if not applicable. 103 * @param {FitModes} mode - The mode 104 */ 105 export function fitIntoTableCell(mode: FitModes): React.CSSProperties { 106 switch (mode) { 107 case TailMode: 108 return { 109 // prints from right to left 110 direction: 'rtl', 111 overflow: 'hidden', 112 textOverflow: 'ellipsis', 113 }; 114 115 case HeadMode: 116 default: 117 return { 118 overflow: 'hidden', 119 textOverflow: 'ellipsis', 120 }; 121 } 122 }