@parca/profile 0.19.51 → 0.19.53
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 +12 -0
- package/dist/ProfileExplorer/index.js +3 -3
- package/dist/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.js +4 -3
- package/dist/ProfileFlameGraph/FlameGraphArrow/index.d.ts +2 -0
- package/dist/ProfileFlameGraph/FlameGraphArrow/index.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/FlameGraphArrow/index.js +7 -36
- package/dist/ProfileFlameGraph/index.d.ts +1 -1
- package/dist/ProfileFlameGraph/index.d.ts.map +1 -1
- package/dist/ProfileFlameGraph/index.js +14 -6
- package/dist/ProfileView/components/DashboardItems/index.d.ts +0 -2
- package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
- package/dist/ProfileView/components/ProfileFilters/useProfileFilters.d.ts.map +1 -1
- package/dist/ProfileView/components/ProfileFilters/useProfileFilters.js +10 -4
- package/dist/ProfileView/hooks/useResetFlameGraphState.d.ts +2 -0
- package/dist/ProfileView/hooks/useResetFlameGraphState.d.ts.map +1 -0
- package/dist/ProfileView/hooks/{useResetStateOnNewSearch.js → useResetFlameGraphState.js} +1 -1
- package/dist/ProfileView/hooks/useVisualizationState.d.ts +0 -2
- package/dist/ProfileView/hooks/useVisualizationState.d.ts.map +1 -1
- package/dist/ProfileView/hooks/useVisualizationState.js +5 -5
- package/dist/ProfileView/index.d.ts.map +1 -1
- package/dist/ProfileView/index.js +1 -3
- package/dist/ProfileViewWithData.js +1 -1
- package/package.json +11 -11
- package/src/ProfileExplorer/index.tsx +3 -3
- package/src/ProfileFlameGraph/FlameGraphArrow/FlameGraphNodes.tsx +4 -4
- package/src/ProfileFlameGraph/FlameGraphArrow/index.tsx +13 -42
- package/src/ProfileFlameGraph/index.tsx +15 -5
- package/src/ProfileView/components/DashboardItems/index.tsx +0 -2
- package/src/ProfileView/components/ProfileFilters/useProfileFilters.ts +10 -4
- package/src/ProfileView/hooks/{useResetStateOnNewSearch.ts → useResetFlameGraphState.ts} +1 -1
- package/src/ProfileView/hooks/useVisualizationState.ts +6 -7
- package/src/ProfileView/index.tsx +0 -4
- package/src/ProfileViewWithData.tsx +1 -1
- package/dist/ProfileView/hooks/useResetStateOnNewSearch.d.ts +0 -2
- package/dist/ProfileView/hooks/useResetStateOnNewSearch.d.ts.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,18 @@
|
|
|
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.19.53](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.52...@parca/profile@0.19.53) (2025-09-15)
|
|
7
|
+
|
|
8
|
+
## 0.24.2 (2025-09-10)
|
|
9
|
+
|
|
10
|
+
**Note:** Version bump only for package @parca/profile
|
|
11
|
+
|
|
12
|
+
## 0.19.52 (2025-09-15)
|
|
13
|
+
|
|
14
|
+
## 0.24.2 (2025-09-10)
|
|
15
|
+
|
|
16
|
+
**Note:** Version bump only for package @parca/profile
|
|
17
|
+
|
|
6
18
|
## 0.19.51 (2025-09-10)
|
|
7
19
|
|
|
8
20
|
## 0.24.1 (2025-09-09)
|
|
@@ -19,7 +19,7 @@ import { createStore } from '@parca/store';
|
|
|
19
19
|
import { capitalizeOnlyFirstLetter, safeDecode } from '@parca/utilities';
|
|
20
20
|
import { ProfileSelectionFromParams, SuffixParams } from '..';
|
|
21
21
|
import { useProfileTypes } from '../ProfileSelector';
|
|
22
|
-
import {
|
|
22
|
+
import { useResetFlameGraphState } from '../ProfileView/hooks/useResetFlameGraphState';
|
|
23
23
|
import { useResetStateOnProfileTypeChange } from '../ProfileView/hooks/useResetStateOnProfileTypeChange';
|
|
24
24
|
import { sumByToParam, useSumByFromParams } from '../useSumBy';
|
|
25
25
|
import ProfileExplorerCompare from './ProfileExplorerCompare';
|
|
@@ -89,7 +89,7 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
89
89
|
const [profileA, setProfileA] = useState(null);
|
|
90
90
|
const [profileB, setProfileB] = useState(null);
|
|
91
91
|
const resetStateOnProfileTypeChange = useResetStateOnProfileTypeChange();
|
|
92
|
-
const
|
|
92
|
+
const resetFlameGraphState = useResetFlameGraphState();
|
|
93
93
|
const sumByA = useSumByFromParams(sum_by_a);
|
|
94
94
|
const sumByB = useSumByFromParams(sum_by_b);
|
|
95
95
|
useEffect(() => {
|
|
@@ -156,7 +156,7 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
156
156
|
}
|
|
157
157
|
else {
|
|
158
158
|
// Reset the state when a new search is performed.
|
|
159
|
-
|
|
159
|
+
resetFlameGraphState();
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
162
|
const mergeParams = q.mergeFrom !== undefined && q.mergeTo !== undefined
|
|
@@ -51,7 +51,6 @@ export const FlameNode = React.memo(function FlameNodeNoMemo({ table, row, color
|
|
|
51
51
|
? BigInt(valueOffsetColumn?.get(row))
|
|
52
52
|
: 0n;
|
|
53
53
|
const colorAttribute = colorBy === 'filename' ? filename : colorBy === 'binary' ? mappingFile : null;
|
|
54
|
-
const colorsMap = colors;
|
|
55
54
|
const hoveringName = hoveringRow !== undefined ? arrowToString(functionNameColumn?.get(hoveringRow)) : '';
|
|
56
55
|
const shouldBeHighlighted = functionName != null && hoveringName != null && functionName === hoveringName;
|
|
57
56
|
const colorResult = useNodeColor({
|
|
@@ -59,7 +58,7 @@ export const FlameNode = React.memo(function FlameNodeNoMemo({ table, row, color
|
|
|
59
58
|
compareMode,
|
|
60
59
|
cumulative,
|
|
61
60
|
diff,
|
|
62
|
-
colorsMap,
|
|
61
|
+
colorsMap: colors,
|
|
63
62
|
colorAttribute,
|
|
64
63
|
});
|
|
65
64
|
const name = useMemo(() => {
|
|
@@ -138,5 +137,7 @@ export const FlameNode = React.memo(function FlameNodeNoMemo({ table, row, color
|
|
|
138
137
|
prevProps.hoveringRow === nextProps.hoveringRow &&
|
|
139
138
|
prevProps.totalWidth === nextProps.totalWidth &&
|
|
140
139
|
prevProps.height === nextProps.height &&
|
|
141
|
-
prevProps.effectiveDepth === nextProps.effectiveDepth
|
|
140
|
+
prevProps.effectiveDepth === nextProps.effectiveDepth &&
|
|
141
|
+
prevProps.colorBy === nextProps.colorBy &&
|
|
142
|
+
prevProps.colors === nextProps.colors);
|
|
142
143
|
});
|
|
@@ -37,6 +37,8 @@ interface FlameGraphArrowProps {
|
|
|
37
37
|
setCurPath: (path: CurrentPathFrame[]) => void;
|
|
38
38
|
isHalfScreen: boolean;
|
|
39
39
|
mappingsListFromMetadata: string[];
|
|
40
|
+
filenamesListFromMetadata: string[];
|
|
41
|
+
colorBy: string;
|
|
40
42
|
compareAbsolute: boolean;
|
|
41
43
|
isFlameChart?: boolean;
|
|
42
44
|
isRenderedAsFlamegraph?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileFlameGraph/FlameGraphArrow/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAQN,MAAM,OAAO,CAAC;AAKf,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileFlameGraph/FlameGraphArrow/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAQN,MAAM,OAAO,CAAC;AAKf,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAC,KAAK,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAIlD,OAAO,EAAuB,aAAa,EAAC,MAAM,mBAAmB,CAAC;AAKtE,OAAO,EACL,gBAAgB,EAMjB,MAAM,SAAS,CAAC;AAEjB,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAC/C,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AACjD,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,eAAe,cAAc,CAAC;AAC3C,eAAO,MAAM,cAAc,aAAa,CAAC;AACzC,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AACjE,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAC7D,eAAO,MAAM,yBAAyB,uBAAuB,CAAC;AAC9D,eAAO,MAAM,cAAc,aAAa,CAAC;AACzC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAC7C,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AAEjD,UAAU,oBAAoB;IAC5B,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,UAAU,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAC/C,YAAY,EAAE,OAAO,CAAC;IACtB,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,yBAAyB,EAAE,MAAM,EAAE,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,OAAO,CAAC;IACzB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,gBAAgB,GAC3B,cAAc,MAAM,EAAE,EACtB,YAAY,OAAO,EACnB,qBAAqB,WAAW,KAC/B,aAQF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,eAAe,MAAM,EAAE,EACvB,YAAY,OAAO,EACnB,qBAAqB,WAAW,KAC/B,aAQF,CAAC;AAIF,eAAO,MAAM,eAAe,kDA0P1B,CAAC;AAEH,eAAe,eAAe,CAAC"}
|
|
@@ -14,20 +14,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
14
14
|
import { memo, useCallback, useDeferredValue, useEffect, useMemo, useRef, useState, } from 'react';
|
|
15
15
|
import { tableFromIPC } from 'apache-arrow';
|
|
16
16
|
import { useContextMenu } from 'react-contexify';
|
|
17
|
-
import { useParcaContext
|
|
17
|
+
import { useParcaContext } from '@parca/components';
|
|
18
18
|
import { USER_PREFERENCES, useCurrentColorProfile, useUserPreference } from '@parca/hooks';
|
|
19
19
|
import { getColorForFeature, selectDarkMode, useAppSelector } from '@parca/store';
|
|
20
|
-
import { getLastItem } from '@parca/utilities';
|
|
21
20
|
import { useProfileFilters } from '../../ProfileView/components/ProfileFilters/useProfileFilters';
|
|
22
21
|
import { useProfileViewContext } from '../../ProfileView/context/ProfileViewContext';
|
|
23
22
|
import ContextMenuWrapper from './ContextMenuWrapper';
|
|
24
23
|
import { FlameNode, RowHeight } from './FlameGraphNodes';
|
|
25
24
|
import { MemoizedTooltip } from './MemoizedTooltip';
|
|
26
25
|
import { TooltipProvider } from './TooltipContext';
|
|
27
|
-
import { useFilenamesList } from './useMappingList';
|
|
28
26
|
import { useScrollViewport } from './useScrollViewport';
|
|
29
27
|
import { useVisibleNodes } from './useVisibleNodes';
|
|
30
|
-
import {
|
|
28
|
+
import { extractFeature, extractFilenameFeature, getCurrentPathFrameData, getMaxDepth, isCurrentPathFrameMatch, } from './utils';
|
|
31
29
|
export const FIELD_LABELS_ONLY = 'labels_only';
|
|
32
30
|
export const FIELD_MAPPING_FILE = 'mapping_file';
|
|
33
31
|
export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
|
|
@@ -66,7 +64,7 @@ export const getFilenameColors = (filenamesList, isDarkMode, currentColorProfile
|
|
|
66
64
|
return colors;
|
|
67
65
|
};
|
|
68
66
|
const noop = () => { };
|
|
69
|
-
export const FlameGraphArrow = memo(function FlameGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, profileType, profileSource, compareAbsolute, isFlameChart = false, isRenderedAsFlamegraph = false, isInSandwichView = false, tooltipId = 'default', maxFrameCount, isExpanded = false, }) {
|
|
67
|
+
export const FlameGraphArrow = memo(function FlameGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, profileType, profileSource, compareAbsolute, isFlameChart = false, isRenderedAsFlamegraph = false, isInSandwichView = false, tooltipId = 'default', maxFrameCount, isExpanded = false, mappingsListFromMetadata, filenamesListFromMetadata, colorBy, }) {
|
|
70
68
|
const [highlightSimilarStacksPreference] = useUserPreference(USER_PREFERENCES.HIGHLIGHT_SIMILAR_STACKS.key);
|
|
71
69
|
const [hoveringRow, setHoveringRow] = useState(undefined);
|
|
72
70
|
const [dockedMetainfo] = useUserPreference(USER_PREFERENCES.GRAPH_METAINFO_DOCKED.key);
|
|
@@ -87,42 +85,15 @@ export const FlameGraphArrow = memo(function FlameGraphArrow({ arrow, total, fil
|
|
|
87
85
|
const { compareMode } = useProfileViewContext();
|
|
88
86
|
const currentColorProfile = useCurrentColorProfile();
|
|
89
87
|
const colorForSimilarNodes = currentColorProfile.colorForSimilarNodes;
|
|
90
|
-
const [colorBy, _] = useURLState('color_by');
|
|
91
88
|
const colorByValue = colorBy === undefined || colorBy === '' ? 'binary' : colorBy;
|
|
92
|
-
const filenamesList = useFilenamesList(table);
|
|
93
|
-
const mappingsList = useMemo(() => {
|
|
94
|
-
// Read the mappings from the dictionary that contains all mapping strings.
|
|
95
|
-
// This is great, as might only have a dozen or so mappings,
|
|
96
|
-
// and don't need to read through all the rows (potentially thousands).
|
|
97
|
-
const mappingsDict = table.getChild(FIELD_MAPPING_FILE);
|
|
98
|
-
const mappings = mappingsDict?.data
|
|
99
|
-
.map(mapping => {
|
|
100
|
-
if (mapping.dictionary == null) {
|
|
101
|
-
return [];
|
|
102
|
-
}
|
|
103
|
-
const len = mapping.dictionary.length;
|
|
104
|
-
const entries = [];
|
|
105
|
-
for (let i = 0; i < len; i++) {
|
|
106
|
-
const fn = arrowToString(mapping.dictionary.get(i));
|
|
107
|
-
entries.push(getLastItem(fn) ?? '');
|
|
108
|
-
}
|
|
109
|
-
return entries;
|
|
110
|
-
})
|
|
111
|
-
.flat() ?? [];
|
|
112
|
-
// We add a EVERYTHING ELSE mapping to the list.
|
|
113
|
-
mappings.push('');
|
|
114
|
-
// We sort the mappings alphabetically to make sure that the order is always the same.
|
|
115
|
-
mappings.sort((a, b) => a.localeCompare(b));
|
|
116
|
-
return mappings;
|
|
117
|
-
}, [table]);
|
|
118
89
|
const filenameColors = useMemo(() => {
|
|
119
|
-
const colors = getFilenameColors(
|
|
90
|
+
const colors = getFilenameColors(filenamesListFromMetadata, isDarkMode, currentColorProfile);
|
|
120
91
|
return colors;
|
|
121
|
-
}, [isDarkMode,
|
|
92
|
+
}, [isDarkMode, filenamesListFromMetadata, currentColorProfile]);
|
|
122
93
|
const mappingColors = useMemo(() => {
|
|
123
|
-
const colors = getMappingColors(
|
|
94
|
+
const colors = getMappingColors(mappingsListFromMetadata, isDarkMode, currentColorProfile);
|
|
124
95
|
return colors;
|
|
125
|
-
}, [isDarkMode,
|
|
96
|
+
}, [isDarkMode, mappingsListFromMetadata, currentColorProfile]);
|
|
126
97
|
const colorByList = {
|
|
127
98
|
filename: filenameColors,
|
|
128
99
|
binary: mappingColors,
|
|
@@ -31,6 +31,6 @@ export declare const validateFlameChartQuery: (profileSource: MergedProfileSourc
|
|
|
31
31
|
isNonDelta: boolean;
|
|
32
32
|
isDurationTooLong: boolean;
|
|
33
33
|
};
|
|
34
|
-
declare const ProfileFlameGraph: ({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isFlameChart, profileSource, isInSandwichView, isRenderedAsFlamegraph, tooltipId, maxFrameCount, isExpanded, }: ProfileFlameGraphProps) => JSX.Element;
|
|
34
|
+
declare const ProfileFlameGraph: ({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isFlameChart, profileSource, isInSandwichView, isRenderedAsFlamegraph, tooltipId, maxFrameCount, isExpanded, metadataLoading, }: ProfileFlameGraphProps) => JSX.Element;
|
|
35
35
|
export default ProfileFlameGraph;
|
|
36
36
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileFlameGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAM7F,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAO9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAI1C,OAAO,EAAC,mBAAmB,EAAE,aAAa,EAAC,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileFlameGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAM7F,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAO9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAI1C,OAAO,EAAC,mBAAmB,EAAE,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAOpE,OAAO,EAAC,gBAAgB,EAA0B,MAAM,yBAAyB,CAAC;AAIlF,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC;IACtC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAUD,eAAO,MAAM,uBAAuB,GAClC,eAAe,mBAAmB,KACjC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAMpE,CAAC;AAEF,QAAA,MAAM,iBAAiB,GAAqC,qQAoBzD,sBAAsB,KAAG,GAAG,CAAC,OA0T/B,CAAC;AAEF,eAAe,iBAAiB,CAAC"}
|
|
@@ -20,9 +20,10 @@ import { testId } from '@parca/test-utils';
|
|
|
20
20
|
import { capitalizeOnlyFirstLetter, divide } from '@parca/utilities';
|
|
21
21
|
import DiffLegend from '../ProfileView/components/DiffLegend';
|
|
22
22
|
import { useProfileViewContext } from '../ProfileView/context/ProfileViewContext';
|
|
23
|
+
import { useProfileMetadata } from '../ProfileView/hooks/useProfileMetadata';
|
|
24
|
+
import { useVisualizationState } from '../ProfileView/hooks/useVisualizationState';
|
|
23
25
|
import { TimelineGuide } from '../TimelineGuide';
|
|
24
26
|
import { FlameGraphArrow } from './FlameGraphArrow';
|
|
25
|
-
import useMappingList from './FlameGraphArrow/useMappingList';
|
|
26
27
|
import { boundsFromProfileSource } from './FlameGraphArrow/utils';
|
|
27
28
|
const numberFormatter = new Intl.NumberFormat('en-US');
|
|
28
29
|
const ErrorContent = ({ errorMessage }) => {
|
|
@@ -35,11 +36,12 @@ export const validateFlameChartQuery = (profileSource) => {
|
|
|
35
36
|
const isDurationTooLong = duration > 60000000000n; // 60 seconds in nanoseconds
|
|
36
37
|
return { isValid: !isNonDelta && !isDurationTooLong, isNonDelta, isDurationTooLong };
|
|
37
38
|
};
|
|
38
|
-
const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isFlameChart = false, profileSource, isInSandwichView = false, isRenderedAsFlamegraph = false, tooltipId, maxFrameCount, isExpanded = false, }) {
|
|
39
|
+
const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isFlameChart = false, profileSource, isInSandwichView = false, isRenderedAsFlamegraph = false, tooltipId, maxFrameCount, isExpanded = false, metadataLoading = false, }) {
|
|
39
40
|
const { onError, authenticationErrorMessage, isDarkMode, flamechartHelpText } = useParcaContext();
|
|
40
41
|
const { compareMode } = useProfileViewContext();
|
|
41
42
|
const [isLoading, setIsLoading] = useState(true);
|
|
42
43
|
const [flameChartRef, { height: flameChartHeight }] = useMeasure();
|
|
44
|
+
const { colorBy, setColorBy } = useVisualizationState();
|
|
43
45
|
// Create local state for paths when in sandwich view to avoid URL updates
|
|
44
46
|
const [localCurPathArrow, setLocalCurPathArrow] = useState([]);
|
|
45
47
|
const setCurPathArrowWrapper = useCallback((path) => {
|
|
@@ -52,8 +54,12 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filt
|
|
|
52
54
|
}, [isInSandwichView, setNewCurPathArrow]);
|
|
53
55
|
// Determine which paths to use based on isInSandwichView flag
|
|
54
56
|
const effectiveCurPathArrow = isInSandwichView ? localCurPathArrow : curPathArrow;
|
|
55
|
-
const mappingsList =
|
|
56
|
-
|
|
57
|
+
const { mappingsList, filenamesList } = useProfileMetadata({
|
|
58
|
+
flamegraphArrow: arrow,
|
|
59
|
+
metadataMappingFiles,
|
|
60
|
+
metadataLoading,
|
|
61
|
+
colorBy,
|
|
62
|
+
});
|
|
57
63
|
// By default, we want delta profiles (CPU) to be relatively compared.
|
|
58
64
|
// For non-delta profiles, like goroutines or memory, we want the profiles to be compared absolutely.
|
|
59
65
|
const compareAbsoluteDefault = profileType?.delta === false ? 'true' : 'false';
|
|
@@ -119,7 +125,7 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filt
|
|
|
119
125
|
if (total === 0n && !loading)
|
|
120
126
|
return _jsx("div", { className: "mx-auto text-center", children: "Profile has no samples" });
|
|
121
127
|
if (arrow !== undefined) {
|
|
122
|
-
return (_jsxs("div", { className: "relative", children: [isFlameChart ? (_jsx(TimelineGuide, { bounds: boundsFromProfileSource(profileSource), width: width, height: flameChartHeight ?? 420, margin: 0, ticks: 12, timeUnit: "nanoseconds" })) : null, _jsx("div", { ref: flameChartRef, children: _jsx(FlameGraphArrow, { width: width, arrow: arrow, total: total, filtered: filtered, curPath: effectiveCurPathArrow, setCurPath: setCurPathArrowWrapper, profileType: profileType, isHalfScreen: isHalfScreen, mappingsListFromMetadata: mappingsList, compareAbsolute: isCompareAbsolute, isFlameChart: isFlameChart, profileSource: profileSource, isRenderedAsFlamegraph: isRenderedAsFlamegraph, isInSandwichView: isInSandwichView, tooltipId: tooltipId, maxFrameCount: maxFrameCount, isExpanded: isExpanded }) })] }));
|
|
128
|
+
return (_jsxs("div", { className: "relative", children: [isFlameChart ? (_jsx(TimelineGuide, { bounds: boundsFromProfileSource(profileSource), width: width, height: flameChartHeight ?? 420, margin: 0, ticks: 12, timeUnit: "nanoseconds" })) : null, _jsx("div", { ref: flameChartRef, children: _jsx(FlameGraphArrow, { width: width, arrow: arrow, total: total, filtered: filtered, curPath: effectiveCurPathArrow, setCurPath: setCurPathArrowWrapper, profileType: profileType, isHalfScreen: isHalfScreen, mappingsListFromMetadata: mappingsList, filenamesListFromMetadata: filenamesList, compareAbsolute: isCompareAbsolute, isFlameChart: isFlameChart, profileSource: profileSource, isRenderedAsFlamegraph: isRenderedAsFlamegraph, isInSandwichView: isInSandwichView, tooltipId: tooltipId, maxFrameCount: maxFrameCount, isExpanded: isExpanded, colorBy: colorBy }) })] }));
|
|
123
129
|
}
|
|
124
130
|
}, [
|
|
125
131
|
isLoading,
|
|
@@ -131,7 +137,6 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filt
|
|
|
131
137
|
profileType,
|
|
132
138
|
isHalfScreen,
|
|
133
139
|
isDarkMode,
|
|
134
|
-
mappingsList,
|
|
135
140
|
isCompareAbsolute,
|
|
136
141
|
isFlameChart,
|
|
137
142
|
profileSource,
|
|
@@ -145,6 +150,9 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({ arrow, total, filt
|
|
|
145
150
|
tooltipId,
|
|
146
151
|
maxFrameCount,
|
|
147
152
|
isExpanded,
|
|
153
|
+
mappingsList,
|
|
154
|
+
filenamesList,
|
|
155
|
+
colorBy,
|
|
148
156
|
]);
|
|
149
157
|
useEffect(() => {
|
|
150
158
|
if (isTrimmed) {
|
|
@@ -15,8 +15,6 @@ interface GetDashboardItemProps {
|
|
|
15
15
|
profileSource: ProfileSource;
|
|
16
16
|
total: bigint;
|
|
17
17
|
filtered: bigint;
|
|
18
|
-
curPath: string[];
|
|
19
|
-
setNewCurPath: (path: string[]) => void;
|
|
20
18
|
curPathArrow: CurrentPathFrame[];
|
|
21
19
|
setNewCurPathArrow: (path: CurrentPathFrame[]) => void;
|
|
22
20
|
perf?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,kDAAkD,CAAC;AAClF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,OAAO,KAAK,EACV,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,YAAY,EAAE,YAAY,CAAC;IAC3B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;IACF,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,eAAO,MAAM,gBAAgB,GAAI,qLAe9B,qBAAqB,KAAG,GAAG,CAAC,OA+F9B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useProfileFilters.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ProfileFilters/useProfileFilters.ts"],"names":[],"mappings":"AAeA,OAAO,EAAC,KAAK,MAAM,EAA6C,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"useProfileFilters.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ProfileFilters/useProfileFilters.ts"],"names":[],"mappings":"AAeA,OAAO,EAAC,KAAK,MAAM,EAA6C,MAAM,eAAe,CAAC;AAMtF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAC;IAClC,KAAK,CAAC,EAAE,eAAe,GAAG,QAAQ,GAAG,aAAa,GAAG,UAAU,GAAG,SAAS,GAAG,aAAa,CAAC;IAC5F,SAAS,CAAC,EAAE,OAAO,GAAG,WAAW,GAAG,UAAU,GAAG,cAAc,CAAC;IAChE,KAAK,EAAE,MAAM,CAAC;CACf;AAqBD,eAAO,MAAM,uBAAuB,GAAI,cAAc,MAAM,EAAE,KAAG,aAAa,EA+E7E,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAAI,gBAAgB,aAAa,EAAE,KAAG,MAAM,EAmF7E,CAAC;AAEF,eAAO,MAAM,iBAAiB,QAAO;IACnC,YAAY,EAAE,aAAa,EAAE,CAAC;IAC9B,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,mBAAmB,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC;IACpE,YAAY,EAAE,MAAM,IAAI,CAAC;CA2L1B,CAAC"}
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
14
|
+
import { useResetFlameGraphState } from '../../hooks/useResetFlameGraphState';
|
|
14
15
|
import { getPresetByKey, isPresetKey } from './filterPresets';
|
|
15
16
|
import { useProfileFiltersUrlState } from './useProfileFiltersUrlState';
|
|
16
17
|
const createStringCondition = (matchType, value) => ({
|
|
@@ -182,6 +183,7 @@ export const convertToProtoFilters = (profileFilters) => {
|
|
|
182
183
|
};
|
|
183
184
|
export const useProfileFilters = () => {
|
|
184
185
|
const { appliedFilters, setAppliedFilters } = useProfileFiltersUrlState();
|
|
186
|
+
const resetFlameGraphState = useResetFlameGraphState();
|
|
185
187
|
const [localFilters, setLocalFilters] = useState(appliedFilters ?? []);
|
|
186
188
|
const lastAppliedFiltersRef = useRef([]);
|
|
187
189
|
const localFiltersRef = useRef(localFilters);
|
|
@@ -259,9 +261,10 @@ export const useProfileFilters = () => {
|
|
|
259
261
|
// Auto-apply the filter since it has a value
|
|
260
262
|
const filtersToApply = [...(appliedFilters ?? []), newFilter];
|
|
261
263
|
setAppliedFilters(filtersToApply);
|
|
264
|
+
resetFlameGraphState();
|
|
262
265
|
},
|
|
263
266
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
264
|
-
[setAppliedFilters]);
|
|
267
|
+
[setAppliedFilters, resetFlameGraphState]);
|
|
265
268
|
const removeExcludeBinary = useCallback((binaryName) => {
|
|
266
269
|
// Search for the exclude filter (not_contains) for this binary
|
|
267
270
|
const filterToRemove = (appliedFilters ?? []).find(f => f.type === 'frame' &&
|
|
@@ -272,10 +275,11 @@ export const useProfileFilters = () => {
|
|
|
272
275
|
// Remove the filter from applied filters
|
|
273
276
|
const updatedAppliedFilters = (appliedFilters ?? []).filter(f => f.id !== filterToRemove.id);
|
|
274
277
|
setAppliedFilters(updatedAppliedFilters);
|
|
278
|
+
resetFlameGraphState();
|
|
275
279
|
// Also remove from local filters
|
|
276
280
|
setLocalFilters(localFiltersRef.current.filter(f => f.id !== filterToRemove.id));
|
|
277
281
|
}
|
|
278
|
-
}, [appliedFilters, setAppliedFilters]);
|
|
282
|
+
}, [appliedFilters, setAppliedFilters, resetFlameGraphState]);
|
|
279
283
|
const removeFilter = useCallback((id) => {
|
|
280
284
|
setLocalFilters(localFiltersRef.current.filter(f => f.id !== id));
|
|
281
285
|
}, []);
|
|
@@ -285,7 +289,8 @@ export const useProfileFilters = () => {
|
|
|
285
289
|
const resetFilters = useCallback(() => {
|
|
286
290
|
setLocalFilters([]);
|
|
287
291
|
setAppliedFilters([]);
|
|
288
|
-
|
|
292
|
+
resetFlameGraphState();
|
|
293
|
+
}, [setAppliedFilters, resetFlameGraphState]);
|
|
289
294
|
const onApplyFilters = useCallback(() => {
|
|
290
295
|
const validFilters = localFiltersRef.current.filter(f => {
|
|
291
296
|
// For preset filters, only need type and value
|
|
@@ -300,7 +305,8 @@ export const useProfileFilters = () => {
|
|
|
300
305
|
id: `filter-${Date.now()}-${index}`,
|
|
301
306
|
}));
|
|
302
307
|
setAppliedFilters(filtersToApply);
|
|
303
|
-
|
|
308
|
+
resetFlameGraphState();
|
|
309
|
+
}, [setAppliedFilters, resetFlameGraphState]);
|
|
304
310
|
const protoFilters = useMemo(() => {
|
|
305
311
|
return convertToProtoFilters(appliedFilters ?? []);
|
|
306
312
|
}, [appliedFilters]);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useResetFlameGraphState.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/hooks/useResetFlameGraphState.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,uBAAuB,QAAO,CAAC,MAAM,IAAI,CAWrD,CAAC"}
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { useURLState } from '@parca/components';
|
|
14
|
-
export const
|
|
14
|
+
export const useResetFlameGraphState = () => {
|
|
15
15
|
const [val, setCurPath] = useURLState('cur_path');
|
|
16
16
|
return () => {
|
|
17
17
|
setTimeout(() => {
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { CurrentPathFrame } from '../../ProfileFlameGraph/FlameGraphArrow/utils';
|
|
2
2
|
export declare const useVisualizationState: () => {
|
|
3
|
-
curPath: string[];
|
|
4
|
-
setCurPath: (path: string[]) => void;
|
|
5
3
|
curPathArrow: CurrentPathFrame[];
|
|
6
4
|
setCurPathArrow: (path: CurrentPathFrame[]) => void;
|
|
7
5
|
colorStackLegend: string | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVisualizationState.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/hooks/useVisualizationState.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAC,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;
|
|
1
|
+
{"version":3,"file":"useVisualizationState.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/hooks/useVisualizationState.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAC,gBAAgB,EAAC,MAAM,+CAA+C,CAAC;AAG/E,eAAO,MAAM,qBAAqB,QAAO;IACvC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,eAAe,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACpD,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7C,oBAAoB,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,uBAAuB,EAAE,CAAC,oBAAoB,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IAC5E,yBAAyB,EAAE,MAAM,IAAI,CAAC;CA0EvC,CAAC"}
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
|
-
import { useCallback, useMemo
|
|
13
|
+
import { useCallback, useMemo } from 'react';
|
|
14
14
|
import { JSONParser, JSONSerializer, useURLState, useURLStateCustom } from '@parca/components';
|
|
15
15
|
import { FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_NAME, FIELD_LABELS, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE, } from '../../ProfileFlameGraph/FlameGraphArrow';
|
|
16
|
+
import { useResetFlameGraphState } from './useResetFlameGraphState';
|
|
16
17
|
export const useVisualizationState = () => {
|
|
17
|
-
const [curPath, setCurPath] = useState([]);
|
|
18
18
|
const [curPathArrow, setCurPathArrow] = useURLStateCustom('cur_path', {
|
|
19
19
|
parse: (JSONParser),
|
|
20
20
|
stringify: JSONSerializer,
|
|
@@ -27,6 +27,7 @@ export const useVisualizationState = () => {
|
|
|
27
27
|
alwaysReturnArray: true,
|
|
28
28
|
});
|
|
29
29
|
const [sandwichFunctionName, setSandwichFunctionName] = useURLState('sandwich_function_name');
|
|
30
|
+
const resetFlameGraphState = useResetFlameGraphState();
|
|
30
31
|
const levelsOfProfiling = useMemo(() => [
|
|
31
32
|
FIELD_FUNCTION_NAME,
|
|
32
33
|
FIELD_FUNCTION_FILE_NAME,
|
|
@@ -44,7 +45,8 @@ export const useVisualizationState = () => {
|
|
|
44
45
|
const filteredGroupBy = groupBy.filter(item => !levelsOfProfiling.includes(item));
|
|
45
46
|
setGroupBy([...filteredGroupBy, key]); // add
|
|
46
47
|
}
|
|
47
|
-
|
|
48
|
+
resetFlameGraphState();
|
|
49
|
+
}, [groupBy, setGroupBy, levelsOfProfiling, resetFlameGraphState]);
|
|
48
50
|
const setGroupByLabels = useCallback((labels) => {
|
|
49
51
|
setGroupBy(groupBy.filter(l => !l.startsWith(`${FIELD_LABELS}.`)).concat(labels));
|
|
50
52
|
}, [groupBy, setGroupBy]);
|
|
@@ -52,8 +54,6 @@ export const useVisualizationState = () => {
|
|
|
52
54
|
setSandwichFunctionName(undefined);
|
|
53
55
|
}, [setSandwichFunctionName]);
|
|
54
56
|
return {
|
|
55
|
-
curPath,
|
|
56
|
-
setCurPath,
|
|
57
57
|
curPathArrow,
|
|
58
58
|
setCurPathArrow,
|
|
59
59
|
colorStackLegend,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,WAAW,GAAI,iMAczB,gBAAgB,KAAG,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAE/E,eAAO,MAAM,WAAW,GAAI,iMAczB,gBAAgB,KAAG,GAAG,CAAC,OA2HzB,CAAC"}
|
|
@@ -26,7 +26,7 @@ import { useVisualizationState } from './hooks/useVisualizationState';
|
|
|
26
26
|
export const ProfileView = ({ total, filtered, flamegraphData, flamechartData, topTableData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, sandwichData, }) => {
|
|
27
27
|
const { timezone, perf, profileViewExternalMainActions, preferencesModal, profileViewExternalSubActions, } = useParcaContext();
|
|
28
28
|
const { ref, dimensions } = useContainerDimensions();
|
|
29
|
-
const {
|
|
29
|
+
const { curPathArrow, setCurPathArrow, colorStackLegend, colorBy, groupBy, toggleGroupBy, setGroupByLabels, sandwichFunctionName, resetSandwichFunctionName, } = useVisualizationState();
|
|
30
30
|
const { colorMappings } = useProfileMetadata({
|
|
31
31
|
flamegraphArrow: flamegraphData.arrow,
|
|
32
32
|
metadataMappingFiles: flamegraphData.metadataMappingFiles,
|
|
@@ -49,8 +49,6 @@ export const ProfileView = ({ total, filtered, flamegraphData, flamechartData, t
|
|
|
49
49
|
profileSource,
|
|
50
50
|
total,
|
|
51
51
|
filtered,
|
|
52
|
-
curPath,
|
|
53
|
-
setNewCurPath: setCurPath,
|
|
54
52
|
curPathArrow,
|
|
55
53
|
setNewCurPathArrow: setCurPathArrow,
|
|
56
54
|
perf,
|
|
@@ -39,7 +39,7 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
|
|
|
39
39
|
const { protoFilters } = useProfileFilters();
|
|
40
40
|
useEffect(() => {
|
|
41
41
|
// If profile type is not delta, remove flamechart from the dashboard items
|
|
42
|
-
// and set it to flame if no other items are selected.
|
|
42
|
+
// and set it to flame graph if no other items are selected.
|
|
43
43
|
if (profileSource == null) {
|
|
44
44
|
return;
|
|
45
45
|
}
|
package/package.json
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.53",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@floating-ui/react": "^0.27.12",
|
|
7
7
|
"@headlessui/react": "^1.7.19",
|
|
8
8
|
"@iconify/react": "^4.0.0",
|
|
9
|
-
"@parca/client": "0.17.
|
|
10
|
-
"@parca/components": "0.16.
|
|
11
|
-
"@parca/dynamicsize": "0.16.
|
|
12
|
-
"@parca/hooks": "0.0.
|
|
13
|
-
"@parca/icons": "0.16.
|
|
14
|
-
"@parca/parser": "0.16.
|
|
15
|
-
"@parca/store": "0.16.
|
|
16
|
-
"@parca/test-utils": "0.0.
|
|
17
|
-
"@parca/utilities": "0.0.
|
|
9
|
+
"@parca/client": "0.17.5",
|
|
10
|
+
"@parca/components": "0.16.370",
|
|
11
|
+
"@parca/dynamicsize": "0.16.67",
|
|
12
|
+
"@parca/hooks": "0.0.102",
|
|
13
|
+
"@parca/icons": "0.16.74",
|
|
14
|
+
"@parca/parser": "0.16.81",
|
|
15
|
+
"@parca/store": "0.16.186",
|
|
16
|
+
"@parca/test-utils": "0.0.12",
|
|
17
|
+
"@parca/utilities": "0.0.109",
|
|
18
18
|
"@popperjs/core": "^2.11.8",
|
|
19
19
|
"@protobuf-ts/runtime-rpc": "^2.5.0",
|
|
20
20
|
"@storybook/preview-api": "^8.4.3",
|
|
@@ -79,5 +79,5 @@
|
|
|
79
79
|
"access": "public",
|
|
80
80
|
"registry": "https://registry.npmjs.org/"
|
|
81
81
|
},
|
|
82
|
-
"gitHead": "
|
|
82
|
+
"gitHead": "364f74584252524568010bb27636fdb87fe7aee7"
|
|
83
83
|
}
|
|
@@ -23,7 +23,7 @@ import {capitalizeOnlyFirstLetter, safeDecode, type NavigateFunction} from '@par
|
|
|
23
23
|
|
|
24
24
|
import {ProfileSelection, ProfileSelectionFromParams, SuffixParams} from '..';
|
|
25
25
|
import {QuerySelection, useProfileTypes} from '../ProfileSelector';
|
|
26
|
-
import {
|
|
26
|
+
import {useResetFlameGraphState} from '../ProfileView/hooks/useResetFlameGraphState';
|
|
27
27
|
import {useResetStateOnProfileTypeChange} from '../ProfileView/hooks/useResetStateOnProfileTypeChange';
|
|
28
28
|
import {sumByToParam, useSumByFromParams} from '../useSumBy';
|
|
29
29
|
import ProfileExplorerCompare from './ProfileExplorerCompare';
|
|
@@ -162,7 +162,7 @@ const ProfileExplorerApp = ({
|
|
|
162
162
|
const [profileB, setProfileB] = useState<ProfileSelection | null>(null);
|
|
163
163
|
|
|
164
164
|
const resetStateOnProfileTypeChange = useResetStateOnProfileTypeChange();
|
|
165
|
-
const
|
|
165
|
+
const resetFlameGraphState = useResetFlameGraphState();
|
|
166
166
|
|
|
167
167
|
const sumByA = useSumByFromParams(sum_by_a);
|
|
168
168
|
const sumByB = useSumByFromParams(sum_by_b);
|
|
@@ -250,7 +250,7 @@ const ProfileExplorerApp = ({
|
|
|
250
250
|
resetStateOnProfileTypeChange();
|
|
251
251
|
} else {
|
|
252
252
|
// Reset the state when a new search is performed.
|
|
253
|
-
|
|
253
|
+
resetFlameGraphState();
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
256
|
|
|
@@ -130,8 +130,6 @@ export const FlameNode = React.memo(
|
|
|
130
130
|
const colorAttribute =
|
|
131
131
|
colorBy === 'filename' ? filename : colorBy === 'binary' ? mappingFile : null;
|
|
132
132
|
|
|
133
|
-
const colorsMap = colors;
|
|
134
|
-
|
|
135
133
|
const hoveringName =
|
|
136
134
|
hoveringRow !== undefined ? arrowToString(functionNameColumn?.get(hoveringRow)) : '';
|
|
137
135
|
const shouldBeHighlighted =
|
|
@@ -142,7 +140,7 @@ export const FlameNode = React.memo(
|
|
|
142
140
|
compareMode,
|
|
143
141
|
cumulative,
|
|
144
142
|
diff,
|
|
145
|
-
colorsMap,
|
|
143
|
+
colorsMap: colors,
|
|
146
144
|
colorAttribute,
|
|
147
145
|
});
|
|
148
146
|
|
|
@@ -296,7 +294,9 @@ export const FlameNode = React.memo(
|
|
|
296
294
|
prevProps.hoveringRow === nextProps.hoveringRow &&
|
|
297
295
|
prevProps.totalWidth === nextProps.totalWidth &&
|
|
298
296
|
prevProps.height === nextProps.height &&
|
|
299
|
-
prevProps.effectiveDepth === nextProps.effectiveDepth
|
|
297
|
+
prevProps.effectiveDepth === nextProps.effectiveDepth &&
|
|
298
|
+
prevProps.colorBy === nextProps.colorBy &&
|
|
299
|
+
prevProps.colors === nextProps.colors
|
|
300
300
|
);
|
|
301
301
|
}
|
|
302
302
|
);
|
|
@@ -21,15 +21,15 @@ import React, {
|
|
|
21
21
|
useState,
|
|
22
22
|
} from 'react';
|
|
23
23
|
|
|
24
|
-
import {
|
|
24
|
+
import {Table, tableFromIPC} from 'apache-arrow';
|
|
25
25
|
import {useContextMenu} from 'react-contexify';
|
|
26
26
|
|
|
27
27
|
import {FlamegraphArrow} from '@parca/client';
|
|
28
|
-
import {useParcaContext
|
|
28
|
+
import {useParcaContext} from '@parca/components';
|
|
29
29
|
import {USER_PREFERENCES, useCurrentColorProfile, useUserPreference} from '@parca/hooks';
|
|
30
30
|
import {ProfileType} from '@parca/parser';
|
|
31
31
|
import {getColorForFeature, selectDarkMode, useAppSelector} from '@parca/store';
|
|
32
|
-
import {
|
|
32
|
+
import {type ColorConfig} from '@parca/utilities';
|
|
33
33
|
|
|
34
34
|
import {ProfileSource} from '../../ProfileSource';
|
|
35
35
|
import {useProfileFilters} from '../../ProfileView/components/ProfileFilters/useProfileFilters';
|
|
@@ -38,12 +38,10 @@ import ContextMenuWrapper, {ContextMenuWrapperRef} from './ContextMenuWrapper';
|
|
|
38
38
|
import {FlameNode, RowHeight, colorByColors} from './FlameGraphNodes';
|
|
39
39
|
import {MemoizedTooltip} from './MemoizedTooltip';
|
|
40
40
|
import {TooltipProvider} from './TooltipContext';
|
|
41
|
-
import {useFilenamesList} from './useMappingList';
|
|
42
41
|
import {useScrollViewport} from './useScrollViewport';
|
|
43
42
|
import {useVisibleNodes} from './useVisibleNodes';
|
|
44
43
|
import {
|
|
45
44
|
CurrentPathFrame,
|
|
46
|
-
arrowToString,
|
|
47
45
|
extractFeature,
|
|
48
46
|
extractFilenameFeature,
|
|
49
47
|
getCurrentPathFrameData,
|
|
@@ -84,6 +82,8 @@ interface FlameGraphArrowProps {
|
|
|
84
82
|
setCurPath: (path: CurrentPathFrame[]) => void;
|
|
85
83
|
isHalfScreen: boolean;
|
|
86
84
|
mappingsListFromMetadata: string[];
|
|
85
|
+
filenamesListFromMetadata: string[];
|
|
86
|
+
colorBy: string;
|
|
87
87
|
compareAbsolute: boolean;
|
|
88
88
|
isFlameChart?: boolean;
|
|
89
89
|
isRenderedAsFlamegraph?: boolean;
|
|
@@ -139,6 +139,9 @@ export const FlameGraphArrow = memo(function FlameGraphArrow({
|
|
|
139
139
|
tooltipId = 'default',
|
|
140
140
|
maxFrameCount,
|
|
141
141
|
isExpanded = false,
|
|
142
|
+
mappingsListFromMetadata,
|
|
143
|
+
filenamesListFromMetadata,
|
|
144
|
+
colorBy,
|
|
142
145
|
}: FlameGraphArrowProps): React.JSX.Element {
|
|
143
146
|
const [highlightSimilarStacksPreference] = useUserPreference<boolean>(
|
|
144
147
|
USER_PREFERENCES.HIGHLIGHT_SIMILAR_STACKS.key
|
|
@@ -169,49 +172,17 @@ export const FlameGraphArrow = memo(function FlameGraphArrow({
|
|
|
169
172
|
const currentColorProfile = useCurrentColorProfile();
|
|
170
173
|
const colorForSimilarNodes = currentColorProfile.colorForSimilarNodes;
|
|
171
174
|
|
|
172
|
-
const
|
|
173
|
-
const colorByValue = colorBy === undefined || colorBy === '' ? 'binary' : (colorBy as string);
|
|
174
|
-
|
|
175
|
-
const filenamesList = useFilenamesList(table);
|
|
176
|
-
|
|
177
|
-
const mappingsList = useMemo(() => {
|
|
178
|
-
// Read the mappings from the dictionary that contains all mapping strings.
|
|
179
|
-
// This is great, as might only have a dozen or so mappings,
|
|
180
|
-
// and don't need to read through all the rows (potentially thousands).
|
|
181
|
-
const mappingsDict: Vector<Dictionary> | null = table.getChild(FIELD_MAPPING_FILE);
|
|
182
|
-
const mappings =
|
|
183
|
-
mappingsDict?.data
|
|
184
|
-
.map(mapping => {
|
|
185
|
-
if (mapping.dictionary == null) {
|
|
186
|
-
return [];
|
|
187
|
-
}
|
|
188
|
-
const len = mapping.dictionary.length;
|
|
189
|
-
const entries: string[] = [];
|
|
190
|
-
for (let i = 0; i < len; i++) {
|
|
191
|
-
const fn = arrowToString(mapping.dictionary.get(i));
|
|
192
|
-
entries.push(getLastItem(fn) ?? '');
|
|
193
|
-
}
|
|
194
|
-
return entries;
|
|
195
|
-
})
|
|
196
|
-
.flat() ?? [];
|
|
197
|
-
|
|
198
|
-
// We add a EVERYTHING ELSE mapping to the list.
|
|
199
|
-
mappings.push('');
|
|
200
|
-
|
|
201
|
-
// We sort the mappings alphabetically to make sure that the order is always the same.
|
|
202
|
-
mappings.sort((a, b) => a.localeCompare(b));
|
|
203
|
-
return mappings;
|
|
204
|
-
}, [table]);
|
|
175
|
+
const colorByValue = colorBy === undefined || colorBy === '' ? 'binary' : colorBy;
|
|
205
176
|
|
|
206
177
|
const filenameColors = useMemo(() => {
|
|
207
|
-
const colors = getFilenameColors(
|
|
178
|
+
const colors = getFilenameColors(filenamesListFromMetadata, isDarkMode, currentColorProfile);
|
|
208
179
|
return colors;
|
|
209
|
-
}, [isDarkMode,
|
|
180
|
+
}, [isDarkMode, filenamesListFromMetadata, currentColorProfile]);
|
|
210
181
|
|
|
211
182
|
const mappingColors = useMemo(() => {
|
|
212
|
-
const colors = getMappingColors(
|
|
183
|
+
const colors = getMappingColors(mappingsListFromMetadata, isDarkMode, currentColorProfile);
|
|
213
184
|
return colors;
|
|
214
|
-
}, [isDarkMode,
|
|
185
|
+
}, [isDarkMode, mappingsListFromMetadata, currentColorProfile]);
|
|
215
186
|
|
|
216
187
|
const colorByList = {
|
|
217
188
|
filename: filenameColors,
|
|
@@ -31,9 +31,10 @@ import {capitalizeOnlyFirstLetter, divide} from '@parca/utilities';
|
|
|
31
31
|
import {MergedProfileSource, ProfileSource} from '../ProfileSource';
|
|
32
32
|
import DiffLegend from '../ProfileView/components/DiffLegend';
|
|
33
33
|
import {useProfileViewContext} from '../ProfileView/context/ProfileViewContext';
|
|
34
|
+
import {useProfileMetadata} from '../ProfileView/hooks/useProfileMetadata';
|
|
35
|
+
import {useVisualizationState} from '../ProfileView/hooks/useVisualizationState';
|
|
34
36
|
import {TimelineGuide} from '../TimelineGuide';
|
|
35
37
|
import {FlameGraphArrow} from './FlameGraphArrow';
|
|
36
|
-
import useMappingList from './FlameGraphArrow/useMappingList';
|
|
37
38
|
import {CurrentPathFrame, boundsFromProfileSource} from './FlameGraphArrow/utils';
|
|
38
39
|
|
|
39
40
|
const numberFormatter = new Intl.NumberFormat('en-US');
|
|
@@ -100,11 +101,13 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
100
101
|
tooltipId,
|
|
101
102
|
maxFrameCount,
|
|
102
103
|
isExpanded = false,
|
|
104
|
+
metadataLoading = false,
|
|
103
105
|
}: ProfileFlameGraphProps): JSX.Element {
|
|
104
106
|
const {onError, authenticationErrorMessage, isDarkMode, flamechartHelpText} = useParcaContext();
|
|
105
107
|
const {compareMode} = useProfileViewContext();
|
|
106
108
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
|
107
109
|
const [flameChartRef, {height: flameChartHeight}] = useMeasure();
|
|
110
|
+
const {colorBy, setColorBy} = useVisualizationState();
|
|
108
111
|
|
|
109
112
|
// Create local state for paths when in sandwich view to avoid URL updates
|
|
110
113
|
const [localCurPathArrow, setLocalCurPathArrow] = useState<CurrentPathFrame[]>([]);
|
|
@@ -123,9 +126,12 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
123
126
|
// Determine which paths to use based on isInSandwichView flag
|
|
124
127
|
const effectiveCurPathArrow = isInSandwichView ? localCurPathArrow : curPathArrow;
|
|
125
128
|
|
|
126
|
-
const mappingsList =
|
|
127
|
-
|
|
128
|
-
|
|
129
|
+
const {mappingsList, filenamesList} = useProfileMetadata({
|
|
130
|
+
flamegraphArrow: arrow,
|
|
131
|
+
metadataMappingFiles,
|
|
132
|
+
metadataLoading,
|
|
133
|
+
colorBy,
|
|
134
|
+
});
|
|
129
135
|
|
|
130
136
|
// By default, we want delta profiles (CPU) to be relatively compared.
|
|
131
137
|
// For non-delta profiles, like goroutines or memory, we want the profiles to be compared absolutely.
|
|
@@ -279,6 +285,7 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
279
285
|
profileType={profileType}
|
|
280
286
|
isHalfScreen={isHalfScreen}
|
|
281
287
|
mappingsListFromMetadata={mappingsList}
|
|
288
|
+
filenamesListFromMetadata={filenamesList}
|
|
282
289
|
compareAbsolute={isCompareAbsolute}
|
|
283
290
|
isFlameChart={isFlameChart}
|
|
284
291
|
profileSource={profileSource}
|
|
@@ -287,6 +294,7 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
287
294
|
tooltipId={tooltipId}
|
|
288
295
|
maxFrameCount={maxFrameCount}
|
|
289
296
|
isExpanded={isExpanded}
|
|
297
|
+
colorBy={colorBy}
|
|
290
298
|
/>
|
|
291
299
|
</div>
|
|
292
300
|
</div>
|
|
@@ -302,7 +310,6 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
302
310
|
profileType,
|
|
303
311
|
isHalfScreen,
|
|
304
312
|
isDarkMode,
|
|
305
|
-
mappingsList,
|
|
306
313
|
isCompareAbsolute,
|
|
307
314
|
isFlameChart,
|
|
308
315
|
profileSource,
|
|
@@ -316,6 +323,9 @@ const ProfileFlameGraph = function ProfileFlameGraphNonMemo({
|
|
|
316
323
|
tooltipId,
|
|
317
324
|
maxFrameCount,
|
|
318
325
|
isExpanded,
|
|
326
|
+
mappingsList,
|
|
327
|
+
filenamesList,
|
|
328
|
+
colorBy,
|
|
319
329
|
]);
|
|
320
330
|
|
|
321
331
|
useEffect(() => {
|
|
@@ -42,8 +42,6 @@ interface GetDashboardItemProps {
|
|
|
42
42
|
profileSource: ProfileSource;
|
|
43
43
|
total: bigint;
|
|
44
44
|
filtered: bigint;
|
|
45
|
-
curPath: string[];
|
|
46
|
-
setNewCurPath: (path: string[]) => void;
|
|
47
45
|
curPathArrow: CurrentPathFrame[];
|
|
48
46
|
setNewCurPathArrow: (path: CurrentPathFrame[]) => void;
|
|
49
47
|
perf?: {
|
|
@@ -15,6 +15,7 @@ import {useCallback, useEffect, useMemo, useRef, useState} from 'react';
|
|
|
15
15
|
|
|
16
16
|
import {type Filter, type NumberCondition, type StringCondition} from '@parca/client';
|
|
17
17
|
|
|
18
|
+
import {useResetFlameGraphState} from '../../hooks/useResetFlameGraphState';
|
|
18
19
|
import {getPresetByKey, isPresetKey} from './filterPresets';
|
|
19
20
|
import {useProfileFiltersUrlState} from './useProfileFiltersUrlState';
|
|
20
21
|
|
|
@@ -226,6 +227,7 @@ export const useProfileFilters = (): {
|
|
|
226
227
|
resetFilters: () => void;
|
|
227
228
|
} => {
|
|
228
229
|
const {appliedFilters, setAppliedFilters} = useProfileFiltersUrlState();
|
|
230
|
+
const resetFlameGraphState = useResetFlameGraphState();
|
|
229
231
|
|
|
230
232
|
const [localFilters, setLocalFilters] = useState<ProfileFilter[]>(appliedFilters ?? []);
|
|
231
233
|
|
|
@@ -327,9 +329,10 @@ export const useProfileFilters = (): {
|
|
|
327
329
|
// Auto-apply the filter since it has a value
|
|
328
330
|
const filtersToApply = [...(appliedFilters ?? []), newFilter];
|
|
329
331
|
setAppliedFilters(filtersToApply);
|
|
332
|
+
resetFlameGraphState();
|
|
330
333
|
},
|
|
331
334
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
332
|
-
[setAppliedFilters]
|
|
335
|
+
[setAppliedFilters, resetFlameGraphState]
|
|
333
336
|
);
|
|
334
337
|
|
|
335
338
|
const removeExcludeBinary = useCallback(
|
|
@@ -349,12 +352,13 @@ export const useProfileFilters = (): {
|
|
|
349
352
|
f => f.id !== filterToRemove.id
|
|
350
353
|
);
|
|
351
354
|
setAppliedFilters(updatedAppliedFilters);
|
|
355
|
+
resetFlameGraphState();
|
|
352
356
|
|
|
353
357
|
// Also remove from local filters
|
|
354
358
|
setLocalFilters(localFiltersRef.current.filter(f => f.id !== filterToRemove.id));
|
|
355
359
|
}
|
|
356
360
|
},
|
|
357
|
-
[appliedFilters, setAppliedFilters]
|
|
361
|
+
[appliedFilters, setAppliedFilters, resetFlameGraphState]
|
|
358
362
|
);
|
|
359
363
|
|
|
360
364
|
const removeFilter = useCallback((id: string) => {
|
|
@@ -368,7 +372,8 @@ export const useProfileFilters = (): {
|
|
|
368
372
|
const resetFilters = useCallback(() => {
|
|
369
373
|
setLocalFilters([]);
|
|
370
374
|
setAppliedFilters([]);
|
|
371
|
-
|
|
375
|
+
resetFlameGraphState();
|
|
376
|
+
}, [setAppliedFilters, resetFlameGraphState]);
|
|
372
377
|
|
|
373
378
|
const onApplyFilters = useCallback((): void => {
|
|
374
379
|
const validFilters = localFiltersRef.current.filter(f => {
|
|
@@ -386,7 +391,8 @@ export const useProfileFilters = (): {
|
|
|
386
391
|
}));
|
|
387
392
|
|
|
388
393
|
setAppliedFilters(filtersToApply);
|
|
389
|
-
|
|
394
|
+
resetFlameGraphState();
|
|
395
|
+
}, [setAppliedFilters, resetFlameGraphState]);
|
|
390
396
|
|
|
391
397
|
const protoFilters = useMemo(() => {
|
|
392
398
|
return convertToProtoFilters(appliedFilters ?? []);
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
|
-
import {useCallback, useMemo
|
|
14
|
+
import {useCallback, useMemo} from 'react';
|
|
15
15
|
|
|
16
16
|
import {JSONParser, JSONSerializer, useURLState, useURLStateCustom} from '@parca/components';
|
|
17
17
|
|
|
@@ -23,10 +23,9 @@ import {
|
|
|
23
23
|
FIELD_MAPPING_FILE,
|
|
24
24
|
} from '../../ProfileFlameGraph/FlameGraphArrow';
|
|
25
25
|
import {CurrentPathFrame} from '../../ProfileFlameGraph/FlameGraphArrow/utils';
|
|
26
|
+
import {useResetFlameGraphState} from './useResetFlameGraphState';
|
|
26
27
|
|
|
27
28
|
export const useVisualizationState = (): {
|
|
28
|
-
curPath: string[];
|
|
29
|
-
setCurPath: (path: string[]) => void;
|
|
30
29
|
curPathArrow: CurrentPathFrame[];
|
|
31
30
|
setCurPathArrow: (path: CurrentPathFrame[]) => void;
|
|
32
31
|
colorStackLegend: string | undefined;
|
|
@@ -40,7 +39,6 @@ export const useVisualizationState = (): {
|
|
|
40
39
|
setSandwichFunctionName: (sandwichFunctionName: string | undefined) => void;
|
|
41
40
|
resetSandwichFunctionName: () => void;
|
|
42
41
|
} => {
|
|
43
|
-
const [curPath, setCurPath] = useState<string[]>([]);
|
|
44
42
|
const [curPathArrow, setCurPathArrow] = useURLStateCustom<CurrentPathFrame[]>('cur_path', {
|
|
45
43
|
parse: JSONParser<CurrentPathFrame[]>,
|
|
46
44
|
stringify: JSONSerializer,
|
|
@@ -55,6 +53,7 @@ export const useVisualizationState = (): {
|
|
|
55
53
|
const [sandwichFunctionName, setSandwichFunctionName] = useURLState<string | undefined>(
|
|
56
54
|
'sandwich_function_name'
|
|
57
55
|
);
|
|
56
|
+
const resetFlameGraphState = useResetFlameGraphState();
|
|
58
57
|
|
|
59
58
|
const levelsOfProfiling = useMemo(
|
|
60
59
|
() => [
|
|
@@ -81,8 +80,10 @@ export const useVisualizationState = (): {
|
|
|
81
80
|
const filteredGroupBy = groupBy.filter(item => !levelsOfProfiling.includes(item));
|
|
82
81
|
setGroupBy([...filteredGroupBy, key]); // add
|
|
83
82
|
}
|
|
83
|
+
|
|
84
|
+
resetFlameGraphState();
|
|
84
85
|
},
|
|
85
|
-
[groupBy, setGroupBy, levelsOfProfiling]
|
|
86
|
+
[groupBy, setGroupBy, levelsOfProfiling, resetFlameGraphState]
|
|
86
87
|
);
|
|
87
88
|
|
|
88
89
|
const setGroupByLabels = useCallback(
|
|
@@ -97,8 +98,6 @@ export const useVisualizationState = (): {
|
|
|
97
98
|
}, [setSandwichFunctionName]);
|
|
98
99
|
|
|
99
100
|
return {
|
|
100
|
-
curPath,
|
|
101
|
-
setCurPath,
|
|
102
101
|
curPathArrow,
|
|
103
102
|
setCurPathArrow,
|
|
104
103
|
colorStackLegend,
|
|
@@ -56,8 +56,6 @@ export const ProfileView = ({
|
|
|
56
56
|
const {ref, dimensions} = useContainerDimensions();
|
|
57
57
|
|
|
58
58
|
const {
|
|
59
|
-
curPath,
|
|
60
|
-
setCurPath,
|
|
61
59
|
curPathArrow,
|
|
62
60
|
setCurPathArrow,
|
|
63
61
|
colorStackLegend,
|
|
@@ -100,8 +98,6 @@ export const ProfileView = ({
|
|
|
100
98
|
profileSource,
|
|
101
99
|
total,
|
|
102
100
|
filtered,
|
|
103
|
-
curPath,
|
|
104
|
-
setNewCurPath: setCurPath,
|
|
105
101
|
curPathArrow,
|
|
106
102
|
setNewCurPathArrow: setCurPathArrow,
|
|
107
103
|
perf,
|
|
@@ -58,7 +58,7 @@ export const ProfileViewWithData = ({
|
|
|
58
58
|
|
|
59
59
|
useEffect(() => {
|
|
60
60
|
// If profile type is not delta, remove flamechart from the dashboard items
|
|
61
|
-
// and set it to flame if no other items are selected.
|
|
61
|
+
// and set it to flame graph if no other items are selected.
|
|
62
62
|
if (profileSource == null) {
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useResetStateOnNewSearch.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/hooks/useResetStateOnNewSearch.ts"],"names":[],"mappings":"AAeA,eAAO,MAAM,wBAAwB,QAAO,CAAC,MAAM,IAAI,CAWtD,CAAC"}
|