@parca/profile 0.16.361 → 0.16.362

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 (42) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/Callgraph/index.d.ts +3 -2
  3. package/dist/Callgraph/index.js +2 -2
  4. package/dist/GraphTooltipArrow/Content.d.ts +3 -2
  5. package/dist/GraphTooltipArrow/Content.js +3 -4
  6. package/dist/GraphTooltipArrow/DockedGraphTooltip/index.d.ts +3 -2
  7. package/dist/GraphTooltipArrow/DockedGraphTooltip/index.js +2 -2
  8. package/dist/GraphTooltipArrow/useGraphTooltip/index.d.ts +3 -2
  9. package/dist/GraphTooltipArrow/useGraphTooltip/index.js +6 -7
  10. package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts +2 -1
  11. package/dist/ProfileIcicleGraph/IcicleGraph/index.js +2 -2
  12. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts +3 -2
  13. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.js +2 -2
  14. package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts +3 -2
  15. package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.js +6 -6
  16. package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +2 -1
  17. package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +4 -4
  18. package/dist/ProfileIcicleGraph/index.d.ts +3 -2
  19. package/dist/ProfileIcicleGraph/index.js +2 -2
  20. package/dist/ProfileView/ProfileViewContext.d.ts +0 -1
  21. package/dist/ProfileView/ProfileViewContext.js +0 -1
  22. package/dist/ProfileView/index.d.ts +1 -2
  23. package/dist/ProfileView/index.js +5 -5
  24. package/dist/ProfileViewWithData.js +1 -13
  25. package/dist/SourceView/Highlighter.js +2 -2
  26. package/dist/Table/index.d.ts +2 -1
  27. package/dist/Table/index.js +6 -6
  28. package/package.json +2 -2
  29. package/src/Callgraph/index.tsx +4 -3
  30. package/src/GraphTooltipArrow/Content.tsx +5 -6
  31. package/src/GraphTooltipArrow/DockedGraphTooltip/index.tsx +4 -3
  32. package/src/GraphTooltipArrow/useGraphTooltip/index.ts +16 -9
  33. package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +4 -3
  34. package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx +4 -3
  35. package/src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx +10 -8
  36. package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +8 -7
  37. package/src/ProfileIcicleGraph/index.tsx +5 -4
  38. package/src/ProfileView/ProfileViewContext.tsx +0 -2
  39. package/src/ProfileView/index.tsx +4 -6
  40. package/src/ProfileViewWithData.tsx +0 -14
  41. package/src/SourceView/Highlighter.tsx +7 -2
  42. package/src/Table/index.tsx +10 -7
package/CHANGELOG.md CHANGED
@@ -3,6 +3,10 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.16.362](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.361...@parca/profile@0.16.362) (2024-04-29)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
6
10
  ## [0.16.361](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.360...@parca/profile@0.16.361) (2024-04-26)
7
11
 
8
12
  **Note:** Version bump only for package @parca/profile
@@ -1,10 +1,11 @@
1
1
  /// <reference types="react" />
2
2
  import { Callgraph as CallgraphType } from '@parca/client';
3
+ import { ProfileType } from '@parca/parser';
3
4
  export interface Props {
4
5
  data: CallgraphType;
5
6
  svgString: string;
6
- sampleUnit: string;
7
+ profileType: ProfileType | undefined;
7
8
  width: number;
8
9
  }
9
- declare const Callgraph: ({ data, svgString, sampleUnit, width }: Props) => JSX.Element;
10
+ declare const Callgraph: ({ data, svgString, profileType, width }: Props) => JSX.Element;
10
11
  export default Callgraph;
@@ -20,7 +20,7 @@ import { Button, useKeyDown, useURLState } from '@parca/components';
20
20
  import { selectDarkMode, setHoveringNode, useAppDispatch, useAppSelector } from '@parca/store';
21
21
  import { getNewSpanColor } from '@parca/utilities';
22
22
  import GraphTooltip from '../GraphTooltip';
