@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,257 @@
1
+ import React, { useCallback, RefObject, Dispatch, SetStateAction } from 'react';
2
+ import { Maybe } from 'true-myth';
3
+ import type { Unwrapped } from 'true-myth/maybe';
4
+ import { Units } from '../models/units';
5
+ import {
6
+ getFormatter,
7
+ numberWithCommas,
8
+ formatPercent,
9
+ ratioToPercent,
10
+ diffPercent,
11
+ } from '../format/format';
12
+ import {
13
+ FlamegraphPalette,
14
+ DefaultPalette,
15
+ } from '../FlameGraph/FlameGraphComponent/colorPalette';
16
+
17
+ import { Tooltip, TooltipData } from './Tooltip';
18
+
19
+ type xyToDataSingle = (
20
+ x: number,
21
+ y: number
22
+ ) => Maybe<{ format: 'single'; name: string; total: number }>;
23
+
24
+ type xyToDataDouble = (
25
+ x: number,
26
+ y: number
27
+ ) => Maybe<{
28
+ format: 'double';
29
+ name: string;
30
+ totalLeft: number;
31
+ totalRight: number;
32
+ barTotal: number;
33
+ }>;
34
+
35
+ export type FlamegraphTooltipProps = {
36
+ canvasRef: RefObject<HTMLCanvasElement>;
37
+
38
+ units: Units;
39
+ sampleRate: number;
40
+ numTicks: number;
41
+ leftTicks: number;
42
+ rightTicks: number;
43
+
44
+ palette: FlamegraphPalette;
45
+ } & (
46
+ | { format: 'single'; xyToData: xyToDataSingle }
47
+ | {
48
+ format: 'double';
49
+ leftTicks: number;
50
+ rightTicks: number;
51
+ xyToData: xyToDataDouble;
52
+ }
53
+ );
54
+
55
+ export default function FlamegraphTooltip(props: FlamegraphTooltipProps) {
56
+ const {
57
+ format,
58
+ canvasRef,
59
+ xyToData,
60
+ numTicks,
61
+ sampleRate,
62
+ units,
63
+ leftTicks,
64
+ rightTicks,
65
+ palette,
66
+ } = props;
67
+
68
+ const setTooltipContent = useCallback(
69
+ (
70
+ setContent: Dispatch<
71
+ SetStateAction<{
72
+ title: {
73
+ text: string;
74
+ diff: {
75
+ text: string;
76
+ color: string;
77
+ };
78
+ };
79
+ tooltipData: TooltipData[];
80
+ }>
81
+ >,
82
+ onMouseOut: () => void,
83
+ e: MouseEvent
84
+ ) => {
85
+ const formatter = getFormatter(numTicks, sampleRate, units);
86
+ const opt = xyToData(e.offsetX, e.offsetY);
87
+
88
+ let data: Unwrapped<typeof opt>;
89
+
90
+ // waiting on
91
+ // https://github.com/true-myth/true-myth/issues/279
92
+ if (opt.isJust) {
93
+ data = opt.value;
94
+ } else {
95
+ onMouseOut();
96
+ return;
97
+ }
98
+
99
+ // set the content for tooltip
100
+ switch (data.format) {
101
+ case 'single': {
102
+ const newLeftContent: TooltipData = {
103
+ percent: formatPercent(data.total / numTicks),
104
+ samples:
105
+ units === 'trace_samples' ? '' : numberWithCommas(data.total),
106
+ units,
107
+ formattedValue: formatter.format(data.total, sampleRate),
108
+ tooltipType: 'flamegraph',
109
+ };
110
+ setContent({
111
+ title: {
112
+ text: data.name,
113
+ diff: {
114
+ text: '',
115
+ color: '',
116
+ },
117
+ },
118
+ tooltipData: [newLeftContent],
119
+ });
120
+
121
+ break;
122
+ }
123
+
124
+ case 'double': {
125
+ if (format === 'single') {
126
+ throw new Error(
127
+ "props format is 'single' but it has been mapped to 'double'"
128
+ );
129
+ }
130
+
131
+ const d = formatDouble(
132
+ {
133
+ formatter,
134
+ sampleRate,
135
+ totalLeft: data.totalLeft,
136
+ leftTicks,
137
+ totalRight: data.totalRight,
138
+ rightTicks,
139
+ title: data.name,
140
+ units,
141
+ },
142
+ palette
143
+ );
144
+
145
+ setContent({
146
+ title: d.title,
147
+ tooltipData: d.tooltipData,
148
+ });
149
+
150
+ break;
151
+ }
152
+ default:
153
+ throw new Error(`Unsupported format:'`);
154
+ }
155
+ },
156
+ [numTicks, sampleRate, units, leftTicks, rightTicks, palette]
157
+ );
158
+
159
+ return (
160
+ <Tooltip
161
+ dataSourceRef={canvasRef}
162
+ clickInfoSide="right"
163
+ setTooltipContent={setTooltipContent}
164
+ />
165
+ );
166
+ }
167
+
168
+ interface Formatter {
169
+ format(samples: number, sampleRate: number): string;
170
+ }
171
+
172
+ export function formatDouble(
173
+ {
174
+ formatter,
175
+ sampleRate,
176
+ totalLeft,
177
+ leftTicks,
178
+ totalRight,
179
+ rightTicks,
180
+ title,
181
+ units,
182
+ }: {
183
+ formatter: Formatter;
184
+ sampleRate: number;
185
+ totalLeft: number;
186
+ leftTicks: number;
187
+ totalRight: number;
188
+ rightTicks: number;
189
+ title: string;
190
+ units: Units;
191
+ },
192
+ palette: FlamegraphPalette = DefaultPalette
193
+ ): {
194
+ tooltipData: TooltipData[];
195
+ title: {
196
+ text: string;
197
+ diff: {
198
+ text: string;
199
+ color: string;
200
+ };
201
+ };
202
+ } {
203
+ const leftRatio = totalLeft / leftTicks;
204
+ const rightRatio = totalRight / rightTicks;
205
+
206
+ const leftPercent = ratioToPercent(leftRatio);
207
+ const rightPercent = ratioToPercent(rightRatio);
208
+
209
+ const newLeft: TooltipData = {
210
+ percent: `${leftPercent}%`,
211
+ samples: numberWithCommas(totalLeft),
212
+ units,
213
+ formattedValue: formatter.format(totalLeft, sampleRate),
214
+ tooltipType: 'flamegraph',
215
+ };
216
+
217
+ const newRight: TooltipData = {
218
+ percent: `${rightPercent}%`,
219
+ samples: numberWithCommas(totalRight),
220
+ units,
221
+ formattedValue: formatter.format(totalRight, sampleRate),
222
+ tooltipType: 'flamegraph',
223
+ };
224
+
225
+ const totalDiff = diffPercent(leftPercent, rightPercent);
226
+
227
+ let tooltipDiffColor = '';
228
+ if (totalDiff > 0) {
229
+ tooltipDiffColor = palette.badColor.rgb().string();
230
+ } else if (totalDiff < 0) {
231
+ tooltipDiffColor = palette.goodColor.rgb().string();
232
+ }
233
+
234
+ let tooltipDiffText = '';
235
+ if (!totalLeft) {
236
+ // this is a new function
237
+ tooltipDiffText = '(new)';
238
+ } else if (!totalRight) {
239
+ // this function has been removed
240
+ tooltipDiffText = '(removed)';
241
+ } else if (totalDiff > 0) {
242
+ tooltipDiffText = `(+${totalDiff.toFixed(2)}%)`;
243
+ } else if (totalDiff < 0) {
244
+ tooltipDiffText = `(${totalDiff.toFixed(2)}%)`;
245
+ }
246
+
247
+ return {
248
+ title: {
249
+ text: title,
250
+ diff: {
251
+ text: tooltipDiffText,
252
+ color: tooltipDiffColor,
253
+ },
254
+ },
255
+ tooltipData: [newLeft, newRight],
256
+ };
257
+ }
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+
3
+ export default function LeftClickIcon() {
4
+ return (
5
+ <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
6
+ <defs />
7
+ <path
8
+ style={{ fill: '#7d7d7f' }}
9
+ d="M24,19.56c0,5.22-3.54,9.44-7.92,9.44h-3.17c-4.37,0-7.92-4.23-7.92-9.44v-7.56H24v7.56Z"
10
+ />
11
+ <path
12
+ style={{ fill: '#7d7d7f' }}
13
+ d="M15,1h.82c4.52,0,8.18,3.73,8.18,8.33v1.67H15V1Z"
14
+ />
15
+ <path d="M13.18,1h.82V11H5v-1.67c0-4.6,3.66-8.33,8.18-8.33Z" />
16
+ </svg>
17
+ );
18
+ }
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+
3
+ export default function RightClickIcon() {
4
+ return (
5
+ <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 30 30">
6
+ <defs />
7
+ <path
8
+ style={{ fill: '#7d7d7f' }}
9
+ d="M5,19.56c0,5.22,3.54,9.44,7.92,9.44h3.17c4.37,0,7.92-4.23,7.92-9.44v-7.56H5v7.56Z"
10
+ />
11
+ <path
12
+ style={{ fill: '#7d7d7f' }}
13
+ d="M14,1h-.82c-4.52,0-8.18,3.73-8.18,8.33v1.67H14V1Z"
14
+ />
15
+ <path d="M15.82,1h-.82V11h9v-1.67c0-4.6-3.66-8.33-8.18-8.33Z" />
16
+ </svg>
17
+ );
18
+ }
@@ -0,0 +1,44 @@
1
+ /* eslint-disable react/jsx-props-no-spreading */
2
+ import React, { useRef } from 'react';
3
+ import { render, screen } from '@testing-library/react';
4
+ import userEvent from '@testing-library/user-event';
5
+ import type { Units } from 'src/models';
6
+ import { DefaultPalette } from '../FlameGraph/FlameGraphComponent/colorPalette';
7
+
8
+ import TableTooltip, { TableTooltipProps } from './TableTooltip';
9
+
10
+ function TestTable(props: Omit<TableTooltipProps, 'tableBodyRef'>) {
11
+ const tableBodyRef = useRef<HTMLTableSectionElement>(null);
12
+
13
+ return (
14
+ <>
15
+ <table>
16
+ <tbody data-testid="table-body" ref={tableBodyRef} />
17
+ </table>
18
+ <TableTooltip
19
+ {...(props as TableTooltipProps)}
20
+ tableBodyRef={tableBodyRef}
21
+ />
22
+ </>
23
+ );
24
+ }
25
+
26
+ describe('TableTooltip', () => {
27
+ const renderTable = (props: Omit<TableTooltipProps, 'tableBodyRef'>) =>
28
+ render(<TestTable {...props} />);
29
+
30
+ it('should render TableTooltip', () => {
31
+ const props = {
32
+ numTicks: 100,
33
+ sampleRate: 100,
34
+ units: 'samples' as Units,
35
+ palette: DefaultPalette,
36
+ };
37
+
38
+ renderTable(props);
39
+
40
+ userEvent.hover(screen.getByTestId('table-body'));
41
+
42
+ expect(screen.getByTestId('tooltip')).toBeInTheDocument();
43
+ });
44
+ });
@@ -0,0 +1,145 @@
1
+ import React, { useCallback, RefObject, Dispatch, SetStateAction } from 'react';
2
+ import { Units } from '../models/units';
3
+
4
+ import type { FlamegraphPalette } from '../FlameGraph/FlameGraphComponent/colorPalette';
5
+ import { Tooltip, TooltipData } from './Tooltip';
6
+ import { formatDouble } from './FlamegraphTooltip';
7
+ import { getFormatter } from '../format/format';
8
+
9
+ export interface TableTooltipProps {
10
+ tableBodyRef: RefObject<HTMLTableSectionElement>;
11
+ numTicks: number;
12
+ sampleRate: number;
13
+ units: Units;
14
+ palette: FlamegraphPalette;
15
+ }
16
+
17
+ export default function TableTooltip({
18
+ numTicks,
19
+ sampleRate,
20
+ units,
21
+ tableBodyRef,
22
+ palette,
23
+ }: TableTooltipProps) {
24
+ const formatter = getFormatter(numTicks, sampleRate, units);
25
+ const totalFlamebearer = formatter.format(numTicks, sampleRate);
26
+
27
+ const setTooltipContent = useCallback(
28
+ (
29
+ setContent: Dispatch<
30
+ SetStateAction<{
31
+ title: {
32
+ text: string;
33
+ diff: {
34
+ text: string;
35
+ color: string;
36
+ };
37
+ };
38
+ tooltipData: TooltipData[];
39
+ }>
40
+ >,
41
+ onMouseOut: () => void,
42
+ e: MouseEvent
43
+ ) => {
44
+ const tableRowElementData = (e.target as Element).closest('tr')?.dataset
45
+ .row;
46
+
47
+ if (!tableRowElementData) {
48
+ onMouseOut();
49
+ return;
50
+ }
51
+ const [format, functionName, ...rowValues] =
52
+ tableRowElementData.split(';');
53
+
54
+ switch (format) {
55
+ case 'single': {
56
+ const [self, total] = rowValues;
57
+ const selfFormatted = formatter.format(
58
+ parseInt(self, 10),
59
+ sampleRate
60
+ );
61
+ const totalFormated = formatter.format(
62
+ parseInt(total, 10),
63
+ sampleRate
64
+ );
65
+ // todo: i think it will be good to decrease number of calculations here
66
+ const totalFlamebearerSplitted = totalFlamebearer.split(' ');
67
+ const totalFlamebearerNoUnitsValue =
68
+ totalFlamebearerSplitted[0] === '<'
69
+ ? totalFlamebearerSplitted[1]
70
+ : totalFlamebearerSplitted[0];
71
+
72
+ const selfSplitted = selfFormatted.split(' ');
73
+ const selfNoUnitsValue =
74
+ selfSplitted[0] === '<' ? selfSplitted[1] : selfSplitted[0];
75
+
76
+ const totalSplitted = totalFormated.split(' ');
77
+ const totalNoUnitsValue =
78
+ totalSplitted[0] === '<' ? totalSplitted[1] : totalSplitted[0];
79
+
80
+ const newContent: TooltipData = {
81
+ units,
82
+ self: `${selfFormatted}(${(
83
+ (parseFloat(selfNoUnitsValue) /
84
+ parseFloat(totalFlamebearerNoUnitsValue)) *
85
+ 100
86
+ ).toFixed(2)}%)`,
87
+ total: `${totalFormated}(${(
88
+ (parseFloat(totalNoUnitsValue) /
89
+ parseFloat(totalFlamebearerNoUnitsValue)) *
90
+ 100
91
+ ).toFixed(2)}%)`,
92
+ tooltipType: 'table',
93
+ };
94
+
95
+ setContent({
96
+ title: {
97
+ text: functionName,
98
+ diff: {
99
+ text: '',
100
+ color: '',
101
+ },
102
+ },
103
+ tooltipData: [newContent],
104
+ });
105
+ break;
106
+ }
107
+ case 'double': {
108
+ const [totalLeft, leftTicks, totalRight, rightTicks] = rowValues;
109
+ const d = formatDouble(
110
+ {
111
+ formatter,
112
+ sampleRate,
113
+ totalLeft: parseInt(totalLeft, 10),
114
+ leftTicks: parseInt(leftTicks, 10),
115
+ totalRight: parseInt(totalRight, 10),
116
+ rightTicks: parseInt(rightTicks, 10),
117
+ title: functionName,
118
+ units,
119
+ },
120
+ palette
121
+ );
122
+
123
+ setContent({
124
+ title: d.title,
125
+ tooltipData: d.tooltipData,
126
+ });
127
+
128
+ break;
129
+ }
130
+ default:
131
+ break;
132
+ }
133
+ },
134
+ [tableBodyRef, numTicks, formatter, sampleRate]
135
+ );
136
+
137
+ return (
138
+ <Tooltip
139
+ dataSourceRef={tableBodyRef}
140
+ shouldShowTitle={false}
141
+ clickInfoSide="left"
142
+ setTooltipContent={setTooltipContent}
143
+ />
144
+ );
145
+ }
@@ -0,0 +1,71 @@
1
+ .tooltip {
2
+ width: 420px;
3
+ position: fixed;
4
+ background: var(--ps-tooltip-bg);
5
+ box-shadow: 1px 2px 4px 0px rgba(0, 0, 0, 0.3);
6
+ border-radius: 4px;
7
+ color: var(--ps-tooltip-text);
8
+ font-size: 12px;
9
+ visibility: hidden;
10
+ z-index: 2;
11
+ pointer-events: none;
12
+
13
+ &.flamegraphDiffTooltip {
14
+ width: 450px;
15
+ }
16
+
17
+ .tooltipName {
18
+ color: var(--ps-tooltip-text);
19
+ background-color: var(--ps-tooltip-header-bg);
20
+ border-top-right-radius: 4px;
21
+ border-top-left-radius: 4px;
22
+ font-weight: bold;
23
+ white-space: nowrap;
24
+ overflow: hidden;
25
+ text-overflow: ellipsis;
26
+ padding: 8px 10px;
27
+ font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
28
+ }
29
+
30
+ .functionName {
31
+ padding: 8px 10px 0;
32
+ font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
33
+
34
+ white-space: break-spaces;
35
+ word-break: break-all;
36
+ }
37
+
38
+ .tooltipTable {
39
+ width: calc(100% - 10px * 2);
40
+ margin: 10px;
41
+ display: table; /* although this is the default, users may have an overwrite */
42
+
43
+ th,
44
+ td {
45
+ background-color: var(--ps-tooltip-bg);
46
+ border: 1px solid var(--ps-tooltip-header-bg);
47
+ padding: 5px;
48
+ font-weight: normal;
49
+ }
50
+ }
51
+
52
+ .clickInfo {
53
+ margin-bottom: 10px;
54
+ display: flex;
55
+ justify-content: center;
56
+ color: var(--ps-right-click-info);
57
+
58
+ svg {
59
+ color: initial;
60
+ display: block;
61
+ align-self: center;
62
+ width: 22px;
63
+ height: 22px;
64
+ margin-right: 5px;
65
+ }
66
+
67
+ span {
68
+ font-size: 14px;
69
+ }
70
+ }
71
+ }