@parca/profile 0.16.416 → 0.16.418
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.js +3 -2
- package/dist/GraphTooltipArrow/Content.d.ts +2 -3
- package/dist/GraphTooltipArrow/Content.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/Content.js +6 -5
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.d.ts +2 -1
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.js +6 -7
- package/dist/GraphTooltipArrow/useGraphTooltip/index.d.ts +2 -3
- package/dist/GraphTooltipArrow/useGraphTooltip/index.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/useGraphTooltip/index.js +9 -30
- package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.d.ts +1 -3
- package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/useGraphTooltipMetaInfo/index.js +6 -16
- package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts.map +1 -1
- package/dist/ProfileExplorer/ProfileExplorerCompare.js +3 -3
- package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts.map +1 -1
- package/dist/ProfileExplorer/ProfileExplorerSingle.js +1 -1
- package/dist/ProfileExplorer/index.d.ts.map +1 -1
- package/dist/ProfileExplorer/index.js +1 -7
- package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.d.ts +1 -3
- package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.js +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts +0 -2
- package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/index.js +4 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.d.ts +1 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.js +8 -20
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts +2 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.js +3 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.js +6 -46
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +2 -5
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +6 -12
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.d.ts +1 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.js +2 -5
- package/dist/ProfileIcicleGraph/index.d.ts +1 -3
- package/dist/ProfileIcicleGraph/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/index.js +21 -48
- package/dist/ProfileMetricsGraph/index.js +1 -2
- package/dist/ProfileView/FilterByFunctionButton.d.ts +1 -4
- package/dist/ProfileView/FilterByFunctionButton.d.ts.map +1 -1
- package/dist/ProfileView/FilterByFunctionButton.js +12 -3
- package/dist/ProfileView/ViewSelector.d.ts +1 -3
- package/dist/ProfileView/ViewSelector.d.ts.map +1 -1
- package/dist/ProfileView/ViewSelector.js +3 -4
- package/dist/ProfileView/VisualizationPanel.d.ts +0 -2
- package/dist/ProfileView/VisualizationPanel.d.ts.map +1 -1
- package/dist/ProfileView/VisualizationPanel.js +2 -2
- package/dist/ProfileView/index.d.ts +1 -5
- package/dist/ProfileView/index.d.ts.map +1 -1
- package/dist/ProfileView/index.js +11 -18
- package/dist/ProfileViewWithData.d.ts +1 -3
- package/dist/ProfileViewWithData.d.ts.map +1 -1
- package/dist/ProfileViewWithData.js +15 -12
- package/dist/SourceView/index.js +1 -1
- package/dist/SourceView/useSelectedLineRange.js +1 -1
- package/dist/Table/index.d.ts +1 -2
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +9 -25
- package/dist/TopTable/index.d.ts.map +1 -1
- package/dist/TopTable/index.js +3 -7
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/styles.css +1 -1
- package/package.json +7 -7
- package/src/Callgraph/index.tsx +3 -3
- package/src/GraphTooltipArrow/Content.tsx +7 -36
- package/src/GraphTooltipArrow/DockedGraphTooltip/index.tsx +8 -16
- package/src/GraphTooltipArrow/useGraphTooltip/index.ts +10 -42
- package/src/GraphTooltipArrow/useGraphTooltipMetaInfo/index.ts +6 -22
- package/src/ProfileExplorer/ProfileExplorerCompare.tsx +2 -3
- package/src/ProfileExplorer/ProfileExplorerSingle.tsx +1 -5
- package/src/ProfileExplorer/index.tsx +0 -8
- package/src/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.tsx +2 -4
- package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +5 -8
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.tsx +8 -27
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx +5 -4
- package/src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx +9 -54
- package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +9 -20
- package/src/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.ts +1 -9
- package/src/ProfileIcicleGraph/index.tsx +21 -67
- package/src/ProfileMetricsGraph/index.tsx +2 -2
- package/src/ProfileView/FilterByFunctionButton.tsx +15 -9
- package/src/ProfileView/ViewSelector.tsx +6 -7
- package/src/ProfileView/VisualizationPanel.tsx +1 -9
- package/src/ProfileView/index.tsx +8 -23
- package/src/ProfileViewWithData.tsx +15 -18
- package/src/SourceView/index.tsx +1 -1
- package/src/SourceView/useSelectedLineRange.ts +2 -2
- package/src/Table/index.tsx +10 -41
- package/src/TopTable/index.tsx +3 -8
- package/src/index.tsx +4 -0
|
@@ -17,7 +17,7 @@ import {Icon} from '@iconify/react';
|
|
|
17
17
|
import {Table} from 'apache-arrow';
|
|
18
18
|
|
|
19
19
|
import {ProfileType} from '@parca/parser';
|
|
20
|
-
import {getLastItem
|
|
20
|
+
import {getLastItem} from '@parca/utilities';
|
|
21
21
|
|
|
22
22
|
import {hexifyAddress, truncateString, truncateStringReverse} from '../utils';
|
|
23
23
|
import {ExpandOnHover} from './ExpandOnHoverValue';
|
|
@@ -33,7 +33,7 @@ interface GraphTooltipArrowContentProps {
|
|
|
33
33
|
row: number | null;
|
|
34
34
|
level: number;
|
|
35
35
|
isFixed: boolean;
|
|
36
|
-
|
|
36
|
+
compareAbsolute: boolean;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
const NoData = (): React.JSX.Element => {
|
|
@@ -49,7 +49,7 @@ const GraphTooltipArrowContent = ({
|
|
|
49
49
|
row,
|
|
50
50
|
level,
|
|
51
51
|
isFixed,
|
|
52
|
-
|
|
52
|
+
compareAbsolute,
|
|
53
53
|
}: GraphTooltipArrowContentProps): React.JSX.Element => {
|
|
54
54
|
const graphTooltipData = useGraphTooltip({
|
|
55
55
|
table,
|
|
@@ -59,6 +59,7 @@ const GraphTooltipArrowContent = ({
|
|
|
59
59
|
totalUnfiltered,
|
|
60
60
|
row,
|
|
61
61
|
level,
|
|
62
|
+
compareAbsolute,
|
|
62
63
|
});
|
|
63
64
|
|
|
64
65
|
if (graphTooltipData === null) {
|
|
@@ -69,9 +70,7 @@ const GraphTooltipArrowContent = ({
|
|
|
69
70
|
name,
|
|
70
71
|
locationAddress,
|
|
71
72
|
cumulativeText,
|
|
72
|
-
cumulativePerSecondText,
|
|
73
73
|
flatText,
|
|
74
|
-
flatPerSecondText,
|
|
75
74
|
diffText,
|
|
76
75
|
diff,
|
|
77
76
|
row: rowNumber,
|
|
@@ -104,32 +103,12 @@ const GraphTooltipArrowContent = ({
|
|
|
104
103
|
<div>{cumulativeText}</div>
|
|
105
104
|
</td>
|
|
106
105
|
</tr>
|
|
107
|
-
{profileType?.delta ?? false ? (
|
|
108
|
-
<tr>
|
|
109
|
-
<td className="w-1/4"></td>
|
|
110
|
-
<td className="w-3/4">
|
|
111
|
-
<div>{cumulativePerSecondText}</div>
|
|
112
|
-
</td>
|
|
113
|
-
</tr>
|
|
114
|
-
) : (
|
|
115
|
-
<></>
|
|
116
|
-
)}
|
|
117
106
|
<tr>
|
|
118
107
|
<td className="w-1/4 pt-2">Flat</td>
|
|
119
108
|
<td className="w-3/4 pt-2">
|
|
120
109
|
<div>{flatText}</div>
|
|
121
110
|
</td>
|
|
122
111
|
</tr>
|
|
123
|
-
{profileType?.delta ?? false ? (
|
|
124
|
-
<tr>
|
|
125
|
-
<td className="w-1/4"></td>
|
|
126
|
-
<td className="w-3/4">
|
|
127
|
-
<div>{flatPerSecondText}</div>
|
|
128
|
-
</td>
|
|
129
|
-
</tr>
|
|
130
|
-
) : (
|
|
131
|
-
<></>
|
|
132
|
-
)}
|
|
133
112
|
{diff !== 0n && (
|
|
134
113
|
<tr>
|
|
135
114
|
<td className="w-1/4 pt-2">Diff</td>
|
|
@@ -138,7 +117,7 @@ const GraphTooltipArrowContent = ({
|
|
|
138
117
|
</td>
|
|
139
118
|
</tr>
|
|
140
119
|
)}
|
|
141
|
-
<TooltipMetaInfo table={table} row={rowNumber}
|
|
120
|
+
<TooltipMetaInfo table={table} row={rowNumber} />
|
|
142
121
|
</tbody>
|
|
143
122
|
</table>
|
|
144
123
|
</div>
|
|
@@ -153,15 +132,7 @@ const GraphTooltipArrowContent = ({
|
|
|
153
132
|
);
|
|
154
133
|
};
|
|
155
134
|
|
|
156
|
-
const TooltipMetaInfo = ({
|
|
157
|
-
table,
|
|
158
|
-
row,
|
|
159
|
-
navigateTo,
|
|
160
|
-
}: {
|
|
161
|
-
table: Table<any>;
|
|
162
|
-
row: number;
|
|
163
|
-
navigateTo: NavigateFunction;
|
|
164
|
-
}): React.JSX.Element => {
|
|
135
|
+
const TooltipMetaInfo = ({table, row}: {table: Table<any>; row: number}): React.JSX.Element => {
|
|
165
136
|
const {
|
|
166
137
|
labelPairs,
|
|
167
138
|
functionFilename,
|
|
@@ -170,7 +141,7 @@ const TooltipMetaInfo = ({
|
|
|
170
141
|
mappingFile,
|
|
171
142
|
mappingBuildID,
|
|
172
143
|
inlined,
|
|
173
|
-
} = useGraphTooltipMetaInfo({table, row
|
|
144
|
+
} = useGraphTooltipMetaInfo({table, row});
|
|
174
145
|
|
|
175
146
|
const labels = labelPairs.map(
|
|
176
147
|
(l): React.JSX.Element => (
|
|
@@ -32,6 +32,7 @@ interface Props {
|
|
|
32
32
|
level: number;
|
|
33
33
|
profileType?: ProfileType;
|
|
34
34
|
unit?: string;
|
|
35
|
+
compareAbsolute: boolean;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
const InfoSection = ({
|
|
@@ -63,9 +64,10 @@ export const DockedGraphTooltip = ({
|
|
|
63
64
|
level,
|
|
64
65
|
profileType,
|
|
65
66
|
unit,
|
|
67
|
+
compareAbsolute,
|
|
66
68
|
}: Props): JSX.Element => {
|
|
67
69
|
let {width} = useWindowSize();
|
|
68
|
-
const {profileExplorer
|
|
70
|
+
const {profileExplorer} = useParcaContext();
|
|
69
71
|
const {PaddingX} = profileExplorer ?? {PaddingX: 0};
|
|
70
72
|
width = width - PaddingX - 24;
|
|
71
73
|
|
|
@@ -77,6 +79,7 @@ export const DockedGraphTooltip = ({
|
|
|
77
79
|
totalUnfiltered,
|
|
78
80
|
row,
|
|
79
81
|
level,
|
|
82
|
+
compareAbsolute,
|
|
80
83
|
});
|
|
81
84
|
|
|
82
85
|
const {
|
|
@@ -87,21 +90,13 @@ export const DockedGraphTooltip = ({
|
|
|
87
90
|
mappingFile,
|
|
88
91
|
mappingBuildID,
|
|
89
92
|
inlined,
|
|
90
|
-
} = useGraphTooltipMetaInfo({table, row: row ?? 0
|
|
93
|
+
} = useGraphTooltipMetaInfo({table, row: row ?? 0});
|
|
91
94
|
|
|
92
95
|
if (graphTooltipData === null) {
|
|
93
96
|
return <></>;
|
|
94
97
|
}
|
|
95
98
|
|
|
96
|
-
const {
|
|
97
|
-
name,
|
|
98
|
-
cumulativeText,
|
|
99
|
-
cumulativePerSecondText,
|
|
100
|
-
flatText,
|
|
101
|
-
flatPerSecondText,
|
|
102
|
-
diffText,
|
|
103
|
-
diff,
|
|
104
|
-
} = graphTooltipData;
|
|
99
|
+
const {name, cumulativeText, flatText, diffText, diff} = graphTooltipData;
|
|
105
100
|
|
|
106
101
|
const labels = labelPairs.map(
|
|
107
102
|
(l): React.JSX.Element => (
|
|
@@ -118,9 +113,6 @@ export const DockedGraphTooltip = ({
|
|
|
118
113
|
const inlinedText = inlined === null ? 'merged' : inlined ? 'yes' : 'no';
|
|
119
114
|
const addressText = locationAddress !== 0n ? hexifyAddress(locationAddress) : <NoData />;
|
|
120
115
|
|
|
121
|
-
const cumulativeTextBoth = `${cumulativeText}\n${cumulativePerSecondText}`;
|
|
122
|
-
const flatTextBoth = `${flatText}\n${flatPerSecondText}`;
|
|
123
|
-
|
|
124
116
|
return (
|
|
125
117
|
<div
|
|
126
118
|
className="fixed bottom-0 z-20 overflow-hidden rounded-t-lg border-l border-r border-t border-gray-400 bg-white bg-opacity-90 px-8 py-3 dark:border-gray-600 dark:bg-black dark:bg-opacity-80"
|
|
@@ -141,8 +133,8 @@ export const DockedGraphTooltip = ({
|
|
|
141
133
|
)}
|
|
142
134
|
</div>
|
|
143
135
|
<div className="flex justify-between gap-3">
|
|
144
|
-
<InfoSection title="Cumulative" value={
|
|
145
|
-
<InfoSection title="Flat" value={
|
|
136
|
+
<InfoSection title="Cumulative" value={cumulativeText} minWidth="w-44" />
|
|
137
|
+
<InfoSection title="Flat" value={flatText} minWidth="w-44" />
|
|
146
138
|
{diff !== 0n ? <InfoSection title="Diff" value={diffText} minWidth="w-44" /> : null}
|
|
147
139
|
<InfoSection
|
|
148
140
|
title="File"
|
|
@@ -18,18 +18,11 @@ import {divide, valueFormatter} from '@parca/utilities';
|
|
|
18
18
|
|
|
19
19
|
import {
|
|
20
20
|
FIELD_CUMULATIVE,
|
|
21
|
-
FIELD_CUMULATIVE_PER_SECOND,
|
|
22
21
|
FIELD_DIFF,
|
|
23
|
-
FIELD_DIFF_PER_SECOND,
|
|
24
22
|
FIELD_FLAT,
|
|
25
|
-
FIELD_FLAT_PER_SECOND,
|
|
26
23
|
FIELD_LOCATION_ADDRESS,
|
|
27
24
|
} from '../../ProfileIcicleGraph/IcicleGraphArrow';
|
|
28
|
-
import {
|
|
29
|
-
getTextForCumulative,
|
|
30
|
-
getTextForCumulativePerSecond,
|
|
31
|
-
nodeLabel,
|
|
32
|
-
} from '../../ProfileIcicleGraph/IcicleGraphArrow/utils';
|
|
25
|
+
import {getTextForCumulative, nodeLabel} from '../../ProfileIcicleGraph/IcicleGraphArrow/utils';
|
|
33
26
|
|
|
34
27
|
interface Props {
|
|
35
28
|
table: Table<any>;
|
|
@@ -37,6 +30,7 @@ interface Props {
|
|
|
37
30
|
unit?: string;
|
|
38
31
|
total: bigint;
|
|
39
32
|
totalUnfiltered: bigint;
|
|
33
|
+
compareAbsolute: boolean;
|
|
40
34
|
row: number | null;
|
|
41
35
|
level: number;
|
|
42
36
|
}
|
|
@@ -45,9 +39,7 @@ interface GraphTooltipData {
|
|
|
45
39
|
name: string;
|
|
46
40
|
locationAddress: bigint;
|
|
47
41
|
cumulativeText: string;
|
|
48
|
-
cumulativePerSecondText: string;
|
|
49
42
|
flatText: string;
|
|
50
|
-
flatPerSecondText: string;
|
|
51
43
|
diffText: string;
|
|
52
44
|
diff: bigint;
|
|
53
45
|
row: number;
|
|
@@ -57,6 +49,7 @@ export const useGraphTooltip = ({
|
|
|
57
49
|
table,
|
|
58
50
|
profileType,
|
|
59
51
|
unit,
|
|
52
|
+
compareAbsolute,
|
|
60
53
|
total,
|
|
61
54
|
totalUnfiltered,
|
|
62
55
|
row,
|
|
@@ -73,43 +66,23 @@ export const useGraphTooltip = ({
|
|
|
73
66
|
table.getChild(FIELD_CUMULATIVE)?.get(row) !== null
|
|
74
67
|
? BigInt(table.getChild(FIELD_CUMULATIVE)?.get(row))
|
|
75
68
|
: 0n;
|
|
76
|
-
const cumulativePerSecond: number =
|
|
77
|
-
table.getChild(FIELD_CUMULATIVE_PER_SECOND)?.get(row) !== null
|
|
78
|
-
? table.getChild(FIELD_CUMULATIVE_PER_SECOND)?.get(row)
|
|
79
|
-
: 0;
|
|
80
69
|
const flat: bigint =
|
|
81
70
|
table.getChild(FIELD_FLAT)?.get(row) !== null
|
|
82
71
|
? BigInt(table.getChild(FIELD_FLAT)?.get(row))
|
|
83
72
|
: 0n;
|
|
84
|
-
const flatPerSecond: number =
|
|
85
|
-
table.getChild(FIELD_FLAT_PER_SECOND)?.get(row) !== null
|
|
86
|
-
? table.getChild(FIELD_FLAT_PER_SECOND)?.get(row)
|
|
87
|
-
: 0;
|
|
88
73
|
const diff: bigint =
|
|
89
74
|
table.getChild(FIELD_DIFF)?.get(row) !== null
|
|
90
75
|
? BigInt(table.getChild(FIELD_DIFF)?.get(row))
|
|
91
76
|
: 0n;
|
|
92
|
-
const diffPerSecond: number =
|
|
93
|
-
table.getChild(FIELD_DIFF_PER_SECOND)?.get(row) !== null
|
|
94
|
-
? table.getChild(FIELD_DIFF_PER_SECOND)?.get(row)
|
|
95
|
-
: 0;
|
|
96
77
|
|
|
97
78
|
let diffText = '';
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
} else {
|
|
106
|
-
const prevValue = cumulative - diff;
|
|
107
|
-
const diffRatio = diff !== 0n ? divide(diff, prevValue) : 0;
|
|
108
|
-
const diffSign = diff > 0 ? '+' : '';
|
|
109
|
-
const diffValueText = diffSign + valueFormatter(diff, unit, 1);
|
|
110
|
-
const diffPercentageText = diffSign + (diffRatio * 100).toFixed(2) + '%';
|
|
111
|
-
diffText = `${diffValueText} (${diffPercentageText})`;
|
|
112
|
-
}
|
|
79
|
+
const prevValue = cumulative - diff;
|
|
80
|
+
const diffRatio = diff !== 0n ? divide(diff, prevValue) : 0;
|
|
81
|
+
const diffSign = diff > 0 ? '+' : '';
|
|
82
|
+
const diffValueText = diffSign + valueFormatter(diff, unit, 1);
|
|
83
|
+
const diffPercentageText = diffSign + (diffRatio * 100).toFixed(2) + '%';
|
|
84
|
+
|
|
85
|
+
diffText = compareAbsolute ? `${diffValueText} (${diffPercentageText})` : diffPercentageText;
|
|
113
86
|
|
|
114
87
|
const name = nodeLabel(table, row, level, false);
|
|
115
88
|
|
|
@@ -117,12 +90,7 @@ export const useGraphTooltip = ({
|
|
|
117
90
|
name,
|
|
118
91
|
locationAddress,
|
|
119
92
|
cumulativeText: getTextForCumulative(cumulative, totalUnfiltered, total, unit ?? ''),
|
|
120
|
-
cumulativePerSecondText: getTextForCumulativePerSecond(
|
|
121
|
-
cumulativePerSecond,
|
|
122
|
-
unit ?? 'CPU Cores'
|
|
123
|
-
),
|
|
124
93
|
flatText: getTextForCumulative(flat, totalUnfiltered, total, unit ?? ''),
|
|
125
|
-
flatPerSecondText: getTextForCumulativePerSecond(flatPerSecond, unit ?? 'CPU Cores'),
|
|
126
94
|
diffText,
|
|
127
95
|
diff,
|
|
128
96
|
row,
|
|
@@ -15,7 +15,6 @@ import {Table} from 'apache-arrow';
|
|
|
15
15
|
|
|
16
16
|
import {QueryRequest_ReportType} from '@parca/client';
|
|
17
17
|
import {useParcaContext, useURLState} from '@parca/components';
|
|
18
|
-
import type {NavigateFunction} from '@parca/utilities';
|
|
19
18
|
|
|
20
19
|
import {
|
|
21
20
|
FIELD_FUNCTION_FILE_NAME,
|
|
@@ -35,7 +34,6 @@ import {useQuery} from '../../useQuery';
|
|
|
35
34
|
interface Props {
|
|
36
35
|
table: Table<any>;
|
|
37
36
|
row: number;
|
|
38
|
-
navigateTo: NavigateFunction;
|
|
39
37
|
}
|
|
40
38
|
|
|
41
39
|
interface GraphTooltipMetaInfoData {
|
|
@@ -51,11 +49,7 @@ interface GraphTooltipMetaInfoData {
|
|
|
51
49
|
inlined: boolean | null;
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
export const useGraphTooltipMetaInfo = ({
|
|
55
|
-
table,
|
|
56
|
-
row,
|
|
57
|
-
navigateTo,
|
|
58
|
-
}: Props): GraphTooltipMetaInfoData => {
|
|
52
|
+
export const useGraphTooltipMetaInfo = ({table, row}: Props): GraphTooltipMetaInfoData => {
|
|
59
53
|
const mappingFile: string | null = arrowToString(table.getChild(FIELD_MAPPING_FILE)?.get(row));
|
|
60
54
|
const mappingBuildID: string | null = arrowToString(
|
|
61
55
|
table.getChild(FIELD_MAPPING_BUILD_ID)?.get(row)
|
|
@@ -112,28 +106,18 @@ export const useGraphTooltipMetaInfo = ({
|
|
|
112
106
|
])
|
|
113
107
|
.filter(value => value[1] !== '') as Array<[string, string]>;
|
|
114
108
|
|
|
115
|
-
const [dashboardItems, setDashboardItems] = useURLState({
|
|
116
|
-
|
|
117
|
-
navigateTo,
|
|
109
|
+
const [dashboardItems, setDashboardItems] = useURLState<string[]>('dashboard_items', {
|
|
110
|
+
alwaysReturnArray: true,
|
|
118
111
|
});
|
|
119
112
|
|
|
120
113
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
121
|
-
const [unusedBuildId, setSourceBuildId] = useURLState(
|
|
122
|
-
param: 'source_buildid',
|
|
123
|
-
navigateTo,
|
|
124
|
-
});
|
|
114
|
+
const [unusedBuildId, setSourceBuildId] = useURLState('source_buildid');
|
|
125
115
|
|
|
126
116
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
127
|
-
const [unusedFilename, setSourceFilename] = useURLState(
|
|
128
|
-
param: 'source_filename',
|
|
129
|
-
navigateTo,
|
|
130
|
-
});
|
|
117
|
+
const [unusedFilename, setSourceFilename] = useURLState('source_filename');
|
|
131
118
|
|
|
132
119
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
133
|
-
const [unusedLine, setSourceLine] = useURLState(
|
|
134
|
-
param: 'source_line',
|
|
135
|
-
navigateTo,
|
|
136
|
-
});
|
|
120
|
+
const [unusedLine, setSourceLine] = useURLState('source_line');
|
|
137
121
|
|
|
138
122
|
const openFile = (): void => {
|
|
139
123
|
setDashboardItems([dashboardItems[0], 'source']);
|
|
@@ -56,8 +56,8 @@ const ProfileExplorerCompare = ({
|
|
|
56
56
|
closeProfile('B');
|
|
57
57
|
};
|
|
58
58
|
|
|
59
|
-
const [compareAbsolute] = useURLState(
|
|
60
|
-
const [functionFilter] = useURLState(
|
|
59
|
+
const [compareAbsolute] = useURLState('compare_absolute');
|
|
60
|
+
const [functionFilter] = useURLState('filter_by_function');
|
|
61
61
|
|
|
62
62
|
return (
|
|
63
63
|
<>
|
|
@@ -96,7 +96,6 @@ const ProfileExplorerCompare = ({
|
|
|
96
96
|
<div>
|
|
97
97
|
<Card className="mt-2 px-6 py-4">
|
|
98
98
|
<ProfileViewWithData
|
|
99
|
-
navigateTo={navigateTo}
|
|
100
99
|
queryClient={queryClient}
|
|
101
100
|
profileSource={
|
|
102
101
|
new ProfileDiffSource(
|
|
@@ -53,11 +53,7 @@ const ProfileExplorerSingle = ({
|
|
|
53
53
|
</Card>
|
|
54
54
|
{profile != null ? (
|
|
55
55
|
<Card className="mt-2 px-6 py-4">
|
|
56
|
-
<ProfileViewWithData
|
|
57
|
-
queryClient={queryClient}
|
|
58
|
-
profileSource={profile.ProfileSource()}
|
|
59
|
-
navigateTo={navigateTo}
|
|
60
|
-
/>
|
|
56
|
+
<ProfileViewWithData queryClient={queryClient} profileSource={profile.ProfileSource()} />
|
|
61
57
|
</Card>
|
|
62
58
|
) : (
|
|
63
59
|
<></>
|
|
@@ -48,8 +48,6 @@ export const getExpressionAsAString = (expression: string | []): string => {
|
|
|
48
48
|
return x;
|
|
49
49
|
};
|
|
50
50
|
|
|
51
|
-
const DEFAULT_DASHBOARD_ITEMS = ['icicle'];
|
|
52
|
-
|
|
53
51
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
54
52
|
const sanitizeDateRange = (
|
|
55
53
|
time_selection_a: string,
|
|
@@ -149,7 +147,6 @@ const ProfileExplorerApp = ({
|
|
|
149
147
|
compare_b,
|
|
150
148
|
sum_by_b,
|
|
151
149
|
filter_by_function,
|
|
152
|
-
dashboard_items,
|
|
153
150
|
} = queryParams;
|
|
154
151
|
|
|
155
152
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
@@ -231,7 +228,6 @@ const ProfileExplorerApp = ({
|
|
|
231
228
|
return navigateTo('/', {
|
|
232
229
|
...queryParams,
|
|
233
230
|
...SuffixParams(p.HistoryParams(), suffix),
|
|
234
|
-
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
235
231
|
});
|
|
236
232
|
};
|
|
237
233
|
|
|
@@ -274,7 +270,6 @@ const ProfileExplorerApp = ({
|
|
|
274
270
|
to_a: q.to.toString(),
|
|
275
271
|
time_selection_a: q.timeSelection,
|
|
276
272
|
sum_by_a: sumByToParam(q.sumBy),
|
|
277
|
-
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
278
273
|
...mergeParams,
|
|
279
274
|
},
|
|
280
275
|
})
|
|
@@ -286,7 +281,6 @@ const ProfileExplorerApp = ({
|
|
|
286
281
|
return navigateTo('/', {
|
|
287
282
|
...queryParams,
|
|
288
283
|
...SuffixParams(p.HistoryParams(), '_a'),
|
|
289
|
-
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
290
284
|
});
|
|
291
285
|
};
|
|
292
286
|
|
|
@@ -335,7 +329,6 @@ const ProfileExplorerApp = ({
|
|
|
335
329
|
time_selection_a: q.timeSelection,
|
|
336
330
|
sum_by_a: sumByToParam(q.sumBy),
|
|
337
331
|
filter_by_function: filter_by_function ?? '',
|
|
338
|
-
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
339
332
|
...mergeParams,
|
|
340
333
|
},
|
|
341
334
|
})
|
|
@@ -367,7 +360,6 @@ const ProfileExplorerApp = ({
|
|
|
367
360
|
time_selection_b: q.timeSelection,
|
|
368
361
|
sum_by_b: sumByToParam(q.sumBy),
|
|
369
362
|
filter_by_function: filter_by_function ?? '',
|
|
370
|
-
dashboard_items: dashboard_items ?? DEFAULT_DASHBOARD_ITEMS,
|
|
371
363
|
...mergeParams,
|
|
372
364
|
},
|
|
373
365
|
})
|
|
@@ -19,18 +19,16 @@ import cx from 'classnames';
|
|
|
19
19
|
import {useURLState} from '@parca/components';
|
|
20
20
|
import {USER_PREFERENCES, useUserPreference} from '@parca/hooks';
|
|
21
21
|
import {EVERYTHING_ELSE, selectStackColors, useAppSelector} from '@parca/store';
|
|
22
|
-
import type {NavigateFunction} from '@parca/utilities';
|
|
23
22
|
|
|
24
23
|
interface Props {
|
|
25
|
-
navigateTo?: NavigateFunction;
|
|
26
24
|
compareMode?: boolean;
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
const ColorStackLegend = ({
|
|
27
|
+
const ColorStackLegend = ({compareMode = false}: Props): JSX.Element => {
|
|
30
28
|
const [colorProfileName] = useUserPreference<string>(
|
|
31
29
|
USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key
|
|
32
30
|
);
|
|
33
|
-
const [currentSearchString, setSearchString] = useURLState(
|
|
31
|
+
const [currentSearchString, setSearchString] = useURLState('search_string');
|
|
34
32
|
const stackColors = useAppSelector(selectStackColors);
|
|
35
33
|
|
|
36
34
|
const stackColorArray = useMemo(() => {
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
import {memo, useEffect, useMemo, useRef, useState} from 'react';
|
|
15
15
|
|
|
16
16
|
import {Flamegraph} from '@parca/client';
|
|
17
|
+
import {useURLState} from '@parca/components';
|
|
17
18
|
import {ProfileType} from '@parca/parser';
|
|
18
19
|
import {setHoveringNode, useAppDispatch} from '@parca/store';
|
|
19
|
-
import {scaleLinear, selectQueryParam
|
|
20
|
+
import {scaleLinear, selectQueryParam} from '@parca/utilities';
|
|
20
21
|
|
|
21
22
|
import GraphTooltip from '../../GraphTooltip';
|
|
22
23
|
import {useProfileViewContext} from '../../ProfileView/ProfileViewContext';
|
|
@@ -32,7 +33,6 @@ interface IcicleGraphProps {
|
|
|
32
33
|
width?: number;
|
|
33
34
|
curPath: string[];
|
|
34
35
|
setCurPath: (path: string[]) => void;
|
|
35
|
-
navigateTo?: NavigateFunction;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
export const IcicleGraph = memo(function IcicleGraph({
|
|
@@ -43,7 +43,6 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
43
43
|
setCurPath,
|
|
44
44
|
curPath,
|
|
45
45
|
profileType,
|
|
46
|
-
navigateTo,
|
|
47
46
|
}: IcicleGraphProps): JSX.Element {
|
|
48
47
|
const dispatch = useAppDispatch();
|
|
49
48
|
const [height, setHeight] = useState(0);
|
|
@@ -51,7 +50,7 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
51
50
|
const ref = useRef<SVGGElement>(null);
|
|
52
51
|
|
|
53
52
|
const coloredGraph = useColoredGraph(graph);
|
|
54
|
-
const currentSearchString = (
|
|
53
|
+
const [currentSearchString] = useURLState('search_string');
|
|
55
54
|
const {compareMode} = useProfileViewContext();
|
|
56
55
|
const isColorStackLegendEnabled = selectQueryParam('color_stack_legend') === 'true';
|
|
57
56
|
|
|
@@ -74,9 +73,7 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
74
73
|
|
|
75
74
|
return (
|
|
76
75
|
<div onMouseLeave={() => dispatch(setHoveringNode(undefined))}>
|
|
77
|
-
{isColorStackLegendEnabled &&
|
|
78
|
-
<ColorStackLegend navigateTo={navigateTo} compareMode={compareMode} />
|
|
79
|
-
)}
|
|
76
|
+
{isColorStackLegendEnabled && <ColorStackLegend compareMode={compareMode} />}
|
|
80
77
|
<GraphTooltip
|
|
81
78
|
unit={profileType?.sampleUnit ?? ''}
|
|
82
79
|
total={total}
|
|
@@ -113,7 +110,7 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
113
110
|
path={[]}
|
|
114
111
|
level={0}
|
|
115
112
|
isRoot={true}
|
|
116
|
-
searchString={currentSearchString}
|
|
113
|
+
searchString={currentSearchString as string}
|
|
117
114
|
compareMode={compareMode}
|
|
118
115
|
/>
|
|
119
116
|
</g>
|
|
@@ -19,7 +19,6 @@ import cx from 'classnames';
|
|
|
19
19
|
import {useURLState} from '@parca/components';
|
|
20
20
|
import {USER_PREFERENCES, useCurrentColorProfile, useUserPreference} from '@parca/hooks';
|
|
21
21
|
import {EVERYTHING_ELSE, selectDarkMode, useAppSelector} from '@parca/store';
|
|
22
|
-
import {type NavigateFunction} from '@parca/utilities';
|
|
23
22
|
|
|
24
23
|
import {getMappingColors} from '.';
|
|
25
24
|
import useMappingList from './useMappingList';
|
|
@@ -27,24 +26,18 @@ import useMappingList from './useMappingList';
|
|
|
27
26
|
interface Props {
|
|
28
27
|
mappings?: string[];
|
|
29
28
|
loading?: boolean;
|
|
30
|
-
navigateTo?: NavigateFunction;
|
|
31
29
|
compareMode?: boolean;
|
|
32
30
|
}
|
|
33
31
|
|
|
34
|
-
const ColorStackLegend = ({
|
|
35
|
-
mappings,
|
|
36
|
-
navigateTo,
|
|
37
|
-
compareMode = false,
|
|
38
|
-
loading,
|
|
39
|
-
}: Props): React.JSX.Element => {
|
|
32
|
+
const ColorStackLegend = ({mappings, compareMode = false, loading}: Props): React.JSX.Element => {
|
|
40
33
|
const isDarkMode = useAppSelector(selectDarkMode);
|
|
41
34
|
const currentColorProfile = useCurrentColorProfile();
|
|
42
35
|
const [colorProfileName] = useUserPreference<string>(
|
|
43
36
|
USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key
|
|
44
37
|
);
|
|
45
|
-
const [currentSearchString, setSearchString] = useURLState({
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
const [currentSearchString, setSearchString] = useURLState<string[]>('binary_frame_filter', {
|
|
39
|
+
alwaysReturnArray: true,
|
|
40
|
+
defaultValue: [],
|
|
48
41
|
});
|
|
49
42
|
|
|
50
43
|
const mappingsList = useMappingList(mappings);
|
|
@@ -79,7 +72,7 @@ const ColorStackLegend = ({
|
|
|
79
72
|
}
|
|
80
73
|
|
|
81
74
|
return (
|
|
82
|
-
<div className="my-4 flex w-full flex-wrap justify-start">
|
|
75
|
+
<div className="my-4 flex w-full flex-wrap justify-start column-gap-2">
|
|
83
76
|
{stackColorArray.map(([feature, color]) => {
|
|
84
77
|
const filteringAllowed = feature !== EVERYTHING_ELSE;
|
|
85
78
|
const isHighlighted =
|
|
@@ -88,7 +81,7 @@ const ColorStackLegend = ({
|
|
|
88
81
|
<div
|
|
89
82
|
key={feature}
|
|
90
83
|
className={cx(
|
|
91
|
-
'flex-no-wrap mb-1 flex w-
|
|
84
|
+
'flex-no-wrap mb-1 flex w-[19.25%] items-center justify-between text-ellipsis p-1',
|
|
92
85
|
{
|
|
93
86
|
'cursor-pointer': filteringAllowed,
|
|
94
87
|
'bg-gray-200 dark:bg-gray-800': isHighlighted,
|
|
@@ -100,12 +93,7 @@ const ColorStackLegend = ({
|
|
|
100
93
|
}
|
|
101
94
|
|
|
102
95
|
// Check if the current search string is defined and an array
|
|
103
|
-
const updatedSearchString =
|
|
104
|
-
? [...currentSearchString, feature] // If array, append the feature
|
|
105
|
-
: // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
|
|
106
|
-
currentSearchString // If not array, preserve current value
|
|
107
|
-
? currentSearchString.split(',') // If string, split by commas
|
|
108
|
-
: [feature]; // If undefined, initialize array with feature
|
|
96
|
+
const updatedSearchString = [...currentSearchString, feature]; // If array, append the feature
|
|
109
97
|
|
|
110
98
|
setSearchString(updatedSearchString);
|
|
111
99
|
}}
|
|
@@ -123,15 +111,8 @@ const ColorStackLegend = ({
|
|
|
123
111
|
<Icon
|
|
124
112
|
icon="radix-icons:cross-circled"
|
|
125
113
|
onClick={e => {
|
|
126
|
-
let searchString: string[] = [];
|
|
127
|
-
if (typeof currentSearchString === 'string') {
|
|
128
|
-
searchString.push(currentSearchString);
|
|
129
|
-
} else {
|
|
130
|
-
searchString = currentSearchString;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
114
|
// remove the current feature from the search string array of strings
|
|
134
|
-
setSearchString(
|
|
115
|
+
setSearchString(currentSearchString.filter((f: string) => f !== feature));
|
|
135
116
|
e.stopPropagation();
|
|
136
117
|
}}
|
|
137
118
|
/>
|
|
@@ -19,7 +19,7 @@ import {Tooltip} from 'react-tooltip';
|
|
|
19
19
|
import {useParcaContext} from '@parca/components';
|
|
20
20
|
import {USER_PREFERENCES, useUserPreference} from '@parca/hooks';
|
|
21
21
|
import {ProfileType} from '@parca/parser';
|
|
22
|
-
import {getLastItem
|
|
22
|
+
import {getLastItem} from '@parca/utilities';
|
|
23
23
|
|
|
24
24
|
import {useGraphTooltip} from '../../GraphTooltipArrow/useGraphTooltip';
|
|
25
25
|
import {useGraphTooltipMetaInfo} from '../../GraphTooltipArrow/useGraphTooltipMetaInfo';
|
|
@@ -34,7 +34,7 @@ interface ContextMenuProps {
|
|
|
34
34
|
totalUnfiltered: bigint;
|
|
35
35
|
row: number;
|
|
36
36
|
level: number;
|
|
37
|
-
|
|
37
|
+
compareAbsolute: boolean;
|
|
38
38
|
trackVisibility: (isVisible: boolean) => void;
|
|
39
39
|
curPath: string[];
|
|
40
40
|
setCurPath: (path: string[]) => void;
|
|
@@ -49,7 +49,7 @@ const ContextMenu = ({
|
|
|
49
49
|
totalUnfiltered,
|
|
50
50
|
row,
|
|
51
51
|
level,
|
|
52
|
-
|
|
52
|
+
compareAbsolute,
|
|
53
53
|
trackVisibility,
|
|
54
54
|
curPath,
|
|
55
55
|
setCurPath,
|
|
@@ -71,6 +71,7 @@ const ContextMenu = ({
|
|
|
71
71
|
totalUnfiltered,
|
|
72
72
|
row,
|
|
73
73
|
level,
|
|
74
|
+
compareAbsolute,
|
|
74
75
|
});
|
|
75
76
|
|
|
76
77
|
const {
|
|
@@ -83,7 +84,7 @@ const ContextMenu = ({
|
|
|
83
84
|
mappingFile,
|
|
84
85
|
mappingBuildID,
|
|
85
86
|
inlined,
|
|
86
|
-
} = useGraphTooltipMetaInfo({table, row
|
|
87
|
+
} = useGraphTooltipMetaInfo({table, row});
|
|
87
88
|
|
|
88
89
|
if (contextMenuData === null) {
|
|
89
90
|
return <></>;
|