23
- const Callgraph = ({ data, svgString, sampleUnit, width }) => {
23
+ const Callgraph = ({ data, svgString, profileType, width }) => {
24
24
  const originalView = {
25
25
  scale: 1,
26
26
  translation: { x: 0, y: 0 },
@@ -98,6 +98,6 @@ const Callgraph = ({ data, svgString, sampleUnit, width }) => {
98
98
  const isResetViewButtonEnabled = view.scale !== originalView.scale ||
99
99
  view.translation.x !== originalView.translation.x ||
100
100
  view.translation.y !== originalView.translation.y;
101
- return (_jsxs("div", { className: "relative w-full", children: [_jsxs("div", { ref: containerRef, className: "w-full overflow-hidden", children: [_jsx(MapInteractionCSS, { showControls: true, minScale: 1, maxScale: 5, value: view, onChange: (value) => setView(value), children: _jsx(SVG, { ref: svgWrapper, src: svgString, width: width, height: "auto", title: "Callgraph", innerRef: svgRef }) }), svgRef.current !== null && (_jsx(GraphTooltip, { type: "callgraph", unit: sampleUnit, total: data.cumulative, totalUnfiltered: data.cumulative, contextElement: containerRef.current }))] }), _jsx("div", { className: cx(dashboardItems.length > 1 ? 'left-[25px]' : 'left-0', 'absolute top-[-46px] w-auto'), children: _jsx(Button, { variant: "neutral", onClick: resetView, className: "z-50", disabled: !isResetViewButtonEnabled, children: "Reset View" }) })] }));
101
+ return (_jsxs("div", { className: "relative w-full", children: [_jsxs("div", { ref: containerRef, className: "w-full overflow-hidden", children: [_jsx(MapInteractionCSS, { showControls: true, minScale: 1, maxScale: 5, value: view, onChange: (value) => setView(value), children: _jsx(SVG, { ref: svgWrapper, src: svgString, width: width, height: "auto", title: "Callgraph", innerRef: svgRef }) }), svgRef.current !== null && (_jsx(GraphTooltip, { type: "callgraph", unit: profileType?.sampleUnit ?? '', total: data.cumulative, totalUnfiltered: data.cumulative, contextElement: containerRef.current }))] }), _jsx("div", { className: cx(dashboardItems.length > 1 ? 'left-[25px]' : 'left-0', 'absolute top-[-46px] w-auto'), children: _jsx(Button, { variant: "neutral", onClick: resetView, className: "z-50", disabled: !isResetViewButtonEnabled, children: "Reset View" }) })] }));
102
102
  };
103
103
  export default Callgraph;
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
2
  import { Table } from 'apache-arrow';
3
+ import { ProfileType } from '@parca/parser';
3
4
  import { type NavigateFunction } from '@parca/utilities';
4
5
  interface GraphTooltipArrowContentProps {
5
6
  table: Table<any>;
6
- unit: string;
7
+ profileType?: ProfileType;
7
8
  total: bigint;
8
9
  totalUnfiltered: bigint;
9
10
  row: number | null;
@@ -11,5 +12,5 @@ interface GraphTooltipArrowContentProps {
11
12
  isFixed: boolean;
12
13
  navigateTo: NavigateFunction;
13
14
  }
14
- declare const GraphTooltipArrowContent: ({ table, unit, total, totalUnfiltered, row, level, isFixed, navigateTo, }: GraphTooltipArrowContentProps) => React.JSX.Element;
15
+ declare const GraphTooltipArrowContent: ({ table, profileType, total, totalUnfiltered, row, level, isFixed, navigateTo, }: GraphTooltipArrowContentProps) => React.JSX.Element;
15
16
  export default GraphTooltipArrowContent;
@@ -8,10 +8,10 @@ import { useGraphTooltipMetaInfo } from './useGraphTooltipMetaInfo';
8
8
  const NoData = () => {
9
9
  return _jsx("span", { className: "rounded bg-gray-200 px-2 dark:bg-gray-800", children: "Not available" });
10
10
  };
11
- const GraphTooltipArrowContent = ({ table, unit, total, totalUnfiltered, row, level, isFixed, navigateTo, }) => {
11
+ const GraphTooltipArrowContent = ({ table, profileType, total, totalUnfiltered, row, level, isFixed, navigateTo, }) => {
12
12
  const graphTooltipData = useGraphTooltip({
13
13
  table,
14
- unit,
14
+ profileType,
15
15
  total,
16
16
  totalUnfiltered,
17
17
  row,
@@ -21,12 +21,11 @@ const GraphTooltipArrowContent = ({ table, unit, total, totalUnfiltered, row, le
21
21
  return _jsx(_Fragment, {});
22
22
  }
23
23
  const { name, locationAddress, cumulativeText, cumulativePerSecondText, diffText, diff, row: rowNumber, } = graphTooltipData;
24
- const delta = unit === 'nanoseconds';
25
24
  return (_jsx("div", { className: `flex text-sm ${isFixed ? 'w-full' : ''}`, children: _jsx("div", { className: `m-auto w-full ${isFixed ? 'w-full' : ''}`, children: _jsxs("div", { className: "min-h-52 flex w-[500px] flex-col justify-between rounded-lg border border-gray-300 bg-gray-50 p-3 shadow-lg dark:border-gray-500 dark:bg-gray-900", children: [_jsx("div", { className: "flex flex-row", children: _jsxs("div", { className: "mx-2", children: [_jsx("div", { className: "flex h-10 items-start justify-between gap-4 break-all font-semibold", children: row === 0 ? (_jsx("p", { children: "root" })) : (_jsx("p", { children: name !== ''
26
25
  ? name
27
26
  : locationAddress !== 0n
28
27
  ? hexifyAddress(locationAddress)
29
- : 'unknown' })) }), _jsx("table", { className: "my-2 w-full table-fixed pr-0 text-gray-700 dark:text-gray-300", children: _jsxs("tbody", { children: [delta ? (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Per Second" }), _jsx("td", { className: "w-3/4", children: _jsx("div", { children: cumulativePerSecondText }) })] })) : (_jsx(_Fragment, {})), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Cumulative" }), _jsx("td", { className: "w-3/4", children: _jsx("div", { children: cumulativeText }) })] }), diff !== 0n && (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Diff" }), _jsx("td", { className: "w-3/4", children: _jsx("div", { children: diffText }) })] })), _jsx(TooltipMetaInfo, { table: table, row: rowNumber, navigateTo: navigateTo })] }) })] }) }), _jsxs("div", { className: "flex w-full items-center gap-1 text-xs text-gray-500", children: [_jsx(Icon, { icon: "iconoir:mouse-button-right" }), _jsx("div", { children: "Right click to show context menu" })] })] }) }) }));
28
+ : 'unknown' })) }), _jsx("table", { className: "my-2 w-full table-fixed pr-0 text-gray-700 dark:text-gray-300", children: _jsxs("tbody", { children: [(profileType?.delta ?? false) ? (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Per Second" }), _jsx("td", { className: "w-3/4", children: _jsx("div", { children: cumulativePerSecondText }) })] })) : (_jsx(_Fragment, {})), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Cumulative" }), _jsx("td", { className: "w-3/4", children: _jsx("div", { children: cumulativeText }) })] }), diff !== 0n && (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Diff" }), _jsx("td", { className: "w-3/4", children: _jsx("div", { children: diffText }) })] })), _jsx(TooltipMetaInfo, { table: table, row: rowNumber, navigateTo: navigateTo })] }) })] }) }), _jsxs("div", { className: "flex w-full items-center gap-1 text-xs text-gray-500", children: [_jsx(Icon, { icon: "iconoir:mouse-button-right" }), _jsx("div", { children: "Right click to show context menu" })] })] }) }) }));
30
29
  };
31
30
  const TooltipMetaInfo = ({ table, row, navigateTo, }) => {
32
31
  const { labelPairs, functionFilename, file, locationAddress, mappingFile, mappingBuildID, inlined, } = useGraphTooltipMetaInfo({ table, row, navigateTo });
@@ -1,12 +1,13 @@
1
1
  /// <reference types="react" />
2
2
  import { Table } from 'apache-arrow';
3
+ import { ProfileType } from '@parca/parser';
3
4
  interface Props {
4
5
  table: Table<any>;
5
- unit: string;
6
6
  total: bigint;
7
7
  totalUnfiltered: bigint;
8
8
  row: number | null;
9
9
  level: number;
10
+ profileType?: ProfileType;
10
11
  }
11
- export declare const DockedGraphTooltip: ({ table, unit, total, totalUnfiltered, row, level, }: Props) => JSX.Element;
12
+ export declare const DockedGraphTooltip: ({ table, total, totalUnfiltered, row, level, profileType, }: Props) => JSX.Element;
12
13
  export {};
@@ -25,14 +25,14 @@ const InfoSection = ({ title, value, minWidth = '', }) => {
25
25
  const NoData = () => {
26
26
  return _jsx("span", { className: "rounded bg-gray-200 px-2 dark:bg-gray-800", children: "Not available" });
27
27
  };
28
- export const DockedGraphTooltip = ({ table, unit, total, totalUnfiltered, row, level, }) => {
28
+ export const DockedGraphTooltip = ({ table, total, totalUnfiltered, row, level, profileType, }) => {
29
29
  let { width } = useWindowSize();
30
30
  const { profileExplorer, navigateTo } = useParcaContext();
31
31
  const { PaddingX } = profileExplorer ?? { PaddingX: 0 };
32
32
  width = width - PaddingX - 24;
33
33
  const graphTooltipData = useGraphTooltip({
34
34
  table,
35
- unit,
35
+ profileType,
36
36
  total,
37
37
  totalUnfiltered,
38
38
  row,
@@ -1,7 +1,8 @@
1
1
  import { Table } from 'apache-arrow';
2
+ import { ProfileType } from '@parca/parser';
2
3
  interface Props {
3
4
  table: Table<any>;
4
- unit: string;
5
+ profileType?: ProfileType;
5
6
  total: bigint;
6
7
  totalUnfiltered: bigint;
7
8
  row: number | null;
@@ -16,5 +17,5 @@ interface GraphTooltipData {
16
17
  diff: bigint;
17
18
  row: number;
18
19
  }
19
- export declare const useGraphTooltip: ({ table, unit, total, totalUnfiltered, row, level, }: Props) => GraphTooltipData | null;
20
+ export declare const useGraphTooltip: ({ table, profileType, total, totalUnfiltered, row, level, }: Props) => GraphTooltipData | null;
20
21
  export {};
@@ -13,8 +13,8 @@
13
13
  import { divide, valueFormatter } from '@parca/utilities';
14
14
  import { FIELD_CUMULATIVE, FIELD_CUMULATIVE_PER_SECOND, FIELD_DIFF, FIELD_DIFF_PER_SECOND, FIELD_LOCATION_ADDRESS, } from '../../ProfileIcicleGraph/IcicleGraphArrow';
15
15
  import { getTextForCumulative, getTextForCumulativePerSecond, nodeLabel, } from '../../ProfileIcicleGraph/IcicleGraphArrow/utils';
16
- export const useGraphTooltip = ({ table, unit, total, totalUnfiltered, row, level, }) => {
17
- if (row === null) {
16
+ export const useGraphTooltip = ({ table, profileType, total, totalUnfiltered, row, level, }) => {
17
+ if (row === null || profileType === undefined) {
18
18
  return null;
19
19
  }
20
20
  const locationAddress = table.getChild(FIELD_LOCATION_ADDRESS)?.get(row) ?? 0n;
@@ -30,9 +30,8 @@ export const useGraphTooltip = ({ table, unit, total, totalUnfiltered, row, leve
30
30
  const diffPerSecond = table.getChild(FIELD_DIFF_PER_SECOND)?.get(row) !== null
31
31
  ? table.getChild(FIELD_DIFF_PER_SECOND)?.get(row)
32
32
  : 0;
33
- const delta = unit === 'nanoseconds';
34
33
  let diffText = '';
35
- if (delta) {
34
+ if (profileType?.delta ?? false) {
36
35
  const prevValue = cumulativePerSecond - diffPerSecond;
37
36
  const diffRatio = diffPerSecond !== 0 ? diffPerSecond / prevValue : 0;
38
37
  const diffSign = diffPerSecond > 0 ? '+' : '';
@@ -44,7 +43,7 @@ export const useGraphTooltip = ({ table, unit, total, totalUnfiltered, row, leve
44
43
  const prevValue = cumulative - diff;
45
44
  const diffRatio = diff !== 0n ? divide(diff, prevValue) : 0;
46
45
  const diffSign = diff > 0 ? '+' : '';
47
- const diffValueText = diffSign + valueFormatter(diff, unit, 1);
46
+ const diffValueText = diffSign + valueFormatter(diff, profileType?.sampleUnit ?? '', 1);
48
47
  const diffPercentageText = diffSign + (diffRatio * 100).toFixed(2) + '%';
49
48
  diffText = `${diffValueText} (${diffPercentageText})`;
50
49
  }
@@ -52,8 +51,8 @@ export const useGraphTooltip = ({ table, unit, total, totalUnfiltered, row, leve
52
51
  return {
53
52
  name,
54
53
  locationAddress,
55
- cumulativeText: getTextForCumulative(cumulative, totalUnfiltered, total, unit),
56
- cumulativePerSecondText: getTextForCumulativePerSecond(cumulativePerSecond, unit),
54
+ cumulativeText: getTextForCumulative(cumulative, totalUnfiltered, total, profileType?.periodUnit ?? ''),
55
+ cumulativePerSecondText: getTextForCumulativePerSecond(cumulativePerSecond, profileType?.periodUnit ?? 'CPU Cores'),
57
56
  diffText,
58
57
  diff,
59
58
  row,
@@ -1,11 +1,12 @@
1
1
  /// <reference types="react" />
2
2
  import { Flamegraph } from '@parca/client';
3
+ import { ProfileType } from '@parca/parser';
3
4
  import { type NavigateFunction } from '@parca/utilities';
4
5
  interface IcicleGraphProps {
5
6
  graph: Flamegraph;
6
7
  total: bigint;
7
8
  filtered: bigint;
8
- sampleUnit: string;
9
+ profileType?: ProfileType;
9
10
  width?: number;
10
11
  curPath: string[];
11
12
  setCurPath: (path: string[]) => void;
@@ -19,7 +19,7 @@ import { useProfileViewContext } from '../../ProfileView/ProfileViewContext';
19
19
  import ColorStackLegend from './ColorStackLegend';
20
20
  import { IcicleNode, RowHeight } from './IcicleGraphNodes';
21
21
  import useColoredGraph from './useColoredGraph';
22
- export const IcicleGraph = memo(function IcicleGraph({ graph, total, filtered, width, setCurPath, curPath, sampleUnit, navigateTo, }) {
22
+ export const IcicleGraph = memo(function IcicleGraph({ graph, total, filtered, width, setCurPath, curPath, profileType, navigateTo, }) {
23
23
  const dispatch = useAppDispatch();
24
24
  const [height, setHeight] = useState(0);
25
25
  const svg = useRef(null);
@@ -42,6 +42,6 @@ export const IcicleGraph = memo(function IcicleGraph({ graph, total, filtered, w
42
42
  if (coloredGraph.root === undefined || width === undefined) {
43
43
  return _jsx(_Fragment, {});
44
44
  }
45
- return (_jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [isColorStackLegendEnabled && (_jsx(ColorStackLegend, { navigateTo: navigateTo, compareMode: compareMode })), _jsx(GraphTooltip, { unit: sampleUnit, total: total, totalUnfiltered: total + filtered, contextElement: svg.current, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function }), _jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, children: _jsx("g", { ref: ref, children: _jsx("g", { transform: 'translate(0, 0)', children: _jsx(IcicleNode, { x: 0, y: 0, totalWidth: width, height: RowHeight, setCurPath: setCurPath, curPath: curPath, data: coloredGraph.root, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, compareMode: compareMode }) }) }) })] }));
45
+ return (_jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [isColorStackLegendEnabled && (_jsx(ColorStackLegend, { navigateTo: navigateTo, compareMode: compareMode })), _jsx(GraphTooltip, { unit: profileType?.sampleUnit ?? '', total: total, totalUnfiltered: total + filtered, contextElement: svg.current, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function }), _jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, children: _jsx("g", { ref: ref, children: _jsx("g", { transform: 'translate(0, 0)', children: _jsx(IcicleNode, { x: 0, y: 0, totalWidth: width, height: RowHeight, setCurPath: setCurPath, curPath: curPath, data: coloredGraph.root, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, compareMode: compareMode }) }) }) })] }));
46
46
  });
47
47
  export default IcicleGraph;
@@ -1,10 +1,11 @@
1
1
  /// <reference types="react" />
2
2
  import { Table } from 'apache-arrow';
3
+ import { ProfileType } from '@parca/parser';
3
4
  import { type NavigateFunction } from '@parca/utilities';
4
5
  interface ContextMenuProps {
5
6
  menuId: string;
6
7
  table: Table<any>;
7
- unit: string;
8
+ profileType?: ProfileType;
8
9
  total: bigint;
9
10
  totalUnfiltered: bigint;
10
11
  row: number;
@@ -15,5 +16,5 @@ interface ContextMenuProps {
15
16
  setCurPath: (path: string[]) => void;
16
17
  hideMenu: () => void;
17
18
  }
18
- declare const ContextMenu: ({ menuId, table, unit, total, totalUnfiltered, row, level, navigateTo, trackVisibility, curPath, setCurPath, hideMenu, }: ContextMenuProps) => JSX.Element;
19
+ declare const ContextMenu: ({ menuId, table, total, totalUnfiltered, row, level, navigateTo, trackVisibility, curPath, setCurPath, hideMenu, profileType, }: ContextMenuProps) => JSX.Element;
19
20
  export default ContextMenu;
@@ -19,13 +19,13 @@ import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
19
19
  import { useGraphTooltip } from '../../GraphTooltipArrow/useGraphTooltip';
20
20
  import { useGraphTooltipMetaInfo } from '../../GraphTooltipArrow/useGraphTooltipMetaInfo';
21
21
  import { hexifyAddress, truncateString } from '../../utils';
22
- const ContextMenu = ({ menuId, table, unit, total, totalUnfiltered, row, level, navigateTo, trackVisibility, curPath, setCurPath, hideMenu, }) => {
22
+ const ContextMenu = ({ menuId, table, total, totalUnfiltered, row, level, navigateTo, trackVisibility, curPath, setCurPath, hideMenu, profileType, }) => {
23
23
  const { isDarkMode } = useParcaContext();
24
24
  const { enableSourcesView } = useParcaContext();
25
25
  const [isGraphTooltipDocked, setIsDocked] = useUserPreference(USER_PREFERENCES.GRAPH_METAINFO_DOCKED.key);
26
26
  const contextMenuData = useGraphTooltip({
27
27
  table,
28
- unit,
28
+ profileType,
29
29
  total,
30
30
  totalUnfiltered,
31
31
  row,
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { Table } from 'apache-arrow';
3
3
  import 'react-contexify/dist/ReactContexify.css';
4
+ import { ProfileType } from '@parca/parser';
4
5
  export declare const RowHeight = 26;
5
6
  interface IcicleGraphNodesProps {
6
7
  table: Table<any>;
@@ -22,7 +23,7 @@ interface IcicleGraphNodesProps {
22
23
  sortBy: string;
23
24
  darkMode: boolean;
24
25
  compareMode: boolean;
25
- delta: boolean;
26
+ profileType?: ProfileType;
26
27
  isContextMenuOpen: boolean;
27
28
  hoveringName: string | null;
28
29
  setHoveringName: (name: string | null) => void;
@@ -55,7 +56,7 @@ interface IcicleNodeProps {
55
56
  sortBy: string;
56
57
  darkMode: boolean;
57
58
  compareMode: boolean;
58
- delta: boolean;
59
+ profileType?: ProfileType;
59
60
  isContextMenuOpen: boolean;
60
61
  hoveringName: string | null;
61
62
  setHoveringName: (name: string | null) => void;
@@ -20,7 +20,7 @@ import { FIELD_CHILDREN, FIELD_CUMULATIVE, FIELD_CUMULATIVE_PER_SECOND, FIELD_DI
20
20
  import useNodeColor from './useNodeColor';
21
21
  import { arrowToString, nodeLabel } from './utils';
22
22
  export const RowHeight = 26;
23
- export const IcicleGraphNodes = React.memo(function IcicleGraphNodesNoMemo({ table, childRows, mappingColors, x, y, xScale, total, totalWidth, level, path, setCurPath, setHoveringRow, setHoveringLevel, curPath, sortBy, searchString, darkMode, compareMode, delta, isContextMenuOpen, hoveringName, setHoveringName, hoveringRow, colorForSimilarNodes, highlightSimilarStacksPreference, }) {
23
+ export const IcicleGraphNodes = React.memo(function IcicleGraphNodesNoMemo({ table, childRows, mappingColors, x, y, xScale, total, totalWidth, level, path, setCurPath, setHoveringRow, setHoveringLevel, curPath, sortBy, searchString, darkMode, compareMode, profileType, isContextMenuOpen, hoveringName, setHoveringName, hoveringRow, colorForSimilarNodes, highlightSimilarStacksPreference, }) {
24
24
  const cumulatives = table.getChild(FIELD_CUMULATIVE);
25
25
  if (childRows === undefined || childRows.length === 0) {
26
26
  return _jsx(_Fragment, {});
@@ -35,7 +35,7 @@ export const IcicleGraphNodes = React.memo(function IcicleGraphNodesNoMemo({ tab
35
35
  const xStart = Math.floor(xScale(BigInt(childrenCumulative)));
36
36
  const c = BigInt(cumulatives?.get(child));
37
37
  childrenCumulative += c;
38
- childrenElements.push(_jsx(IcicleNode, { table: table, row: child, mappingColors: mappingColors, x: xStart, y: 0, totalWidth: totalWidth, height: RowHeight, path: path, setCurPath: setCurPath, setHoveringRow: setHoveringRow, setHoveringLevel: setHoveringLevel, level: level, curPath: curPath, total: total, xScale: xScale, sortBy: sortBy, searchString: searchString, darkMode: darkMode, compareMode: compareMode, delta: delta, isContextMenuOpen: isContextMenuOpen, hoveringName: hoveringName, setHoveringName: setHoveringName, hoveringRow: hoveringRow, colorForSimilarNodes: colorForSimilarNodes, highlightSimilarStacksPreference: highlightSimilarStacksPreference }, `node-${level}-${i}`));
38
+ childrenElements.push(_jsx(IcicleNode, { table: table, row: child, mappingColors: mappingColors, x: xStart, y: 0, totalWidth: totalWidth, height: RowHeight, path: path, setCurPath: setCurPath, setHoveringRow: setHoveringRow, setHoveringLevel: setHoveringLevel, level: level, curPath: curPath, total: total, xScale: xScale, sortBy: sortBy, searchString: searchString, darkMode: darkMode, compareMode: compareMode, profileType: profileType, isContextMenuOpen: isContextMenuOpen, hoveringName: hoveringName, setHoveringName: setHoveringName, hoveringRow: hoveringRow, colorForSimilarNodes: colorForSimilarNodes, highlightSimilarStacksPreference: highlightSimilarStacksPreference }, `node-${level}-${i}`));
39
39
  });
40
40
  return _jsx("g", { transform: `translate(${x}, ${y})`, children: childrenElements });
41
41
  });
@@ -48,7 +48,7 @@ const fadedIcicleRectStyles = {
48
48
  transition: 'opacity .15s linear',
49
49
  opacity: '0.5',
50
50
  };
51
- export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, mappingColors, x, y, height, setCurPath, curPath, level, path, total, totalWidth, xScale, isRoot = false, searchString, setHoveringRow, setHoveringLevel, sortBy, darkMode, compareMode, delta, isContextMenuOpen, hoveringName, setHoveringName, hoveringRow, colorForSimilarNodes, highlightSimilarStacksPreference, }) {
51
+ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, mappingColors, x, y, height, setCurPath, curPath, level, path, total, totalWidth, xScale, isRoot = false, searchString, setHoveringRow, setHoveringLevel, sortBy, darkMode, compareMode, profileType, isContextMenuOpen, hoveringName, setHoveringName, hoveringRow, colorForSimilarNodes, highlightSimilarStacksPreference, }) {
52
52
  // get the columns to read from
53
53
  const mappingColumn = table.getChild(FIELD_MAPPING_FILE);
54
54
  const functionNameColumn = table.getChild(FIELD_FUNCTION_NAME);
@@ -97,7 +97,7 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
97
97
  });
98
98
  break;
99
99
  case FIELD_CUMULATIVE:
100
- if (delta) {
100
+ if (profileType?.delta ?? false) {
101
101
  childRows.sort((a, b) => {
102
102
  const aCumulativePerSecond = cumulativePerSecondColumn?.get(a);
103
103
  const bCumulativePerSecond = cumulativePerSecondColumn?.get(b);
@@ -113,7 +113,7 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
113
113
  break;
114
114
  case FIELD_DIFF:
115
115
  childRows.sort((a, b) => {
116
- if (delta) {
116
+ if (profileType?.delta ?? false) {
117
117
  let aRatio = null;
118
118
  let bRatio = null;
119
119
  const aDiff = diffPerSecondColumn?.get(a);
@@ -225,5 +225,5 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
225
225
  ? `${colorForSimilarNodes} stroke-[3] [stroke-dasharray:6,4] [stroke-linecap:round] [stroke-linejoin:round] h-6`
226
226
  : 'stroke-white dark:stroke-gray-700', {
227
227
  'opacity-50': isHighlightEnabled && !isHighlighted,
228
- }) }), width > 5 && (_jsx("svg", { width: width - 5, height: height, children: _jsx("text", { x: 5, y: 15, style: { fontSize: '12px' }, children: name }) }))] }), childRows.length > 0 && (_jsx(IcicleGraphNodes, { table: table, row: row, mappingColors: mappingColors, childRows: childRows, x: x, y: RowHeight, xScale: newXScale, total: total, totalWidth: totalWidth, level: nextLevel, path: nextPath, curPath: nextCurPath, setCurPath: setCurPath, setHoveringRow: setHoveringRow, setHoveringLevel: setHoveringLevel, searchString: searchString, sortBy: sortBy, darkMode: darkMode, delta: delta, compareMode: compareMode, isContextMenuOpen: isContextMenuOpen, hoveringName: hoveringName, setHoveringName: setHoveringName, hoveringRow: hoveringRow, colorForSimilarNodes: colorForSimilarNodes, highlightSimilarStacksPreference: highlightSimilarStacksPreference }))] }));
228
+ }) }), width > 5 && (_jsx("svg", { width: width - 5, height: height, children: _jsx("text", { x: 5, y: 15, style: { fontSize: '12px' }, children: name }) }))] }), childRows.length > 0 && (_jsx(IcicleGraphNodes, { table: table, row: row, mappingColors: mappingColors, childRows: childRows, x: x, y: RowHeight, xScale: newXScale, total: total, totalWidth: totalWidth, level: nextLevel, path: nextPath, curPath: nextCurPath, setCurPath: setCurPath, setHoveringRow: setHoveringRow, setHoveringLevel: setHoveringLevel, searchString: searchString, sortBy: sortBy, darkMode: darkMode, profileType: profileType, compareMode: compareMode, isContextMenuOpen: isContextMenuOpen, hoveringName: hoveringName, setHoveringName: setHoveringName, hoveringRow: hoveringRow, colorForSimilarNodes: colorForSimilarNodes, highlightSimilarStacksPreference: highlightSimilarStacksPreference }))] }));
229
229
  });
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { FlamegraphArrow } from '@parca/client';
3
+ import { ProfileType } from '@parca/parser';
3
4
  import { type NavigateFunction } from '@parca/utilities';
4
5
  export declare const FIELD_LABELS_ONLY = "labels_only";
5
6
  export declare const FIELD_MAPPING_FILE = "mapping_file";
@@ -21,7 +22,7 @@ interface IcicleGraphArrowProps {
21
22
  arrow: FlamegraphArrow;
22
23
  total: bigint;
23
24
  filtered: bigint;
24
- sampleUnit: string;
25
+ profileType?: ProfileType;
25
26
  width?: number;
26
27
  curPath: string[];
27
28
  setCurPath: (path: string[]) => void;
@@ -41,7 +41,7 @@ export const FIELD_CUMULATIVE = 'cumulative';
41
41
  export const FIELD_CUMULATIVE_PER_SECOND = 'cumulative_per_second';
42
42
  export const FIELD_DIFF = 'diff';
43
43
  export const FIELD_DIFF_PER_SECOND = 'diff_per_second';
44
- export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, sampleUnit, navigateTo, sortBy, }) {
44
+ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, profileType, navigateTo, sortBy, }) {
45
45
  const [isContextMenuOpen, setIsContextMenuOpen] = useState(false);
46
46
  const dispatch = useAppDispatch();
47
47
  const [highlightSimilarStacksPreference] = useUserPreference(USER_PREFERENCES.HIGHLIGHT_SIMILAR_STACKS.key);
@@ -141,14 +141,14 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
141
141
  };
142
142
  // useMemo for the root graph as it otherwise renders the whole graph if the hoveringRow changes.
143
143
  const root = useMemo(() => {
144
- return (_jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, onContextMenu: displayMenu, children: _jsx("g", { ref: ref, children: _jsx("g", { transform: 'translate(0, 0)', children: _jsx(IcicleNode, { table: table, row: 0, mappingColors: mappingColors, x: 0, y: 0, totalWidth: width ?? 1, height: RowHeight, setCurPath: setCurPath, curPath: curPath, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, setHoveringRow: setHoveringRow, setHoveringLevel: setHoveringLevel, sortBy: sortBy, darkMode: isDarkMode, compareMode: compareMode, delta: sampleUnit === 'nanoseconds', isContextMenuOpen: isContextMenuOpen, hoveringName: hoveringName, setHoveringName: setHoveringName, hoveringRow: hoveringRow, colorForSimilarNodes: colorForSimilarNodes, highlightSimilarStacksPreference: highlightSimilarStacksPreference }) }) }) }));
144
+ return (_jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, onContextMenu: displayMenu, children: _jsx("g", { ref: ref, children: _jsx("g", { transform: 'translate(0, 0)', children: _jsx(IcicleNode, { table: table, row: 0, mappingColors: mappingColors, x: 0, y: 0, totalWidth: width ?? 1, height: RowHeight, setCurPath: setCurPath, curPath: curPath, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, setHoveringRow: setHoveringRow, setHoveringLevel: setHoveringLevel, sortBy: sortBy, darkMode: isDarkMode, compareMode: compareMode, profileType: profileType, isContextMenuOpen: isContextMenuOpen, hoveringName: hoveringName, setHoveringName: setHoveringName, hoveringRow: hoveringRow, colorForSimilarNodes: colorForSimilarNodes, highlightSimilarStacksPreference: highlightSimilarStacksPreference }) }) }) }));
145
145
  }, [
146
146
  compareMode,
147
147
  curPath,
148
148
  currentSearchString,
149
149
  height,
150
150
  isDarkMode,
151
- sampleUnit,
151
+ profileType,
152
152
  mappingColors,
153
153
  setCurPath,
154
154
  sortBy,
@@ -166,6 +166,6 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
166
166
  if (table.numRows === 0 || width === undefined) {
167
167
  return _jsx(_Fragment, {});
168
168
  }
169
- return (_jsx(_Fragment, { children: _jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [_jsx(ContextMenu, { menuId: MENU_ID, table: table, row: hoveringRow ?? 0, level: hoveringLevel ?? 0, total: total, totalUnfiltered: total + filtered, unit: sampleUnit, navigateTo: navigateTo, trackVisibility: trackVisibility, curPath: curPath, setCurPath: setCurPath, hideMenu: hideAll }), isColorStackLegendEnabled && (_jsx(ColorStackLegend, { mappingColors: mappingColors, navigateTo: navigateTo, compareMode: compareMode })), dockedMetainfo ? (_jsx(DockedGraphTooltip, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, total: total, totalUnfiltered: total + filtered, unit: sampleUnit })) : (!isContextMenuOpen && (_jsx(GraphTooltipArrow, { contextElement: svg.current, isContextMenuOpen: isContextMenuOpen, children: _jsx(GraphTooltipArrowContent, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, isFixed: false, total: total, totalUnfiltered: total + filtered, unit: sampleUnit, navigateTo: navigateTo }) }))), root] }) }));
169
+ return (_jsx(_Fragment, { children: _jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [_jsx(ContextMenu, { menuId: MENU_ID, table: table, row: hoveringRow ?? 0, level: hoveringLevel ?? 0, total: total, totalUnfiltered: total + filtered, profileType: profileType, navigateTo: navigateTo, trackVisibility: trackVisibility, curPath: curPath, setCurPath: setCurPath, hideMenu: hideAll }), isColorStackLegendEnabled && (_jsx(ColorStackLegend, { mappingColors: mappingColors, navigateTo: navigateTo, compareMode: compareMode })), dockedMetainfo ? (_jsx(DockedGraphTooltip, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, total: total, totalUnfiltered: total + filtered, profileType: profileType })) : (!isContextMenuOpen && (_jsx(GraphTooltipArrow, { contextElement: svg.current, isContextMenuOpen: isContextMenuOpen, children: _jsx(GraphTooltipArrowContent, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, isFixed: false, total: total, totalUnfiltered: total + filtered, profileType: profileType, navigateTo: navigateTo }) }))), root] }) }));
170
170
  });
171
171
  export default IcicleGraphArrow;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Flamegraph, FlamegraphArrow } from '@parca/client';
3
+ import { ProfileType } from '@parca/parser';
3
4
  import { type NavigateFunction } from '@parca/utilities';
4
5
  export type ResizeHandler = (width: number, height: number) => void;
5
6
  interface ProfileIcicleGraphProps {
@@ -8,7 +9,7 @@ interface ProfileIcicleGraphProps {
8
9
  arrow?: FlamegraphArrow;
9
10
  total: bigint;
10
11
  filtered: bigint;
11
- sampleUnit: string;
12
+ profileType?: ProfileType;
12
13
  curPath: string[] | [];
13
14
  setNewCurPath: (path: string[]) => void;
14
15
  navigateTo?: NavigateFunction;
@@ -17,5 +18,5 @@ interface ProfileIcicleGraphProps {
17
18
  error?: any;
18
19
  isHalfScreen: boolean;
19
20
  }
20
- declare const ProfileIcicleGraph: ({ graph, arrow, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, isHalfScreen, }: ProfileIcicleGraphProps) => JSX.Element;
21
+ declare const ProfileIcicleGraph: ({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, navigateTo, loading, setActionButtons, error, width, isHalfScreen, }: ProfileIcicleGraphProps) => JSX.Element;
21
22
  export default ProfileIcicleGraph;
@@ -82,7 +82,7 @@ const GroupAndSortActionButtons = ({ navigateTo }) => {
82
82
  });
83
83
  return (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy }), _jsx(SortBySelect, { compareMode: compareMode, sortBy: storeSortBy, setSortBy: setStoreSortBy }), _jsx(RuntimeFilterDropdown, { showRuntimeRuby: showRuntimeRubyStr === 'true', toggleShowRuntimeRuby: () => setShowRuntimeRuby(showRuntimeRubyStr === 'true' ? 'false' : 'true'), showRuntimePython: showRuntimePythonStr === 'true', toggleShowRuntimePython: () => setShowRuntimePython(showRuntimePythonStr === 'true' ? 'false' : 'true'), showInterpretedOnly: showInterpretedOnlyStr === 'true', toggleShowInterpretedOnly: () => setShowInterpretedOnly(showInterpretedOnlyStr === 'true' ? 'false' : 'true') })] }));
84
84
  };
85
- const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, isHalfScreen, }) {
85
+ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, navigateTo, loading, setActionButtons, error, width, isHalfScreen, }) {
86
86
  const { onError, authenticationErrorMessage, isDarkMode } = useParcaContext();
87
87
  const { compareMode } = useProfileViewContext();
88
88
  const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
@@ -134,6 +134,6 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
134
134
  if (isTrimmed) {
135
135
  console.info(`Trimmed ${trimmedFormatted} (${trimmedPercentage}%) too small values.`);
136
136
  }
137
- return (_jsx(AnimatePresence, { children: _jsxs(motion.div, { className: "relative h-full w-full", initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.5 }, children: [compareMode ? _jsx(DiffLegend, {}) : null, _jsxs("div", { className: "min-h-48", id: "h-icicle-graph", children: [graph !== undefined && (_jsx(IcicleGraph, { width: width, graph: graph, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo })), arrow !== undefined && (_jsx(IcicleGraphArrow, { width: width, arrow: arrow, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo, sortBy: storeSortBy }))] }), _jsxs("p", { className: "my-2 text-xs", children: ["Showing ", totalFormatted, ' ', isFiltered ? (_jsxs("span", { children: ["(", filteredPercentage, "%) filtered of ", totalUnfilteredFormatted, ' '] })) : (_jsx(_Fragment, {})), "values.", ' '] })] }, "icicle-graph-loaded") }));
137
+ return (_jsx(AnimatePresence, { children: _jsxs(motion.div, { className: "relative h-full w-full", initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.5 }, children: [compareMode ? _jsx(DiffLegend, {}) : null, _jsxs("div", { className: "min-h-48", id: "h-icicle-graph", children: [graph !== undefined && (_jsx(IcicleGraph, { width: width, graph: graph, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, profileType: profileType, navigateTo: navigateTo })), arrow !== undefined && (_jsx(IcicleGraphArrow, { width: width, arrow: arrow, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, profileType: profileType, navigateTo: navigateTo, sortBy: storeSortBy }))] }), _jsxs("p", { className: "my-2 text-xs", children: ["Showing ", totalFormatted, ' ', isFiltered ? (_jsxs("span", { children: ["(", filteredPercentage, "%) filtered of ", totalUnfilteredFormatted, ' '] })) : (_jsx(_Fragment, {})), "values.", ' '] })] }, "icicle-graph-loaded") }));
138
138
  };
139
139
  export default ProfileIcicleGraph;
@@ -2,7 +2,6 @@ import { ReactNode } from 'react';
2
2
  import { ProfileSource } from '../ProfileSource';
3
3
  interface Props {
4
4
  profileSource?: ProfileSource;
5
- sampleUnit: string;
6
5
  compareMode: boolean;
7
6
  }
8
7
  export declare const defaultValue: Props;
@@ -14,7 +14,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
14
14
  import { createContext, useContext } from 'react';
15
15
  export const defaultValue = {
16
16
  profileSource: undefined,
17
- sampleUnit: 'bytes',
18
17
  compareMode: false,
19
18
  };
20
19
  const ProfileViewContext = createContext(defaultValue);
@@ -39,7 +39,6 @@ export interface ProfileViewProps {
39
39
  topTableData?: TopTableData;
40
40
  callgraphData?: CallgraphData;
41
41
  sourceData?: SourceData;
42
- sampleUnit: string;
43
42
  profileSource?: ProfileSource;
44
43
  queryClient?: QueryServiceClient;
45
44
  navigateTo?: NavigateFunction;
@@ -47,5 +46,5 @@ export interface ProfileViewProps {
47
46
  onDownloadPProf: () => void;
48
47
  pprofDownloading?: boolean;
49
48
  }
50
- export declare const ProfileView: ({ total, filtered, flamegraphData, topTableData, callgraphData, sourceData, sampleUnit, profileSource, queryClient, navigateTo, onDownloadPProf, pprofDownloading, compare, }: ProfileViewProps) => JSX.Element;
49
+ export declare const ProfileView: ({ total, filtered, flamegraphData, topTableData, callgraphData, sourceData, profileSource, queryClient, navigateTo, onDownloadPProf, pprofDownloading, compare, }: ProfileViewProps) => JSX.Element;
51
50
  export {};
@@ -38,7 +38,7 @@ function arrayEquals(a, b) {
38
38
  a.length === b.length &&
39
39
  a.every((val, index) => val === b[index]));
40
40
  }
41
- export const ProfileView = ({ total, filtered, flamegraphData, topTableData, callgraphData, sourceData, sampleUnit, profileSource, queryClient, navigateTo, onDownloadPProf, pprofDownloading, compare, }) => {
41
+ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, callgraphData, sourceData, profileSource, queryClient, navigateTo, onDownloadPProf, pprofDownloading, compare, }) => {
42
42
  const { timezone } = useParcaContext();
43
43
  const { ref, dimensions } = useContainerDimensions();
44
44
  const [curPath, setCurPath] = useState([]);
@@ -107,7 +107,7 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
107
107
  return (_jsx(ConditionalWrapper, { condition: perf?.onRender != null, WrapperComponent: Profiler, wrapperProps: {
108
108
  id: 'icicleGraph',
109
109
  onRender: perf?.onRender,
110
- }, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, arrow: flamegraphData?.arrow, graph: flamegraphData?.data, total: total, filtered: filtered, sampleUnit: sampleUnit, navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons, error: flamegraphData.error, isHalfScreen: isHalfScreen, width: dimensions?.width !== undefined
110
+ }, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, arrow: flamegraphData?.arrow, graph: flamegraphData?.data, total: total, filtered: filtered, profileType: profileSource?.ProfileType(), navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons, error: flamegraphData.error, isHalfScreen: isHalfScreen, width: dimensions?.width !== undefined
111
111
  ? isHalfScreen
112
112
  ? (dimensions.width - 40) / 2
113
113
  : dimensions.width - 16
@@ -116,10 +116,10 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
116
116
  case 'callgraph': {
117
117
  return callgraphData?.data !== undefined &&
118
118
  callgraphSVG !== undefined &&
119
- dimensions?.width !== undefined ? (_jsx(Callgraph, { data: callgraphData.data, svgString: callgraphSVG, sampleUnit: sampleUnit, width: isHalfScreen ? dimensions?.width / 2 : dimensions?.width })) : (_jsx(_Fragment, {}));
119
+ dimensions?.width !== undefined ? (_jsx(Callgraph, { data: callgraphData.data, svgString: callgraphSVG, profileType: profileSource?.ProfileType(), width: isHalfScreen ? dimensions?.width / 2 : dimensions?.width })) : (_jsx(_Fragment, {}));
120
120
  }
121
121
  case 'table': {
122
- return topTableData != null ? (_jsx(Table, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, sampleUnit: sampleUnit, navigateTo: navigateTo, setActionButtons: setActionButtons, currentSearchString: currentSearchString, isHalfScreen: isHalfScreen })) : (_jsx(_Fragment, {}));
122
+ return topTableData != null ? (_jsx(Table, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, profileType: profileSource?.ProfileType(), navigateTo: navigateTo, setActionButtons: setActionButtons, currentSearchString: currentSearchString, isHalfScreen: isHalfScreen })) : (_jsx(_Fragment, {}));
123
123
  }
124
124
  case 'source': {
125
125
  return sourceData != null ? (_jsx(SourceView, { loading: sourceData.loading, data: sourceData.data, total: total, filtered: filtered, setActionButtons: setActionButtons })) : (_jsx(_Fragment, {}));
@@ -150,7 +150,7 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
150
150
  const headerParts = profileSourceString?.split('"') ?? [];
151
151
  const compareMode = compare === true ||
152
152
  (selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true');
153
- return (_jsx(KeyDownProvider, { children: _jsxs(ProfileViewContextProvider, { value: { profileSource, sampleUnit, compareMode }, children: [_jsxs("div", { className: cx('mb-4 flex w-full', hasProfileSource || profileViewExternalMainActions != null
153
+ return (_jsx(KeyDownProvider, { children: _jsxs(ProfileViewContextProvider, { value: { profileSource, compareMode }, children: [_jsxs("div", { className: cx('mb-4 flex w-full', hasProfileSource || profileViewExternalMainActions != null
154
154
  ? 'justify-between'
155
155
  : 'justify-end', {
156
156
  'items-end': !hasProfileSource && profileViewExternalMainActions != null,
@@ -87,18 +87,6 @@ export const ProfileViewWithData = ({ queryClient, profileSource, navigateTo, })
87
87
  sourceResponse,
88
88
  perf,
89
89
  ]);
90
- // Default to the unit of the selected profile type. This is a heuristic, and
91
- // only a fallback, the unit should be returned by the backend.
92
- let sampleUnit = profileSource.ProfileType().sampleUnit;
93
- if (flamegraphResponse?.report.oneofKind === 'flamegraphArrow') {
94
- sampleUnit = flamegraphResponse.report.flamegraphArrow.unit;
95
- }
96
- if (tableResponse?.report.oneofKind === 'tableArrow') {
97
- sampleUnit = tableResponse.report.tableArrow.unit;
98
- }
99
- if (sourceResponse?.report.oneofKind === 'source') {
100
- sampleUnit = sourceResponse.report.source.unit;
101
- }
102
90
  const downloadPProfClick = async () => {
103
91
  if (profileSource == null || queryClient == null) {
104
92
  return;
@@ -163,6 +151,6 @@ export const ProfileViewWithData = ({ queryClient, profileSource, navigateTo, })
163
151
  ? sourceResponse?.report?.source
164
152
  : undefined,
165
153
  error: sourceError,
166
- }, sampleUnit: sampleUnit, profileSource: profileSource, queryClient: queryClient, navigateTo: navigateTo, onDownloadPProf: () => void downloadPProfClick(), pprofDownloading: pprofDownloading }));
154
+ }, profileSource: profileSource, queryClient: queryClient, navigateTo: navigateTo, onDownloadPProf: () => void downloadPProfClick(), pprofDownloading: pprofDownloading }));
167
155
  };
168
156
  export default ProfileViewWithData;
@@ -45,13 +45,13 @@ const intensityScale = scaleLinear().domain([0, 99]).range([0.05, 0.75]);
45
45
  const LineProfileMetadata = ({ value, total, filtered, }) => {
46
46
  const commonClasses = 'w-[52px] shrink-0';
47
47
  const id = useId();
48
- const { sampleUnit } = useProfileViewContext();
48
+ const { profileSource } = useProfileViewContext();
49
49
  if (value === 0n) {
50
50
  return _jsx("div", { className: cx(commonClasses) });
51
51
  }
52
52
  const unfilteredPercent = (Number(value) / Number(total + filtered)) * 100;
53
53
  const filteredPercent = (Number(value) / Number(total)) * 100;
54
- const valueWithUnit = valueFormatter(value, sampleUnit, 1, true);
54
+ const valueWithUnit = valueFormatter(value, profileSource?.ProfileType().sampleUnit ?? '', 1, true);
55
55
  return (_jsxs(_Fragment, { children: [_jsx("p", { className: cx('w- flex justify-end overflow-hidden text-ellipsis whitespace-nowrap', commonClasses), style: { backgroundColor: `rgba(236, 151, 6, ${intensityScale(unfilteredPercent)})` }, "data-tooltip-id": id, "data-tooltip-content": `${valueWithUnit} (${unfilteredPercent.toFixed(2)}%${filtered > 0n ? ` / ${filteredPercent.toFixed(2)}%` : ''})`, children: valueWithUnit }), _jsx(Tooltip, { id: id })] }));
56
56
  };
57
57
  const charsToWidth = (chars) => {
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { Vector } from 'apache-arrow';
3
+ import { ProfileType } from '@parca/parser';
3
4
  import { type NavigateFunction } from '@parca/utilities';
4
5
  export interface ColumnDef {
5
6
  id: string;
@@ -17,7 +18,7 @@ interface TableProps {
17
18
  data?: Uint8Array;
18
19
  total: bigint;
19
20
  filtered: bigint;
20
- sampleUnit: string;
21
+ profileType?: ProfileType;
21
22
  navigateTo?: NavigateFunction;
22
23
  loading: boolean;
23
24
  currentSearchString?: string;