@kylincloud/flamegraph 0.35.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/CHANGELOG.md +1211 -0
  2. package/LICENSE +202 -0
  3. package/README.md +251 -0
  4. package/dist/FlameGraph/FlameGraphComponent/CheckIcon.d.ts +2 -0
  5. package/dist/FlameGraph/FlameGraphComponent/CheckIcon.d.ts.map +1 -0
  6. package/dist/FlameGraph/FlameGraphComponent/ContextMenu.d.ts +17 -0
  7. package/dist/FlameGraph/FlameGraphComponent/ContextMenu.d.ts.map +1 -0
  8. package/dist/FlameGraph/FlameGraphComponent/ContextMenuHighlight.d.ts +14 -0
  9. package/dist/FlameGraph/FlameGraphComponent/ContextMenuHighlight.d.ts.map +1 -0
  10. package/dist/FlameGraph/FlameGraphComponent/DiffLegend.d.ts +9 -0
  11. package/dist/FlameGraph/FlameGraphComponent/DiffLegend.d.ts.map +1 -0
  12. package/dist/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.d.ts +8 -0
  13. package/dist/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.d.ts.map +1 -0
  14. package/dist/FlameGraph/FlameGraphComponent/Flamegraph.d.ts +96 -0
  15. package/dist/FlameGraph/FlameGraphComponent/Flamegraph.d.ts.map +1 -0
  16. package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts +27 -0
  17. package/dist/FlameGraph/FlameGraphComponent/Flamegraph_render.d.ts.map +1 -0
  18. package/dist/FlameGraph/FlameGraphComponent/GraphVizPane.d.ts +7 -0
  19. package/dist/FlameGraph/FlameGraphComponent/GraphVizPane.d.ts.map +1 -0
  20. package/dist/FlameGraph/FlameGraphComponent/Header.d.ts +12 -0
  21. package/dist/FlameGraph/FlameGraphComponent/Header.d.ts.map +1 -0
  22. package/dist/FlameGraph/FlameGraphComponent/Highlight.d.ts +18 -0
  23. package/dist/FlameGraph/FlameGraphComponent/Highlight.d.ts.map +1 -0
  24. package/dist/FlameGraph/FlameGraphComponent/LogoLink.d.ts +2 -0
  25. package/dist/FlameGraph/FlameGraphComponent/LogoLink.d.ts.map +1 -0
  26. package/dist/FlameGraph/FlameGraphComponent/color.d.ts +20 -0
  27. package/dist/FlameGraph/FlameGraphComponent/color.d.ts.map +1 -0
  28. package/dist/FlameGraph/FlameGraphComponent/colorPalette.d.ts +11 -0
  29. package/dist/FlameGraph/FlameGraphComponent/colorPalette.d.ts.map +1 -0
  30. package/dist/FlameGraph/FlameGraphComponent/constants.d.ts +6 -0
  31. package/dist/FlameGraph/FlameGraphComponent/constants.d.ts.map +1 -0
  32. package/dist/FlameGraph/FlameGraphComponent/index.d.ts +37 -0
  33. package/dist/FlameGraph/FlameGraphComponent/index.d.ts.map +1 -0
  34. package/dist/FlameGraph/FlameGraphComponent/murmur3.d.ts +2 -0
  35. package/dist/FlameGraph/FlameGraphComponent/murmur3.d.ts.map +1 -0
  36. package/dist/FlameGraph/FlameGraphComponent/testData.d.ts +53 -0
  37. package/dist/FlameGraph/FlameGraphComponent/testData.d.ts.map +1 -0
  38. package/dist/FlameGraph/FlameGraphComponent/utils.d.ts +6 -0
  39. package/dist/FlameGraph/FlameGraphComponent/utils.d.ts.map +1 -0
  40. package/dist/FlameGraph/FlameGraphComponent/viewTypes.d.ts +2 -0
  41. package/dist/FlameGraph/FlameGraphComponent/viewTypes.d.ts.map +1 -0
  42. package/dist/FlameGraph/FlameGraphRenderer.d.ts +86 -0
  43. package/dist/FlameGraph/FlameGraphRenderer.d.ts.map +1 -0
  44. package/dist/FlameGraph/decode.d.ts +27 -0
  45. package/dist/FlameGraph/decode.d.ts.map +1 -0
  46. package/dist/FlameGraph/normalize.d.ts +6 -0
  47. package/dist/FlameGraph/normalize.d.ts.map +1 -0
  48. package/dist/FlameGraph/uniqueness.d.ts +3 -0
  49. package/dist/FlameGraph/uniqueness.d.ts.map +1 -0
  50. package/dist/FlamegraphRenderer.d.ts +19 -0
  51. package/dist/FlamegraphRenderer.d.ts.map +1 -0
  52. package/dist/Icons.d.ts +9 -0
  53. package/dist/Icons.d.ts.map +1 -0
  54. package/dist/ProfilerTable.d.ts +21 -0
  55. package/dist/ProfilerTable.d.ts.map +1 -0
  56. package/dist/SharedQueryInput.d.ts +10 -0
  57. package/dist/SharedQueryInput.d.ts.map +1 -0
  58. package/dist/Toolbar.d.ts +31 -0
  59. package/dist/Toolbar.d.ts.map +1 -0
  60. package/dist/Tooltip/FlamegraphTooltip.d.ts +59 -0
  61. package/dist/Tooltip/FlamegraphTooltip.d.ts.map +1 -0
  62. package/dist/Tooltip/LeftClickIcon.d.ts +2 -0
  63. package/dist/Tooltip/LeftClickIcon.d.ts.map +1 -0
  64. package/dist/Tooltip/RightClickIcon.d.ts +2 -0
  65. package/dist/Tooltip/RightClickIcon.d.ts.map +1 -0
  66. package/dist/Tooltip/TableTooltip.d.ts +12 -0
  67. package/dist/Tooltip/TableTooltip.d.ts.map +1 -0
  68. package/dist/Tooltip/Tooltip.d.ts +29 -0
  69. package/dist/Tooltip/Tooltip.d.ts.map +1 -0
  70. package/dist/convert/convertJaegerTraceToProfile.d.ts +3 -0
  71. package/dist/convert/convertJaegerTraceToProfile.d.ts.map +1 -0
  72. package/dist/convert/diffTwoProfiles.d.ts +3 -0
  73. package/dist/convert/diffTwoProfiles.d.ts.map +1 -0
  74. package/dist/convert/flamebearersToTree.d.ts +11 -0
  75. package/dist/convert/flamebearersToTree.d.ts.map +1 -0
  76. package/dist/convert/sandwichViewProfiles.d.ts +14 -0
  77. package/dist/convert/sandwichViewProfiles.d.ts.map +1 -0
  78. package/dist/convert/subtract.d.ts +3 -0
  79. package/dist/convert/subtract.d.ts.map +1 -0
  80. package/dist/convert/testData.d.ts +50 -0
  81. package/dist/convert/testData.d.ts.map +1 -0
  82. package/dist/convert/toGraphviz.d.ts +3 -0
  83. package/dist/convert/toGraphviz.d.ts.map +1 -0
  84. package/dist/fitMode/fitMode.d.ts +42 -0
  85. package/dist/fitMode/fitMode.d.ts.map +1 -0
  86. package/dist/format/format.d.ts +42 -0
  87. package/dist/format/format.d.ts.map +1 -0
  88. package/dist/i18n.d.ts +55 -0
  89. package/dist/i18n.d.ts.map +1 -0
  90. package/dist/index.cjs.css +792 -0
  91. package/dist/index.cjs.js +5087 -0
  92. package/dist/index.d.ts +4 -0
  93. package/dist/index.d.ts.map +1 -0
  94. package/dist/index.esm.css +792 -0
  95. package/dist/index.esm.js +5079 -0
  96. package/dist/index.node.d.ts +9 -0
  97. package/dist/index.node.d.ts.map +1 -0
  98. package/dist/logo-v3-small-T5VXIMRR.svg +32 -0
  99. package/dist/models/decode.d.ts +3 -0
  100. package/dist/models/decode.d.ts.map +1 -0
  101. package/dist/models/flamebearer.d.ts +63 -0
  102. package/dist/models/flamebearer.d.ts.map +1 -0
  103. package/dist/models/groups.d.ts +37 -0
  104. package/dist/models/groups.d.ts.map +1 -0
  105. package/dist/models/index.d.ts +8 -0
  106. package/dist/models/index.d.ts.map +1 -0
  107. package/dist/models/profile.d.ts +152 -0
  108. package/dist/models/profile.d.ts.map +1 -0
  109. package/dist/models/spyName.d.ts +8 -0
  110. package/dist/models/spyName.d.ts.map +1 -0
  111. package/dist/models/trace.d.ts +357 -0
  112. package/dist/models/trace.d.ts.map +1 -0
  113. package/dist/models/units.d.ts +6 -0
  114. package/dist/models/units.d.ts.map +1 -0
  115. package/dist/search.d.ts +2 -0
  116. package/dist/search.d.ts.map +1 -0
  117. package/dist/shims/Box.d.ts +38 -0
  118. package/dist/shims/Box.d.ts.map +1 -0
  119. package/dist/shims/Button.d.ts +26 -0
  120. package/dist/shims/Button.d.ts.map +1 -0
  121. package/dist/shims/Dropdown.d.ts +30 -0
  122. package/dist/shims/Dropdown.d.ts.map +1 -0
  123. package/dist/shims/Input.d.ts +19 -0
  124. package/dist/shims/Input.d.ts.map +1 -0
  125. package/dist/shims/LoadingSpinner.d.ts +7 -0
  126. package/dist/shims/LoadingSpinner.d.ts.map +1 -0
  127. package/dist/shims/Menu.d.ts +4 -0
  128. package/dist/shims/Menu.d.ts.map +1 -0
  129. package/dist/shims/NoData.d.ts +2 -0
  130. package/dist/shims/NoData.d.ts.map +1 -0
  131. package/dist/shims/Table.d.ts +52 -0
  132. package/dist/shims/Table.d.ts.map +1 -0
  133. package/dist/shims/Tooltip.d.ts +9 -0
  134. package/dist/shims/Tooltip.d.ts.map +1 -0
  135. package/package.json +84 -0
  136. package/src/FlameGraph/FlameGraphComponent/CheckIcon.tsx +27 -0
  137. package/src/FlameGraph/FlameGraphComponent/ContextMenu.module.scss +10 -0
  138. package/src/FlameGraph/FlameGraphComponent/ContextMenu.spec.tsx +84 -0
  139. package/src/FlameGraph/FlameGraphComponent/ContextMenu.tsx +86 -0
  140. package/src/FlameGraph/FlameGraphComponent/ContextMenuHighlight.module.css +8 -0
  141. package/src/FlameGraph/FlameGraphComponent/ContextMenuHighlight.tsx +47 -0
  142. package/src/FlameGraph/FlameGraphComponent/DiffLegend.module.css +21 -0
  143. package/src/FlameGraph/FlameGraphComponent/DiffLegend.tsx +52 -0
  144. package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.module.css +40 -0
  145. package/src/FlameGraph/FlameGraphComponent/DiffLegendPaletteDropdown.tsx +129 -0
  146. package/src/FlameGraph/FlameGraphComponent/Flamegraph.spec.ts +552 -0
  147. package/src/FlameGraph/FlameGraphComponent/Flamegraph.ts +446 -0
  148. package/src/FlameGraph/FlameGraphComponent/Flamegraph_render.spec.tsx +233 -0
  149. package/src/FlameGraph/FlameGraphComponent/Flamegraph_render.ts +478 -0
  150. package/src/FlameGraph/FlameGraphComponent/GraphVizPane.tsx +56 -0
  151. package/src/FlameGraph/FlameGraphComponent/GraphVizPanel.module.scss +55 -0
  152. package/src/FlameGraph/FlameGraphComponent/Header.module.css +27 -0
  153. package/src/FlameGraph/FlameGraphComponent/Header.tsx +71 -0
  154. package/src/FlameGraph/FlameGraphComponent/Highlight.module.css +7 -0
  155. package/src/FlameGraph/FlameGraphComponent/Highlight.spec.tsx +53 -0
  156. package/src/FlameGraph/FlameGraphComponent/Highlight.tsx +94 -0
  157. package/src/FlameGraph/FlameGraphComponent/LogoLink.module.scss +10 -0
  158. package/src/FlameGraph/FlameGraphComponent/LogoLink.tsx +101 -0
  159. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-collapses-small-blocks-into-one-1-snap.png +0 -0
  160. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-diff-mode-1-snap.png +0 -0
  161. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-highlighted-flamegraph-1-snap.png +0 -0
  162. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-normal-flamegraph-1-snap.png +0 -0
  163. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/canvas-renderer-spec-tsx-canvas-renderer-group-snapshot-works-with-selected-node-1-snap.png +0 -0
  164. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-also-zooms-1-snap.png +0 -0
  165. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-in-the-beginning-1-snap.png +0 -0
  166. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-when-node-is-not-in-the-beginning-1-snap.png +0 -0
  167. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-focused-renders-a-focused-node-zoom-top-level-1-snap.png +0 -0
  168. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-complex-flamegraph-1-snap.png +0 -0
  169. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-double-diff-flamegraph-1-snap.png +0 -0
  170. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-highlighted-double-flamegraph-1-snap.png +0 -0
  171. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-highlighted-flamegraph-1-snap.png +0 -0
  172. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-simple-flamegraph-1-snap.png +0 -0
  173. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-simple-tree-1-snap.png +0 -0
  174. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-zoomed-flamegraph-1-snap.png +0 -0
  175. package/src/FlameGraph/FlameGraphComponent/__image_snapshots__/flamegraph-render-spec-tsx-render-group-snapshot-renders-a-zoomed-with-fit-mode-tail-1-snap.png +0 -0
  176. package/src/FlameGraph/FlameGraphComponent/canvas.module.css +6 -0
  177. package/src/FlameGraph/FlameGraphComponent/color.spec.ts +308 -0
  178. package/src/FlameGraph/FlameGraphComponent/color.ts +167 -0
  179. package/src/FlameGraph/FlameGraphComponent/colorPalette.ts +58 -0
  180. package/src/FlameGraph/FlameGraphComponent/constants.ts +5 -0
  181. package/src/FlameGraph/FlameGraphComponent/index.spec.tsx +291 -0
  182. package/src/FlameGraph/FlameGraphComponent/index.tsx +411 -0
  183. package/src/FlameGraph/FlameGraphComponent/murmur3.ts +97 -0
  184. package/src/FlameGraph/FlameGraphComponent/styles.module.scss +10 -0
  185. package/src/FlameGraph/FlameGraphComponent/testData.ts +427 -0
  186. package/src/FlameGraph/FlameGraphComponent/utils.ts +31 -0
  187. package/src/FlameGraph/FlameGraphComponent/viewTypes.ts +6 -0
  188. package/src/FlameGraph/FlameGraphRenderer.tsx +603 -0
  189. package/src/FlameGraph/FlamegraphRenderer.module.scss +93 -0
  190. package/src/FlameGraph/decode.ts +78 -0
  191. package/src/FlameGraph/normalize.spec.ts +76 -0
  192. package/src/FlameGraph/normalize.ts +60 -0
  193. package/src/FlameGraph/testData.json +423 -0
  194. package/src/FlameGraph/uniqueness.spec.ts +16 -0
  195. package/src/FlameGraph/uniqueness.ts +84 -0
  196. package/src/FlamegraphRenderer.tsx +61 -0
  197. package/src/Icons.tsx +74 -0
  198. package/src/ProfilerTable.tsx +527 -0
  199. package/src/SharedQueryInput.module.scss +82 -0
  200. package/src/SharedQueryInput.tsx +127 -0
  201. package/src/Toolbar.module.scss +117 -0
  202. package/src/Toolbar.spec.tsx +217 -0
  203. package/src/Toolbar.tsx +471 -0
  204. package/src/Tooltip/FlamegraphTooltip.spec.tsx +81 -0
  205. package/src/Tooltip/FlamegraphTooltip.tsx +257 -0
  206. package/src/Tooltip/LeftClickIcon.tsx +18 -0
  207. package/src/Tooltip/RightClickIcon.tsx +18 -0
  208. package/src/Tooltip/TableTooltip.spec.tsx +44 -0
  209. package/src/Tooltip/TableTooltip.tsx +145 -0
  210. package/src/Tooltip/Tooltip.module.scss +71 -0
  211. package/src/Tooltip/Tooltip.spec.tsx +395 -0
  212. package/src/Tooltip/Tooltip.tsx +336 -0
  213. package/src/__snapshots__/Toolbar.spec.tsx.snap +297 -0
  214. package/src/convert/convertJaegerTraceToProfile.ts +97 -0
  215. package/src/convert/diffTwoProfiles.ts +81 -0
  216. package/src/convert/flamebearersToTree.ts +78 -0
  217. package/src/convert/sandwichViewProfiles.spec.ts +65 -0
  218. package/src/convert/sandwichViewProfiles.ts +191 -0
  219. package/src/convert/subtract.ts +87 -0
  220. package/src/convert/testData.ts +145 -0
  221. package/src/convert/toGraphviz.ts +485 -0
  222. package/src/fitMode/fitMode.spec.ts +93 -0
  223. package/src/fitMode/fitMode.ts +122 -0
  224. package/src/format/format.spec.ts +291 -0
  225. package/src/format/format.ts +303 -0
  226. package/src/globals.d.ts +13 -0
  227. package/src/i18n.tsx +293 -0
  228. package/src/index.node.ts +19 -0
  229. package/src/index.spec.tsx +383 -0
  230. package/src/index.tsx +10 -0
  231. package/src/logo-v3-small.svg +32 -0
  232. package/src/models/decode.ts +45 -0
  233. package/src/models/flamebearer.ts +86 -0
  234. package/src/models/groups.ts +14 -0
  235. package/src/models/index.ts +7 -0
  236. package/src/models/profile.spec.ts +32 -0
  237. package/src/models/profile.ts +48 -0
  238. package/src/models/spyName.spec.ts +18 -0
  239. package/src/models/spyName.ts +32 -0
  240. package/src/models/trace.ts +45 -0
  241. package/src/models/units.spec.ts +21 -0
  242. package/src/models/units.ts +24 -0
  243. package/src/sass/_common.scss +206 -0
  244. package/src/sass/_css-variables.scss +201 -0
  245. package/src/sass/_mixins.scss +15 -0
  246. package/src/sass/_sanitize.scss +407 -0
  247. package/src/sass/_variables.scss +53 -0
  248. package/src/sass/flamegraph.scss +18 -0
  249. package/src/search.spec.ts +11 -0
  250. package/src/search.ts +4 -0
  251. package/src/shameful-any.d.ts +2 -0
  252. package/src/shims/Box.module.scss +57 -0
  253. package/src/shims/Box.tsx +105 -0
  254. package/src/shims/Button.module.scss +129 -0
  255. package/src/shims/Button.tsx +128 -0
  256. package/src/shims/Dropdown.module.scss +63 -0
  257. package/src/shims/Dropdown.tsx +96 -0
  258. package/src/shims/Input.module.scss +15 -0
  259. package/src/shims/Input.tsx +55 -0
  260. package/src/shims/LoadingSpinner.tsx +19 -0
  261. package/src/shims/Menu.tsx +9 -0
  262. package/src/shims/NoData.module.scss +6 -0
  263. package/src/shims/NoData.tsx +11 -0
  264. package/src/shims/Table.module.scss +82 -0
  265. package/src/shims/Table.spec.tsx +121 -0
  266. package/src/shims/Table.tsx +252 -0
  267. package/src/shims/Tooltip.tsx +51 -0
