flamegraphTheme.tsx 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. import {lightTheme} from '../../theme';
  2. import {FlamegraphFrame} from '../flamegraphFrame';
  3. import {makeColorBucketTheme, makeColorMap, makeStackToColor} from './../colors/utils';
  4. import {Frame} from './../frame';
  5. const MONOSPACE_FONT = `ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono',
  6. 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono',
  7. 'Courier New', monospace`;
  8. const FRAME_FONT = lightTheme.text.familyMono;
  9. // Luma chroma hue settings
  10. export interface LCH {
  11. C_0: number;
  12. C_d: number;
  13. L_0: number;
  14. L_d: number;
  15. }
  16. // Color can be rgb or rgba. I want to probably eliminate rgb and just use rgba, but we would be allocating 25% more memory,
  17. // and I'm not sure about the impact we'd need. There is a tradeoff between memory and runtime performance checks that I'll need to evaluate at some point.
  18. export type ColorChannels = [number, number, number] | [number, number, number, number];
  19. export interface FlamegraphTheme {
  20. // @TODO, most colors are defined as strings, which is a mistake as we loose a lot of functionality and impose constraints.
  21. // They should instead be defined as arrays of numbers so we can use them with glsl and avoid unnecessary parsing
  22. COLORS: {
  23. BAR_LABEL_FONT_COLOR: string;
  24. COLOR_BUCKET: (t: number, frame?: Frame) => ColorChannels;
  25. COLOR_MAP: (
  26. frames: ReadonlyArray<FlamegraphFrame>,
  27. colorBucket: FlamegraphTheme['COLORS']['COLOR_BUCKET'],
  28. sortByKey?: (a: FlamegraphFrame, b: FlamegraphFrame) => number
  29. ) => Map<FlamegraphFrame['frame']['key'], ColorChannels>;
  30. CURSOR_CROSSHAIR: string;
  31. DIFFERENTIAL_DECREASE: ColorChannels;
  32. DIFFERENTIAL_INCREASE: ColorChannels;
  33. FRAME_FALLBACK_COLOR: [number, number, number, number];
  34. GRID_FRAME_BACKGROUND_COLOR: string;
  35. GRID_LINE_COLOR: string;
  36. HIGHLIGHTED_LABEL_COLOR: ColorChannels;
  37. HOVERED_FRAME_BORDER_COLOR: string;
  38. LABEL_FONT_COLOR: string;
  39. MINIMAP_POSITION_OVERLAY_BORDER_COLOR: string;
  40. MINIMAP_POSITION_OVERLAY_COLOR: string;
  41. REQUEST_2XX_RESPONSE: string;
  42. REQUEST_4XX_RESPONSE: string;
  43. REQUEST_DNS_TIME: string;
  44. REQUEST_SSL_TIME: string;
  45. REQUEST_TCP_TIME: string;
  46. // Nice color picker for GLSL colors - https://keiwando.com/color-picker/
  47. REQUEST_WAIT_TIME: string;
  48. SEARCH_RESULT_FRAME_COLOR: string;
  49. SELECTED_FRAME_BORDER_COLOR: string;
  50. SPAN_FRAME_BACKGROUND: string;
  51. SPAN_FRAME_BORDER: string;
  52. STACK_TO_COLOR: (
  53. frames: ReadonlyArray<FlamegraphFrame>,
  54. colorMapFn: FlamegraphTheme['COLORS']['COLOR_MAP'],
  55. colorBucketFn: FlamegraphTheme['COLORS']['COLOR_BUCKET']
  56. ) => {
  57. colorBuffer: Array<number>;
  58. colorMap: Map<Frame['key'], ColorChannels>;
  59. };
  60. };
  61. CONFIG: {
  62. HIGHLIGHT_RECURSION: boolean;
  63. };
  64. FONTS: {
  65. FONT: string;
  66. FRAME_FONT: string;
  67. };
  68. SIZES: {
  69. BAR_FONT_SIZE: number;
  70. BAR_HEIGHT: number;
  71. BAR_PADDING: number;
  72. FLAMEGRAPH_DEPTH_OFFSET: number;
  73. FRAME_BORDER_WIDTH: number;
  74. GRID_LINE_WIDTH: number;
  75. HOVERED_FRAME_BORDER_WIDTH: number;
  76. LABEL_FONT_PADDING: number;
  77. LABEL_FONT_SIZE: number;
  78. MINIMAP_HEIGHT: number;
  79. MINIMAP_POSITION_OVERLAY_BORDER_WIDTH: number;
  80. REQUEST_BAR_HEIGHT: number;
  81. REQUEST_DEPTH_OFFSET: number;
  82. REQUEST_FONT_SIZE: number;
  83. // Request
  84. REQUEST_TAIL_HEIGHT: number;
  85. // Spans
  86. SPANS_BAR_HEIGHT: number;
  87. SPANS_DEPTH_OFFSET: number;
  88. SPANS_FONT_SIZE: number;
  89. TIMELINE_HEIGHT: number;
  90. TOOLTIP_FONT_SIZE: number;
  91. };
  92. }
  93. // Luma chroma hue settings for light theme
  94. export const LCH_LIGHT = {
  95. C_0: 0.25,
  96. C_d: 0.2,
  97. L_0: 0.8,
  98. L_d: 0.15,
  99. };
  100. // Luma chroma hue settings for dark theme
  101. export const LCH_DARK = {
  102. C_0: 0.2,
  103. C_d: 0.1,
  104. L_0: 0.2,
  105. L_d: 0.1,
  106. };
  107. export const LightFlamegraphTheme: FlamegraphTheme = {
  108. CONFIG: {
  109. HIGHLIGHT_RECURSION: false,
  110. },
  111. SIZES: {
  112. BAR_HEIGHT: 20,
  113. BAR_FONT_SIZE: 11,
  114. BAR_PADDING: 4,
  115. FLAMEGRAPH_DEPTH_OFFSET: 12,
  116. SPANS_DEPTH_OFFSET: 4,
  117. SPANS_FONT_SIZE: 10,
  118. SPANS_BAR_HEIGHT: 14,
  119. REQUEST_TAIL_HEIGHT: 8,
  120. REQUEST_BAR_HEIGHT: 14,
  121. REQUEST_FONT_SIZE: 10,
  122. REQUEST_DEPTH_OFFSET: 4,
  123. MINIMAP_POSITION_OVERLAY_BORDER_WIDTH: 2,
  124. MINIMAP_HEIGHT: 100,
  125. TIMELINE_HEIGHT: 20,
  126. LABEL_FONT_SIZE: 10,
  127. LABEL_FONT_PADDING: 6,
  128. FRAME_BORDER_WIDTH: 2,
  129. HOVERED_FRAME_BORDER_WIDTH: 1,
  130. TOOLTIP_FONT_SIZE: 12,
  131. GRID_LINE_WIDTH: 2,
  132. },
  133. COLORS: {
  134. LABEL_FONT_COLOR: '#1f233a',
  135. BAR_LABEL_FONT_COLOR: '#000',
  136. GRID_LINE_COLOR: '#e5e7eb',
  137. GRID_FRAME_BACKGROUND_COLOR: 'rgba(255, 255, 255, 0.8)',
  138. SEARCH_RESULT_FRAME_COLOR: 'vec4(0.99, 0.70, 0.35, 1.0)',
  139. SELECTED_FRAME_BORDER_COLOR: '#005aff',
  140. HIGHLIGHTED_LABEL_COLOR: [255, 255, 0],
  141. HOVERED_FRAME_BORDER_COLOR: 'rgba(0, 0, 0, 0.8)',
  142. CURSOR_CROSSHAIR: '#bbbbbb',
  143. SPAN_FRAME_BORDER: 'rgba(200, 200, 200, 1)',
  144. SPAN_FRAME_BACKGROUND: 'rgba(231, 231, 231, 0.5)',
  145. MINIMAP_POSITION_OVERLAY_COLOR: 'rgba(0,0,0,0.1)',
  146. MINIMAP_POSITION_OVERLAY_BORDER_COLOR: 'rgba(0,0,0, 0.2)',
  147. REQUEST_WAIT_TIME: `rgba(253,252,224, 1)`,
  148. REQUEST_DNS_TIME: `rgba(57, 146, 152, 1)`,
  149. REQUEST_TCP_TIME: `rgba(242, 146,57,1)`,
  150. REQUEST_SSL_TIME: `rgba(207,84,218, 1)`,
  151. REQUEST_2XX_RESPONSE: 'rgba(218, 231, 209, 1)',
  152. REQUEST_4XX_RESPONSE: 'rgba(255,96, 96, 1)',
  153. DIFFERENTIAL_INCREASE: [0.98, 0.2058, 0.4381],
  154. DIFFERENTIAL_DECREASE: [0.309, 0.2058, 0.98],
  155. COLOR_BUCKET: makeColorBucketTheme(LCH_LIGHT),
  156. COLOR_MAP: makeColorMap,
  157. STACK_TO_COLOR: makeStackToColor([0, 0, 0, 0.035]),
  158. FRAME_FALLBACK_COLOR: [0, 0, 0, 0.035],
  159. },
  160. FONTS: {
  161. FONT: MONOSPACE_FONT,
  162. FRAME_FONT,
  163. },
  164. };
  165. export const DarkFlamegraphTheme: FlamegraphTheme = {
  166. CONFIG: {
  167. HIGHLIGHT_RECURSION: false,
  168. },
  169. SIZES: {
  170. BAR_HEIGHT: 20,
  171. BAR_FONT_SIZE: 11,
  172. BAR_PADDING: 4,
  173. FLAMEGRAPH_DEPTH_OFFSET: 12,
  174. SPANS_DEPTH_OFFSET: 4,
  175. SPANS_FONT_SIZE: 10,
  176. SPANS_BAR_HEIGHT: 14,
  177. REQUEST_TAIL_HEIGHT: 8,
  178. REQUEST_BAR_HEIGHT: 14,
  179. REQUEST_FONT_SIZE: 10,
  180. REQUEST_DEPTH_OFFSET: 4,
  181. MINIMAP_POSITION_OVERLAY_BORDER_WIDTH: 2,
  182. MINIMAP_HEIGHT: 100,
  183. TIMELINE_HEIGHT: 20,
  184. LABEL_FONT_SIZE: 10,
  185. LABEL_FONT_PADDING: 6,
  186. FRAME_BORDER_WIDTH: 2,
  187. HOVERED_FRAME_BORDER_WIDTH: 1,
  188. TOOLTIP_FONT_SIZE: 12,
  189. GRID_LINE_WIDTH: 2,
  190. },
  191. COLORS: {
  192. LABEL_FONT_COLOR: 'rgba(255, 255, 255, 0.8)',
  193. BAR_LABEL_FONT_COLOR: 'rgb(255 255 255 / 80%)',
  194. GRID_LINE_COLOR: '#222227',
  195. GRID_FRAME_BACKGROUND_COLOR: 'rgba(0, 0, 0, 0.4)',
  196. SEARCH_RESULT_FRAME_COLOR: 'vec4(0.99, 0.70, 0.35, 0.7)',
  197. SELECTED_FRAME_BORDER_COLOR: '#3482ea',
  198. HIGHLIGHTED_LABEL_COLOR: [255, 255, 0],
  199. HOVERED_FRAME_BORDER_COLOR: 'rgba(255, 255, 255, 0.8)',
  200. CURSOR_CROSSHAIR: '#828285',
  201. SPAN_FRAME_BORDER: '#57575b',
  202. SPAN_FRAME_BACKGROUND: 'rgba(232, 232, 232, 0.2)',
  203. REQUEST_WAIT_TIME: `rgba(253,252,224, 1)`,
  204. REQUEST_DNS_TIME: `rgba(57, 146, 152, 1)`,
  205. REQUEST_TCP_TIME: `rgba(242, 146,57,1)`,
  206. REQUEST_SSL_TIME: `rgba(207,84,218, 1)`,
  207. REQUEST_2XX_RESPONSE: 'rgba(218, 231, 209, 1)',
  208. REQUEST_4XX_RESPONSE: 'rgba(255,96, 96, 1)',
  209. MINIMAP_POSITION_OVERLAY_COLOR: 'rgba(255,255,255,0.1)',
  210. MINIMAP_POSITION_OVERLAY_BORDER_COLOR: 'rgba(255,255,255, 0.2)',
  211. DIFFERENTIAL_INCREASE: [0.98, 0.2058, 0.4381],
  212. DIFFERENTIAL_DECREASE: [0.309, 0.2058, 0.98],
  213. COLOR_BUCKET: makeColorBucketTheme(LCH_DARK),
  214. COLOR_MAP: makeColorMap,
  215. STACK_TO_COLOR: makeStackToColor([1, 1, 1, 0.1]),
  216. FRAME_FALLBACK_COLOR: [1, 1, 1, 0.1],
  217. },
  218. FONTS: {
  219. FONT: MONOSPACE_FONT,
  220. FRAME_FONT,
  221. },
  222. };