@parca/profile 0.16.361 → 0.16.363
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.
- package/CHANGELOG.md +8 -0
- package/dist/Callgraph/index.d.ts +3 -2
- package/dist/Callgraph/index.js +2 -2
- package/dist/GraphTooltipArrow/Content.d.ts +3 -2
- package/dist/GraphTooltipArrow/Content.js +3 -4
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.d.ts +3 -2
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.js +2 -2
- package/dist/GraphTooltipArrow/useGraphTooltip/index.d.ts +3 -2
- package/dist/GraphTooltipArrow/useGraphTooltip/index.js +6 -7
- package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts +2 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/index.js +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts +3 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.js +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts +3 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.js +6 -6
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +2 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +4 -4
- package/dist/ProfileIcicleGraph/index.d.ts +3 -2
- package/dist/ProfileIcicleGraph/index.js +2 -2
- package/dist/ProfileView/ProfileViewContext.d.ts +0 -1
- package/dist/ProfileView/ProfileViewContext.js +0 -1
- package/dist/ProfileView/index.d.ts +1 -2
- package/dist/ProfileView/index.js +5 -5
- package/dist/ProfileViewWithData.js +1 -13
- package/dist/SourceView/Highlighter.js +2 -2
- package/dist/Table/index.d.ts +2 -1
- package/dist/Table/index.js +6 -6
- package/dist/index.d.ts +0 -15
- package/package.json +3 -3
- package/src/Callgraph/index.tsx +4 -3
- package/src/GraphTooltipArrow/Content.tsx +5 -6
- package/src/GraphTooltipArrow/DockedGraphTooltip/index.tsx +4 -3
- package/src/GraphTooltipArrow/useGraphTooltip/index.ts +16 -9
- package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +4 -3
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx +4 -3
- package/src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx +10 -8
- package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +8 -7
- package/src/ProfileIcicleGraph/index.tsx +5 -4
- package/src/ProfileView/ProfileViewContext.tsx +0 -2
- package/src/ProfileView/index.tsx +4 -6
- package/src/ProfileViewWithData.tsx +0 -14
- package/src/SourceView/Highlighter.tsx +7 -2
- package/src/Table/index.tsx +10 -7
- package/src/index.tsx +0 -19
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
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.363](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.362...@parca/profile@0.16.363) (2024-05-01)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.16.362](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.361...@parca/profile@0.16.362) (2024-04-29)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## [0.16.361](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.360...@parca/profile@0.16.361) (2024-04-26)
|
|
7
15
|
|
|
8
16
|
**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
|
-
|
|
7
|
+
profileType: ProfileType | undefined;
|
|
7
8
|
width: number;
|
|
8
9
|
}
|
|
9
|
-
declare const Callgraph: ({ data, svgString,
|
|
10
|
+
declare const Callgraph: ({ data, svgString, profileType, width }: Props) => JSX.Element;
|
|
10
11
|
export default Callgraph;
|
package/dist/Callgraph/index.js
CHANGED
|
@@ -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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
11
|
+
const GraphTooltipArrowContent = ({ table, profileType, total, totalUnfiltered, row, level, isFixed, navigateTo, }) => {
|
|
12
12
|
const graphTooltipData = useGraphTooltip({
|
|
13
13
|
table,
|
|
14
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
56
|
-
cumulativePerSecondText: getTextForCumulativePerSecond(cumulativePerSecond,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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,
|
|
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;
|
|
@@ -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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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
|
-
},
|
|
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 {
|
|
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) => {
|
package/dist/Table/index.d.ts
CHANGED
|
@@ -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
|
-
|
|
21
|
+
profileType?: ProfileType;
|
|
21
22
|
navigateTo?: NavigateFunction;
|
|
22
23
|
loading: boolean;
|
|
23
24
|
currentSearchString?: string;
|