@@ -0,0 +1,411 @@
1
+ // src/FlameGraph/FlameGraphComponent/index.tsx
2
+ /* eslint-disable no-unused-expressions, import/no-extraneous-dependencies */
3
+ import React, { useCallback, useRef } from 'react';
4
+ import clsx from 'clsx';
5
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
6
+ import { faRedo } from '@fortawesome/free-solid-svg-icons/faRedo';
7
+ import { faCopy } from '@fortawesome/free-solid-svg-icons/faCopy';
8
+ import { faHighlighter } from '@fortawesome/free-solid-svg-icons/faHighlighter';
9
+ import { faCompressAlt } from '@fortawesome/free-solid-svg-icons/faCompressAlt';
10
+ import { MenuItem } from '../../shims/Menu';
11
+ import useResizeObserver from '@react-hook/resize-observer';
12
+ import { Maybe } from 'true-myth';
13
+ import debounce from 'lodash.debounce';
14
+ import { Flamebearer } from '../../models';
15
+ import styles from './canvas.module.css';
16
+ import Flamegraph from './Flamegraph';
17
+ import Highlight from './Highlight';
18
+ import ContextMenuHighlight from './ContextMenuHighlight';
19
+ import FlamegraphTooltip from '../../Tooltip/FlamegraphTooltip';
20
+ import ContextMenu from './ContextMenu';
21
+ import LogoLink from './LogoLink';
22
+ import { SandwichIcon, HeadFirstIcon, TailFirstIcon } from '../../Icons';
23
+ import { PX_PER_LEVEL } from './constants';
24
+ import Header from './Header';
25
+ import { FlamegraphPalette } from './colorPalette';
26
+ import type { ViewTypes } from './viewTypes';
27
+ import { FitModes, HeadMode, TailMode } from '../../fitMode/fitMode';
28
+ import indexStyles from './styles.module.scss';
29
+ import { useFlamegraphI18n } from '../../i18n';
30
+
31
+ interface FlamegraphProps {
32
+ flamebearer: Flamebearer;
33
+ focusedNode: ConstructorParameters<typeof Flamegraph>[2];
34
+ fitMode: ConstructorParameters<typeof Flamegraph>[3];
35
+ updateFitMode: (f: FitModes) => void;
36
+ highlightQuery: ConstructorParameters<typeof Flamegraph>[4];
37
+ zoom: ConstructorParameters<typeof Flamegraph>[5];
38
+ showCredit: boolean;
39
+ selectedItem: Maybe<string>;
40
+
41
+ onZoom: (bar: Maybe<{ i: number; j: number }>) => void;
42
+ onFocusOnNode: (i: number, j: number) => void;
43
+ setActiveItem: (item: { name: string }) => void;
44
+ updateView?: (v: ViewTypes) => void;
45
+
46
+ onReset: () => void;
47
+ isDirty: () => boolean;
48
+
49
+ ['data-testid']?: string;
50
+ palette: FlamegraphPalette;
51
+ setPalette: (p: FlamegraphPalette) => void;
52
+ toolbarVisible?: boolean;
53
+ headerVisible?: boolean;
54
+ disableClick?: boolean;
55
+ showSingleLevel?: boolean;
56
+ }
57
+
58
+ export default function FlameGraphComponent(props: FlamegraphProps) {
59
+ const canvasRef = React.useRef<HTMLCanvasElement>(null);
60
+ const flamegraph = useRef<Flamegraph>();
61
+ const i18n = useFlamegraphI18n();
62
+
63
+ const [rightClickedNode, setRightClickedNode] = React.useState<
64
+ Maybe<{ top: number; left: number; width: number }>
65
+ >(Maybe.nothing());
66
+
67
+ const {
68
+ flamebearer,
69
+ focusedNode,
70
+ fitMode,
71
+ updateFitMode,
72
+ highlightQuery,
73
+ zoom,
74
+ toolbarVisible,
75
+ headerVisible = true,
76
+ disableClick = false,
77
+ showSingleLevel = false,
78
+ showCredit,
79
+ setActiveItem,
80
+ selectedItem,
81
+ updateView,
82
+ } = props;
83
+
84
+ const { onZoom, onReset, isDirty, onFocusOnNode } = props;
85
+ const { 'data-testid': dataTestId } = props;
86
+ const { palette, setPalette } = props;
87
+
88
+ const debouncedRenderCanvas = useCallback(
89
+ debounce(() => {
90
+ renderCanvas();
91
+ }, 50),
92
+ []
93
+ );
94
+
95
+ useResizeObserver(canvasRef, () => {
96
+ if (flamegraph) {
97
+ debouncedRenderCanvas();
98
+ }
99
+ });
100
+
101
+ const onClick = (e: React.MouseEvent<HTMLCanvasElement>) => {
102
+ const opt = getFlamegraph().xyToBar(
103
+ e.nativeEvent.offsetX,
104
+ e.nativeEvent.offsetY
105
+ );
106
+
107
+ opt.match({
108
+ Nothing: () => {},
109
+ Just: (bar) => {
110
+ zoom.match({
111
+ Nothing: () => {
112
+ onZoom(opt);
113
+ },
114
+ Just: (z) => {
115
+ if (bar.i === z.i && bar.j === z.j) {
116
+ onZoom(Maybe.nothing());
117
+ } else {
118
+ onZoom(opt);
119
+ }
120
+ },
121
+ });
122
+ },
123
+ });
124
+ };
125
+
126
+ const xyToHighlightData = (x: number, y: number) => {
127
+ const opt = getFlamegraph().xyToBar(x, y);
128
+
129
+ return opt.map((bar) => {
130
+ return {
131
+ left: getCanvas().offsetLeft + bar.x,
132
+ top: getCanvas().offsetTop + bar.y,
133
+ width: bar.width,
134
+ };
135
+ });
136
+ };
137
+
138
+ const xyToTooltipData = (x: number, y: number) => {
139
+ return getFlamegraph().xyToBar(x, y);
140
+ };
141
+
142
+ const onContextMenuClose = () => {
143
+ setRightClickedNode(Maybe.nothing());
144
+ };
145
+
146
+ const onContextMenuOpen = (x: number, y: number) => {
147
+ setRightClickedNode(xyToHighlightData(x, y));
148
+ };
149
+
150
+ const xyToContextMenuItems = useCallback(
151
+ (x: number, y: number) => {
152
+ const dirty = isDirty();
153
+ const bar = getFlamegraph().xyToBar(x, y);
154
+ const barName = bar.isJust ? bar.value.name : '';
155
+
156
+ const CollapseItem = () => {
157
+ const hoveredOnValidNode = bar.mapOrElse(
158
+ () => false,
159
+ () => true
160
+ );
161
+
162
+ const onClick = bar.mapOrElse(
163
+ () => () => {},
164
+ (f) => onFocusOnNode.bind(null, f.i, f.j)
165
+ );
166
+
167
+ return (
168
+ <MenuItem
169
+ key="focus"
170
+ disabled={!hoveredOnValidNode}
171
+ onClick={onClick}
172
+ >
173
+ <FontAwesomeIcon icon={faCompressAlt} />
174
+ {i18n.collapseNodesAbove}
175
+ </MenuItem>
176
+ );
177
+ };
178
+
179
+ const CopyItem = () => {
180
+ const onClick = () => {
181
+ if (!navigator.clipboard) return;
182
+
183
+ navigator.clipboard.writeText(barName);
184
+ };
185
+
186
+ return (
187
+ <MenuItem key="copy" onClick={onClick}>
188
+ <FontAwesomeIcon icon={faCopy} />
189
+ {i18n.copyFunctionName}
190
+ </MenuItem>
191
+ );
192
+ };
193
+
194
+ const HighlightSimilarNodesItem = () => {
195
+ const onClick = () => {
196
+ setActiveItem({ name: barName });
197
+ };
198
+
199
+ const actionName =
200
+ selectedItem.isJust && selectedItem.value === barName
201
+ ? i18n.clearHighlight
202
+ : i18n.highlightSimilarNodes;
203
+
204
+ return (
205
+ <MenuItem key="highlight-similar-nodes" onClick={onClick}>
206
+ <FontAwesomeIcon icon={faHighlighter} />
207
+ {actionName}
208
+ </MenuItem>
209
+ );
210
+ };
211
+
212
+ const OpenInSandwichViewItem = () => {
213
+ if (!updateView) {
214
+ return null;
215
+ }
216
+
217
+ const handleClick = () => {
218
+ if (updateView) {
219
+ updateView('sandwich');
220
+ setActiveItem({ name: barName });
221
+ }
222
+ };
223
+
224
+ return (
225
+ <MenuItem
226
+ key="open-in-sandwich-view"
227
+ className={indexStyles.sandwichItem}
228
+ onClick={handleClick}
229
+ >
230
+ <SandwichIcon fill="black" />
231
+ {i18n.openInSandwichView}
232
+ </MenuItem>
233
+ );
234
+ };
235
+
236
+ const FitModeItem = () => {
237
+ const isHeadFirst = fitMode === HeadMode;
238
+
239
+ const handleClick = () => {
240
+ const newValues = isHeadFirst ? TailMode : HeadMode;
241
+ updateFitMode(newValues);
242
+ };
243
+
244
+ return (
245
+ <MenuItem
246
+ className={indexStyles.fitModeItem}
247
+ key="fit-mode"
248
+ onClick={handleClick}
249
+ >
250
+ {isHeadFirst ? <TailFirstIcon /> : <HeadFirstIcon />}
251
+ {isHeadFirst ? i18n.showTextTailFirst : i18n.showTextHeadFirst}
252
+ </MenuItem>
253
+ );
254
+ };
255
+
256
+ return [
257
+ <MenuItem key="reset" disabled={!dirty} onClick={onReset}>
258
+ <FontAwesomeIcon icon={faRedo} />
259
+ {i18n.resetView}
260
+ </MenuItem>,
261
+ CollapseItem(),
262
+ CopyItem(),
263
+ HighlightSimilarNodesItem(),
264
+ OpenInSandwichViewItem(),
265
+ FitModeItem(),
266
+ ].filter(Boolean) as JSX.Element[];
267
+ },
268
+ [
269
+ flamegraph,
270
+ selectedItem,
271
+ fitMode,
272
+ isDirty,
273
+ onReset,
274
+ onFocusOnNode,
275
+ setActiveItem,
276
+ updateView,
277
+ i18n,
278
+ ]
279
+ );
280
+
281
+ const constructCanvas = () => {
282
+ if (canvasRef.current) {
283
+ const f = new Flamegraph(
284
+ flamebearer,
285
+ canvasRef.current,
286
+ focusedNode,
287
+ fitMode,
288
+ highlightQuery,
289
+ zoom,
290
+ palette
291
+ );
292
+
293
+ flamegraph.current = f;
294
+ }
295
+ };
296
+
297
+ React.useEffect(() => {
298
+ constructCanvas();
299
+ renderCanvas();
300
+ }, [palette]);
301
+
302
+ React.useEffect(() => {
303
+ constructCanvas();
304
+ renderCanvas();
305
+ }, [
306
+ canvasRef.current,
307
+ flamebearer,
308
+ focusedNode,
309
+ fitMode,
310
+ highlightQuery,
311
+ zoom,
312
+ ]);
313
+
314
+ const renderCanvas = () => {
315
+ canvasRef?.current?.setAttribute('data-state', 'rendering');
316
+ flamegraph?.current?.render();
317
+ canvasRef?.current?.setAttribute('data-state', 'rendered');
318
+ };
319
+
320
+ const dataUnavailable =
321
+ !flamebearer || (flamebearer && flamebearer.names.length <= 1);
322
+
323
+ const getCanvas = () => {
324
+ if (!canvasRef.current) {
325
+ throw new Error('Missing canvas');
326
+ }
327
+ return canvasRef.current;
328
+ };
329
+
330
+ const getFlamegraph = () => {
331
+ if (!flamegraph.current) {
332
+ throw new Error('Missing canvas');
333
+ }
334
+ return flamegraph.current;
335
+ };
336
+
337
+ return (
338
+ <div
339
+ data-testid="flamegraph-view"
340
+ className={clsx(indexStyles.flamegraphPane, {
341
+ 'vertical-orientation': flamebearer.format === 'double',
342
+ })}
343
+ >
344
+ {headerVisible && (
345
+ <Header
346
+ format={flamebearer.format}
347
+ units={flamebearer.units}
348
+ palette={palette}
349
+ setPalette={setPalette}
350
+ toolbarVisible={toolbarVisible}
351
+ />
352
+ )}
353
+ <div
354
+ data-testid={dataTestId}
355
+ style={{
356
+ opacity: dataUnavailable && !showSingleLevel ? 0 : 1,
357
+ }}
358
+ >
359
+ <canvas
360
+ height="0"
361
+ data-testid="flamegraph-canvas"
362
+ data-highlightquery={highlightQuery}
363
+ className={clsx('flamegraph-canvas', styles.canvas)}
364
+ ref={canvasRef}
365
+ onClick={!disableClick ? onClick : undefined}
366
+ />
367
+ </div>
368
+ {showCredit ? <LogoLink /> : ''}
369
+ {flamegraph && canvasRef && (
370
+ <Highlight
371
+ barHeight={PX_PER_LEVEL}
372
+ canvasRef={canvasRef}
373
+ zoom={zoom}
374
+ xyToHighlightData={xyToHighlightData}
375
+ />
376
+ )}
377
+ {flamegraph && (
378
+ <ContextMenuHighlight
379
+ barHeight={PX_PER_LEVEL}
380
+ node={rightClickedNode}
381
+ />
382
+ )}
383
+ {flamegraph && (
384
+ <FlamegraphTooltip
385
+ format={flamebearer.format}
386
+ canvasRef={canvasRef}
387
+ xyToData={xyToTooltipData as ShamefulAny}
388
+ numTicks={flamebearer.numTicks}
389
+ sampleRate={flamebearer.sampleRate}
390
+ leftTicks={
391
+ flamebearer.format === 'double' ? flamebearer.leftTicks : 0
392
+ }
393
+ rightTicks={
394
+ flamebearer.format === 'double' ? flamebearer.rightTicks : 0
395
+ }
396
+ units={flamebearer.units}
397
+ palette={palette}
398
+ />
399
+ )}
400
+
401
+ {!disableClick && flamegraph && canvasRef && (
402
+ <ContextMenu
403
+ canvasRef={canvasRef}
404
+ xyToMenuItems={xyToContextMenuItems}
405
+ onClose={onContextMenuClose}
406
+ onOpen={onContextMenuOpen}
407
+ />
408
+ )}
409
+ </div>
410
+ );
411
+ }
@@ -0,0 +1,97 @@
1
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
+ // @ts-nocheck
3
+ /* eslint-disable @typescript-eslint/restrict-plus-operands */
4
+ /*
5
+
6
+ Copyright (c) 2011 Gary Court
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13
+
14
+ */
15
+
16
+ /* eslint-disable no-plusplus */
17
+ /* eslint-disable prefer-const */
18
+ /* eslint-disable no-bitwise */
19
+ /* eslint-disable camelcase */
20
+
21
+ export default function murmurhash3_32_gc(key: string, seed = 0) {
22
+ let remainder;
23
+ let bytes;
24
+ let h1;
25
+ let h1b;
26
+ let c1;
27
+ let c2;
28
+ let k1;
29
+ let i;
30
+
31
+ remainder = key.length & 3; // key.length % 4
32
+ bytes = key.length - remainder;
33
+ h1 = seed;
34
+ c1 = 0xcc9e2d51;
35
+ c2 = 0x1b873593;
36
+ i = 0;
37
+
38
+ while (i < bytes) {
39
+ k1 =
40
+ (key.charCodeAt(i) & 0xff) |
41
+ ((key.charCodeAt(++i) & 0xff) << 8) |
42
+ ((key.charCodeAt(++i) & 0xff) << 16) |
43
+ ((key.charCodeAt(++i) & 0xff) << 24);
44
+ ++i;
45
+
46
+ k1 =
47
+ ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) & 0xffffffff;
48
+ k1 = (k1 << 15) | (k1 >>> 17);
49
+ k1 =
50
+ ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) & 0xffffffff;
51
+
52
+ h1 ^= k1;
53
+ h1 = (h1 << 13) | (h1 >>> 19);
54
+ h1b =
55
+ ((h1 & 0xffff) * 5 + ((((h1 >>> 16) * 5) & 0xffff) << 16)) & 0xffffffff;
56
+ h1 = (h1b & 0xffff) + 0x6b64 + ((((h1b >>> 16) + 0xe654) & 0xffff) << 16);
57
+ }
58
+
59
+ k1 = 0;
60
+
61
+ switch (remainder) {
62
+ case 3:
63
+ k1 ^= (key.charCodeAt(i + 2) & 0xff) << 16;
64
+ // fall through
65
+ case 2:
66
+ k1 ^= (key.charCodeAt(i + 1) & 0xff) << 8;
67
+ // fall through
68
+ case 1:
69
+ k1 ^= key.charCodeAt(i) & 0xff;
70
+ // fall through
71
+ default:
72
+ k1 =
73
+ ((k1 & 0xffff) * c1 + ((((k1 >>> 16) * c1) & 0xffff) << 16)) &
74
+ 0xffffffff;
75
+ k1 = (k1 << 15) | (k1 >>> 17);
76
+ k1 =
77
+ ((k1 & 0xffff) * c2 + ((((k1 >>> 16) * c2) & 0xffff) << 16)) &
78
+ 0xffffffff;
79
+ h1 ^= k1;
80
+ }
81
+
82
+ h1 ^= key.length;
83
+
84
+ h1 ^= h1 >>> 16;
85
+ h1 =
86
+ ((h1 & 0xffff) * 0x85ebca6b +
87
+ ((((h1 >>> 16) * 0x85ebca6b) & 0xffff) << 16)) &
88
+ 0xffffffff;
89
+ h1 ^= h1 >>> 13;
90
+ h1 =
91
+ ((h1 & 0xffff) * 0xc2b2ae35 +
92
+ ((((h1 >>> 16) * 0xc2b2ae35) & 0xffff) << 16)) &
93
+ 0xffffffff;
94
+ h1 ^= h1 >>> 16;
95
+
96
+ return h1 >>> 0;
97
+ }
@@ -0,0 +1,10 @@
1
+ .flamegraphPane {
2
+ flex: 1;
3
+ position: relative;
4
+
5
+ .fitModeItem svg,
6
+ .sandwichItem svg {
7
+ width: 1em;
8
+ margin-right: 10px;
9
+ }
10
+ }