@parca/profile 0.16.437 → 0.16.439
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/ProfileIcicleGraph/IcicleGraph/utils.d.ts +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraph/utils.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/utils.js +3 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.js +4 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts +5 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.js +20 -8
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +3 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +25 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useMappingList.d.ts +2 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useMappingList.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useMappingList.js +25 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.d.ts +4 -4
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.js +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/utils.d.ts +3 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/utils.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/utils.js +9 -3
- package/dist/ProfileIcicleGraph/index.d.ts +3 -3
- package/dist/ProfileIcicleGraph/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/index.js +20 -5
- package/dist/ProfileView/index.d.ts +3 -3
- package/dist/ProfileView/index.d.ts.map +1 -1
- package/dist/ProfileView/index.js +2 -2
- package/dist/ProfileViewWithData.js +4 -4
- package/dist/components/ActionButtons/GroupByDropdown.js +2 -2
- package/dist/components/VisualisationToolbar/MultiLevelDropdown.d.ts.map +1 -1
- package/dist/components/VisualisationToolbar/MultiLevelDropdown.js +52 -6
- package/dist/styles.css +1 -1
- package/package.json +5 -5
- package/src/ProfileIcicleGraph/IcicleGraph/useColoredGraph.ts +5 -5
- package/src/ProfileIcicleGraph/IcicleGraph/utils.ts +4 -4
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.tsx +7 -2
- package/src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx +32 -10
- package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +42 -6
- package/src/ProfileIcicleGraph/IcicleGraphArrow/useMappingList.ts +32 -0
- package/src/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.ts +6 -6
- package/src/ProfileIcicleGraph/IcicleGraphArrow/utils.ts +18 -4
- package/src/ProfileIcicleGraph/index.tsx +32 -7
- package/src/ProfileView/index.tsx +6 -6
- package/src/ProfileViewWithData.tsx +4 -4
- package/src/components/ActionButtons/GroupByDropdown.tsx +3 -3
- package/src/components/VisualisationToolbar/MultiLevelDropdown.tsx +85 -13
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.439 (2024-10-29)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.16.438](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.437...@parca/profile@0.16.438) (2024-10-23)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## 0.16.437 (2024-10-23)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FlamegraphNode } from '@parca/client';
|
|
2
2
|
import { Location, Mapping, Function as ParcaFunction } from '@parca/client/dist/parca/metastore/v1alpha1/metastore';
|
|
3
|
-
import { type
|
|
3
|
+
import { type BinaryFeature } from '@parca/store';
|
|
4
4
|
export declare const getBinaryName: (node: FlamegraphNode, mappings: Mapping[], locations: Location[], strings: string[]) => string | undefined;
|
|
5
5
|
export declare function nodeLabel(node: FlamegraphNode, strings: string[], mappings: Mapping[], locations: Location[], functions: ParcaFunction[], showBinaryName: boolean): string;
|
|
6
|
-
export declare const extractFeature: (data: FlamegraphNode, mappings: Mapping[], locations: Location[], strings: string[]) =>
|
|
6
|
+
export declare const extractFeature: (data: FlamegraphNode, mappings: Mapping[], locations: Location[], strings: string[]) => BinaryFeature;
|
|
7
7
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraph/utils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,cAAc,EAAC,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,IAAI,aAAa,EAC1B,MAAM,uDAAuD,CAAC;AAC/D,OAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraph/utils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,cAAc,EAAC,MAAM,eAAe,CAAC;AAC7C,OAAO,EACL,QAAQ,EACR,OAAO,EACP,QAAQ,IAAI,aAAa,EAC1B,MAAM,uDAAuD,CAAC;AAC/D,OAAO,EAAwC,KAAK,aAAa,EAAC,MAAM,cAAc,CAAC;AAKvF,eAAO,MAAM,aAAa,SAClB,cAAc,YACV,OAAO,EAAE,aACR,QAAQ,EAAE,WACZ,MAAM,EAAE,KAChB,MAAM,GAAG,SAoBX,CAAC;AAEF,wBAAgB,SAAS,CACvB,IAAI,EAAE,cAAc,EACpB,OAAO,EAAE,MAAM,EAAE,EACjB,QAAQ,EAAE,OAAO,EAAE,EACnB,SAAS,EAAE,QAAQ,EAAE,EACrB,SAAS,EAAE,aAAa,EAAE,EAC1B,cAAc,EAAE,OAAO,GACtB,MAAM,CA6BR;AAED,eAAO,MAAM,cAAc,SACnB,cAAc,YACV,OAAO,EAAE,aACR,QAAQ,EAAE,WACZ,MAAM,EAAE,KAChB,aAOF,CAAC"}
|
|
@@ -10,7 +10,7 @@
|
|
|
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 {
|
|
13
|
+
import { BINARY_FEATURE_TYPES, EVERYTHING_ELSE } from '@parca/store';
|
|
14
14
|
import { getLastItem } from '@parca/utilities';
|
|
15
15
|
import { hexifyAddress } from '../../utils';
|
|
16
16
|
export const getBinaryName = (node, mappings, locations, strings) => {
|
|
@@ -60,7 +60,7 @@ export function nodeLabel(node, strings, mappings, locations, functions, showBin
|
|
|
60
60
|
export const extractFeature = (data, mappings, locations, strings) => {
|
|
61
61
|
const binaryName = getBinaryName(data, mappings, locations, strings);
|
|
62
62
|
if (binaryName != null) {
|
|
63
|
-
return { name: binaryName, type:
|
|
63
|
+
return { name: binaryName, type: BINARY_FEATURE_TYPES.Binary };
|
|
64
64
|
}
|
|
65
|
-
return { name: EVERYTHING_ELSE, type:
|
|
65
|
+
return { name: EVERYTHING_ELSE, type: BINARY_FEATURE_TYPES.Misc };
|
|
66
66
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ColorStackLegend.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAYrC,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,QAAA,MAAM,gBAAgB,uCAA8C,KAAK,KAAG,KAAK,CAAC,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"ColorStackLegend.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAYrC,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,QAAA,MAAM,gBAAgB,uCAA8C,KAAK,KAAG,KAAK,CAAC,GAAG,CAAC,OAmGrF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
|
|
@@ -23,7 +23,9 @@ const ColorStackLegend = ({ mappings, compareMode = false, loading }) => {
|
|
|
23
23
|
const isDarkMode = useAppSelector(selectDarkMode);
|
|
24
24
|
const currentColorProfile = useCurrentColorProfile();
|
|
25
25
|
const [colorProfileName] = useUserPreference(USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key);
|
|
26
|
-
const [
|
|
26
|
+
const [colorByValue, _] = useURLState('color_by');
|
|
27
|
+
const colorBy = colorByValue === 'binary' || colorByValue === undefined ? 'binary' : 'filename';
|
|
28
|
+
const [currentSearchString, setSearchString] = useURLState(`binary_frame_filter`, {
|
|
27
29
|
alwaysReturnArray: true,
|
|
28
30
|
defaultValue: [],
|
|
29
31
|
});
|
|
@@ -59,7 +61,7 @@ const ColorStackLegend = ({ mappings, compareMode = false, loading }) => {
|
|
|
59
61
|
'cursor-pointer': filteringAllowed,
|
|
60
62
|
'bg-gray-200 dark:bg-gray-800': isHighlighted,
|
|
61
63
|
}), onClick: () => {
|
|
62
|
-
if (!filteringAllowed || isHighlighted) {
|
|
64
|
+
if (!filteringAllowed || isHighlighted || colorBy !== 'binary') {
|
|
63
65
|
return;
|
|
64
66
|
}
|
|
65
67
|
// Check if the current search string is defined and an array
|
|
@@ -6,7 +6,8 @@ export declare const RowHeight = 26;
|
|
|
6
6
|
interface IcicleGraphNodesProps {
|
|
7
7
|
table: Table<any>;
|
|
8
8
|
row: number;
|
|
9
|
-
|
|
9
|
+
colors: colorByColors;
|
|
10
|
+
colorBy: string;
|
|
10
11
|
childRows: number[];
|
|
11
12
|
x: number;
|
|
12
13
|
y: number;
|
|
@@ -32,7 +33,7 @@ interface IcicleGraphNodesProps {
|
|
|
32
33
|
highlightSimilarStacksPreference: boolean;
|
|
33
34
|
}
|
|
34
35
|
export declare const IcicleGraphNodes: React.NamedExoticComponent<IcicleGraphNodesProps>;
|
|
35
|
-
export interface
|
|
36
|
+
export interface colorByColors {
|
|
36
37
|
[key: string]: string;
|
|
37
38
|
}
|
|
38
39
|
interface IcicleNodeProps {
|
|
@@ -44,7 +45,8 @@ interface IcicleNodeProps {
|
|
|
44
45
|
level: number;
|
|
45
46
|
table: Table<any>;
|
|
46
47
|
row: number;
|
|
47
|
-
|
|
48
|
+
colors: colorByColors;
|
|
49
|
+
colorBy: string;
|
|
48
50
|
path: string[];
|
|
49
51
|
total: bigint;
|
|
50
52
|
setCurPath: (path: string[]) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IcicleGraphNodes.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA2B,MAAM,OAAO,CAAC;AAEhD,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAMnC,OAAO,yCAAyC,CAAC;AAEjD,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"IcicleGraphNodes.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx"],"names":[],"mappings":"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"}
|
|
@@ -16,11 +16,11 @@ import cx from 'classnames';
|
|
|
16
16
|
import { selectBinaries, useAppSelector } from '@parca/store';
|
|
17
17
|
import { isSearchMatch, scaleLinear } from '@parca/utilities';
|
|
18
18
|
import 'react-contexify/dist/ReactContexify.css';
|
|
19
|
-
import { FIELD_CHILDREN, FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_NAME, FIELD_MAPPING_FILE, } from './index';
|
|
19
|
+
import { FIELD_CHILDREN, FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_NAME, FIELD_MAPPING_FILE, } from './index';
|
|
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,
|
|
23
|
+
export const IcicleGraphNodes = React.memo(function IcicleGraphNodesNoMemo({ table, childRows, colors, colorBy, 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,
|
|
38
|
+
childrenElements.push(_jsx(IcicleNode, { table: table, row: child, colors: colors, colorBy: colorBy, 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,18 +48,31 @@ 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,
|
|
51
|
+
export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, colors, colorBy, 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);
|
|
55
55
|
const cumulativeColumn = table.getChild(FIELD_CUMULATIVE);
|
|
56
56
|
const diffColumn = table.getChild(FIELD_DIFF);
|
|
57
|
+
const filenameColumn = table.getChild(FIELD_FUNCTION_FILE_NAME);
|
|
57
58
|
// get the actual values from the columns
|
|
58
59
|
const mappingFile = arrowToString(mappingColumn?.get(row));
|
|
59
60
|
const functionName = arrowToString(functionNameColumn?.get(row));
|
|
60
61
|
const cumulative = cumulativeColumn?.get(row) !== null ? BigInt(cumulativeColumn?.get(row)) : 0n;
|
|
61
62
|
const diff = diffColumn?.get(row) !== null ? BigInt(diffColumn?.get(row)) : null;
|
|
62
63
|
const childRows = Array.from(table.getChild(FIELD_CHILDREN)?.get(row) ?? []);
|
|
64
|
+
const filename = arrowToString(filenameColumn?.get(row));
|
|
65
|
+
const colorAttribute = useMemo(() => {
|
|
66
|
+
let attr;
|
|
67
|
+
if (colorBy === 'filename') {
|
|
68
|
+
attr = filename;
|
|
69
|
+
}
|
|
70
|
+
else if (colorBy === 'binary') {
|
|
71
|
+
attr = mappingFile;
|
|
72
|
+
}
|
|
73
|
+
return attr ?? null; // Provide a default value of null if attr is undefined
|
|
74
|
+
}, [colorBy, filename, mappingFile]);
|
|
75
|
+
const colorsMap = colors;
|
|
63
76
|
const highlightedNodes = useMemo(() => {
|
|
64
77
|
if (!highlightSimilarStacksPreference) {
|
|
65
78
|
return null;
|
|
@@ -105,7 +118,6 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
|
|
|
105
118
|
const aDiff = diffColumn?.get(a) !== null ? BigInt(diffColumn?.get(a)) : null;
|
|
106
119
|
if (aDiff !== null) {
|
|
107
120
|
const cumulative = cumulativeColumn?.get(a) !== null ? BigInt(cumulativeColumn?.get(a)) : 0n;
|
|
108
|
-
console.log(typeof cumulative, typeof aDiff);
|
|
109
121
|
const prev = cumulative - aDiff;
|
|
110
122
|
aRatio = Number(aDiff) / Number(prev);
|
|
111
123
|
}
|
|
@@ -136,8 +148,8 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
|
|
|
136
148
|
compareMode,
|
|
137
149
|
cumulative,
|
|
138
150
|
diff,
|
|
139
|
-
|
|
140
|
-
|
|
151
|
+
colorsMap,
|
|
152
|
+
colorAttribute,
|
|
141
153
|
});
|
|
142
154
|
const name = useMemo(() => {
|
|
143
155
|
return isRoot ? 'root' : nodeLabel(table, row, level, binaries.length > 1);
|
|
@@ -184,5 +196,5 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
|
|
|
184
196
|
? `${colorForSimilarNodes} stroke-[3] [stroke-dasharray:6,4] [stroke-linecap:round] [stroke-linejoin:round] h-6`
|
|
185
197
|
: 'stroke-white dark:stroke-gray-700', {
|
|
186
198
|
'opacity-50': isHighlightEnabled && !isHighlighted,
|
|
187
|
-
}) }), 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,
|
|
199
|
+
}) }), 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, colors: colors, colorBy: colorBy, 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 }))] }));
|
|
188
200
|
});
|
|
@@ -2,7 +2,7 @@ import React from 'react';
|
|
|
2
2
|
import { FlamegraphArrow } from '@parca/client';
|
|
3
3
|
import { ProfileType } from '@parca/parser';
|
|
4
4
|
import { type ColorConfig } from '@parca/utilities';
|
|
5
|
-
import {
|
|
5
|
+
import { colorByColors } from './IcicleGraphNodes';
|
|
6
6
|
export declare const FIELD_LABELS_ONLY = "labels_only";
|
|
7
7
|
export declare const FIELD_MAPPING_FILE = "mapping_file";
|
|
8
8
|
export declare const FIELD_MAPPING_BUILD_ID = "mapping_build_id";
|
|
@@ -32,7 +32,8 @@ interface IcicleGraphArrowProps {
|
|
|
32
32
|
mappingsListFromMetadata: string[];
|
|
33
33
|
compareAbsolute: boolean;
|
|
34
34
|
}
|
|
35
|
-
export declare const getMappingColors: (mappingsList: string[], isDarkMode: boolean, currentColorProfile: ColorConfig) =>
|
|
35
|
+
export declare const getMappingColors: (mappingsList: string[], isDarkMode: boolean, currentColorProfile: ColorConfig) => colorByColors;
|
|
36
|
+
export declare const getFilenameColors: (filenamesList: string[], isDarkMode: boolean, currentColorProfile: ColorConfig) => colorByColors;
|
|
36
37
|
export declare const IcicleGraphArrow: React.NamedExoticComponent<IcicleGraphArrowProps>;
|
|
37
38
|
export default IcicleGraphArrow;
|
|
38
39
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgE,MAAM,OAAO,CAAC;AAKrF,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAQ1C,OAAO,EAA2B,KAAK,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAO5E,OAAO,EAAwB,aAAa,EAAC,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgE,MAAM,OAAO,CAAC;AAKrF,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAQ1C,OAAO,EAA2B,KAAK,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAO5E,OAAO,EAAwB,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAIxE,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,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;AAEjC,UAAU,qBAAqB;IAC7B,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,gBAAgB,iBACb,MAAM,EAAE,cACV,OAAO,uBACE,WAAW,KAC/B,aAQF,CAAC;AAEF,eAAO,MAAM,iBAAiB,kBACb,MAAM,EAAE,cACX,OAAO,uBACE,WAAW,KAC/B,aAQF,CAAC;AAIF,eAAO,MAAM,gBAAgB,mDAiR3B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
|
|
@@ -24,7 +24,8 @@ import { DockedGraphTooltip } from '../../GraphTooltipArrow/DockedGraphTooltip';
|
|
|
24
24
|
import { useProfileViewContext } from '../../ProfileView/ProfileViewContext';
|
|
25
25
|
import ContextMenu from './ContextMenu';
|
|
26
26
|
import { IcicleNode, RowHeight } from './IcicleGraphNodes';
|
|
27
|
-
import {
|
|
27
|
+
import { useFilenamesList } from './useMappingList';
|
|
28
|
+
import { arrowToString, extractFeature, extractFilenameFeature } from './utils';
|
|
28
29
|
export const FIELD_LABELS_ONLY = 'labels_only';
|
|
29
30
|
export const FIELD_MAPPING_FILE = 'mapping_file';
|
|
30
31
|
export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
|
|
@@ -48,6 +49,14 @@ export const getMappingColors = (mappingsList, isDarkMode, currentColorProfile)
|
|
|
48
49
|
});
|
|
49
50
|
return colors;
|
|
50
51
|
};
|
|
52
|
+
export const getFilenameColors = (filenamesList, isDarkMode, currentColorProfile) => {
|
|
53
|
+
const filenameFeatures = filenamesList.map(filename => extractFilenameFeature(filename));
|
|
54
|
+
const colors = {};
|
|
55
|
+
Object.entries(filenameFeatures).forEach(([_, feature]) => {
|
|
56
|
+
colors[feature.name] = getColorForFeature(feature.name, isDarkMode, currentColorProfile.colors);
|
|
57
|
+
});
|
|
58
|
+
return colors;
|
|
59
|
+
};
|
|
51
60
|
const noop = () => { };
|
|
52
61
|
export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, profileType, sortBy, flamegraphLoading, mappingsListFromMetadata, compareAbsolute, }) {
|
|
53
62
|
const [isContextMenuOpen, setIsContextMenuOpen] = useState(false);
|
|
@@ -69,6 +78,9 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
69
78
|
const { compareMode } = useProfileViewContext();
|
|
70
79
|
const currentColorProfile = useCurrentColorProfile();
|
|
71
80
|
const colorForSimilarNodes = currentColorProfile.colorForSimilarNodes;
|
|
81
|
+
const [colorBy, _] = useURLState('color_by');
|
|
82
|
+
const colorByValue = colorBy === undefined || colorBy === '' ? 'binary' : colorBy;
|
|
83
|
+
const filenamesList = useFilenamesList(table);
|
|
72
84
|
const mappingsList = useMemo(() => {
|
|
73
85
|
// Read the mappings from the dictionary that contains all mapping strings.
|
|
74
86
|
// This is great, as might only have a dozen or so mappings,
|
|
@@ -94,10 +106,19 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
94
106
|
mappings.sort((a, b) => a.localeCompare(b));
|
|
95
107
|
return mappings;
|
|
96
108
|
}, [table]);
|
|
109
|
+
const filenameColors = useMemo(() => {
|
|
110
|
+
const colors = getFilenameColors(filenamesList, isDarkMode, currentColorProfile);
|
|
111
|
+
return colors;
|
|
112
|
+
}, [isDarkMode, filenamesList, currentColorProfile]);
|
|
97
113
|
const mappingColors = useMemo(() => {
|
|
98
114
|
const colors = getMappingColors(mappingsList, isDarkMode, currentColorProfile);
|
|
99
115
|
return colors;
|
|
100
116
|
}, [isDarkMode, mappingsList, currentColorProfile]);
|
|
117
|
+
const colorByList = {
|
|
118
|
+
filename: filenameColors,
|
|
119
|
+
binary: mappingColors,
|
|
120
|
+
};
|
|
121
|
+
const colorByColors = colorByList[colorByValue];
|
|
101
122
|
useEffect(() => {
|
|
102
123
|
if (ref.current != null) {
|
|
103
124
|
setHeight(ref?.current.getBoundingClientRect().height);
|
|
@@ -146,13 +167,14 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
146
167
|
}, []);
|
|
147
168
|
// useMemo for the root graph as it otherwise renders the whole graph if the hoveringRow changes.
|
|
148
169
|
const root = useMemo(() => {
|
|
149
|
-
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,
|
|
170
|
+
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, colors: colorByColors, colorBy: colorByValue, x: 0, y: 0, totalWidth: width ?? 1, height: RowHeight, setCurPath: setCurPath, curPath: curPath, total: total, xScale: xScale, path: path, level: 0, isRoot: true, searchString: currentSearchString ?? '', setHoveringRow: setHoveringRow, setHoveringLevel: setHoveringLevel, sortBy: sortBy, darkMode: isDarkMode, compareMode: compareMode, profileType: profileType, isContextMenuOpen: isContextMenuOpen, hoveringName: highlightSimilarStacksName, setHoveringName: highlightSimilarStacksSetName, hoveringRow: highlightSimilarStacksRow, colorForSimilarNodes: colorForSimilarNodes, highlightSimilarStacksPreference: highlightSimilarStacksPreference }) }) }) }));
|
|
150
171
|
}, [
|
|
151
172
|
width,
|
|
152
173
|
height,
|
|
153
174
|
displayMenu,
|
|
154
175
|
table,
|
|
155
|
-
|
|
176
|
+
colorByColors,
|
|
177
|
+
colorByValue,
|
|
156
178
|
setCurPath,
|
|
157
179
|
curPath,
|
|
158
180
|
total,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useMappingList.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/useMappingList.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"useMappingList.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/useMappingList.ts"],"names":[],"mappings":"AAeA,OAAO,EAAa,KAAK,EAAS,MAAM,cAAc,CAAC;AAOvD,QAAA,MAAM,cAAc,aAAc,MAAM,EAAE,GAAG,SAAS,KAAG,MAAM,EAsB9D,CAAC;AAEF,eAAO,MAAM,gBAAgB,UAAW,KAAK,GAAG,IAAI,KAAG,MAAM,EAyB5D,CAAC;AAEF,eAAe,cAAc,CAAC"}
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { useMemo } from 'react';
|
|
14
14
|
import { getLastItem } from '@parca/utilities';
|
|
15
|
+
import { FIELD_FUNCTION_FILE_NAME } from './index';
|
|
16
|
+
import { arrowToString } from './utils';
|
|
15
17
|
const useMappingList = (mappings) => {
|
|
16
18
|
const mappingsList = useMemo(() => {
|
|
17
19
|
if (mappings === undefined) {
|
|
@@ -30,4 +32,27 @@ const useMappingList = (mappings) => {
|
|
|
30
32
|
}, [mappings]);
|
|
31
33
|
return mappingsList;
|
|
32
34
|
};
|
|
35
|
+
export const useFilenamesList = (table) => {
|
|
36
|
+
if (table === null) {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
const filenamesDict = table.getChild(FIELD_FUNCTION_FILE_NAME);
|
|
40
|
+
const filenames = filenamesDict?.data
|
|
41
|
+
.map(file => {
|
|
42
|
+
if (file.dictionary == null) {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
const len = file.dictionary.length;
|
|
46
|
+
const entries = [];
|
|
47
|
+
for (let i = 0; i < len; i++) {
|
|
48
|
+
const fn = arrowToString(file.dictionary.get(i));
|
|
49
|
+
entries.push(getLastItem(fn) ?? '');
|
|
50
|
+
}
|
|
51
|
+
return entries;
|
|
52
|
+
})
|
|
53
|
+
.flat() ?? [];
|
|
54
|
+
filenames.push('');
|
|
55
|
+
filenames.sort((a, b) => a.localeCompare(b));
|
|
56
|
+
return filenames;
|
|
57
|
+
};
|
|
33
58
|
export default useMappingList;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
interface
|
|
1
|
+
interface colors {
|
|
2
2
|
[key: string]: string;
|
|
3
3
|
}
|
|
4
4
|
interface Props {
|
|
@@ -6,9 +6,9 @@ interface Props {
|
|
|
6
6
|
compareMode: boolean;
|
|
7
7
|
cumulative: bigint;
|
|
8
8
|
diff: bigint | null;
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
colorsMap: colors;
|
|
10
|
+
colorAttribute: string | null;
|
|
11
11
|
}
|
|
12
|
-
declare const useNodeColor: ({ isDarkMode, compareMode, cumulative, diff,
|
|
12
|
+
declare const useNodeColor: ({ isDarkMode, compareMode, cumulative, diff, colorsMap, colorAttribute, }: Props) => string;
|
|
13
13
|
export default useNodeColor;
|
|
14
14
|
//# sourceMappingURL=useNodeColor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useNodeColor.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.ts"],"names":[],"mappings":"AAgBA,UAAU,
|
|
1
|
+
{"version":3,"file":"useNodeColor.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/useNodeColor.ts"],"names":[],"mappings":"AAgBA,UAAU,MAAM;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,UAAU,KAAK;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,QAAA,MAAM,YAAY,8EAOf,KAAK,KAAG,MAMV,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
import { EVERYTHING_ELSE } from '@parca/store';
|
|
14
14
|
import { diffColor, getLastItem } from '@parca/utilities';
|
|
15
|
-
const useNodeColor = ({ isDarkMode, compareMode, cumulative, diff,
|
|
15
|
+
const useNodeColor = ({ isDarkMode, compareMode, cumulative, diff, colorsMap, colorAttribute, }) => {
|
|
16
16
|
if (compareMode) {
|
|
17
17
|
return diffColor(diff ?? 0n, cumulative, isDarkMode);
|
|
18
18
|
}
|
|
19
|
-
return
|
|
19
|
+
return colorsMap[getLastItem(colorAttribute ?? '') ?? EVERYTHING_ELSE];
|
|
20
20
|
};
|
|
21
21
|
export default useNodeColor;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { Table } from 'apache-arrow';
|
|
2
|
-
import { type
|
|
2
|
+
import { type BinaryFeature, type FilenameFeature } from '@parca/store';
|
|
3
3
|
export declare function nodeLabel(table: Table<any>, row: number, level: number, showBinaryName: boolean): string;
|
|
4
|
-
export declare const extractFeature: (mapping: string) =>
|
|
4
|
+
export declare const extractFeature: (mapping: string) => BinaryFeature;
|
|
5
|
+
export declare const extractFilenameFeature: (filename: string) => FilenameFeature;
|
|
5
6
|
export declare const getTextForCumulative: (hoveringNodeCumulative: bigint, totalUnfiltered: bigint, total: bigint, unit: string) => string;
|
|
6
7
|
export declare const getTextForCumulativePerSecond: (hoveringNodeCumulative: number, unit: string) => string;
|
|
7
8
|
export declare const arrowToString: (buffer: any) => string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/utils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAEnC,OAAO,
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/utils.ts"],"names":[],"mappings":"AAaA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAEnC,OAAO,EAIL,KAAK,aAAa,EAClB,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AAWtB,wBAAgB,SAAS,CACvB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,cAAc,EAAE,OAAO,GACtB,MAAM,CAkCR;AAED,eAAO,MAAM,cAAc,YAAa,MAAM,KAAG,aAMhD,CAAC;AAEF,eAAO,MAAM,sBAAsB,aAAc,MAAM,KAAG,eAMzD,CAAC;AAEF,eAAO,MAAM,oBAAoB,2BACP,MAAM,mBACb,MAAM,SAChB,MAAM,QACP,MAAM,KACX,MAOF,CAAC;AAEF,eAAO,MAAM,6BAA6B,2BAChB,MAAM,QACxB,MAAM,KACX,MAMF,CAAC;AAEF,eAAO,MAAM,aAAa,WAAY,GAAG,KAAG,MAAM,GAAG,IAQpD,CAAC"}
|
|
@@ -10,7 +10,7 @@
|
|
|
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 { EVERYTHING_ELSE,
|
|
13
|
+
import { BINARY_FEATURE_TYPES, EVERYTHING_ELSE, FILENAMES_FEATURE_TYPES, } from '@parca/store';
|
|
14
14
|
import { divide, getLastItem, valueFormatter } from '@parca/utilities';
|
|
15
15
|
import { hexifyAddress } from '../../utils';
|
|
16
16
|
import { FIELD_FUNCTION_NAME, FIELD_LABELS_ONLY, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE, } from './index';
|
|
@@ -46,9 +46,15 @@ export function nodeLabel(table, row, level, showBinaryName) {
|
|
|
46
46
|
}
|
|
47
47
|
export const extractFeature = (mapping) => {
|
|
48
48
|
if (mapping != null && mapping !== '') {
|
|
49
|
-
return { name: mapping, type:
|
|
49
|
+
return { name: mapping, type: BINARY_FEATURE_TYPES.Binary };
|
|
50
50
|
}
|
|
51
|
-
return { name: EVERYTHING_ELSE, type:
|
|
51
|
+
return { name: EVERYTHING_ELSE, type: BINARY_FEATURE_TYPES.Misc };
|
|
52
|
+
};
|
|
53
|
+
export const extractFilenameFeature = (filename) => {
|
|
54
|
+
if (filename != null && filename !== '') {
|
|
55
|
+
return { name: filename, type: FILENAMES_FEATURE_TYPES.Filename };
|
|
56
|
+
}
|
|
57
|
+
return { name: EVERYTHING_ELSE, type: FILENAMES_FEATURE_TYPES.Misc };
|
|
52
58
|
};
|
|
53
59
|
export const getTextForCumulative = (hoveringNodeCumulative, totalUnfiltered, total, unit) => {
|
|
54
60
|
const filtered = totalUnfiltered > total
|
|
@@ -15,9 +15,9 @@ interface ProfileIcicleGraphProps {
|
|
|
15
15
|
setActionButtons?: (buttons: React.JSX.Element) => void;
|
|
16
16
|
error?: any;
|
|
17
17
|
isHalfScreen: boolean;
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
metadataMappingFiles?: string[];
|
|
19
|
+
metadataLoading?: boolean;
|
|
20
20
|
}
|
|
21
|
-
declare const ProfileIcicleGraph: ({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, loading, error, width, isHalfScreen,
|
|
21
|
+
declare const ProfileIcicleGraph: ({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, }: ProfileIcicleGraphProps) => JSX.Element;
|
|
22
22
|
export default ProfileIcicleGraph;
|
|
23
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAqC,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAK1D,OAAO,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAY1C,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACvB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,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;CAC3B;AAMD,QAAA,MAAM,kBAAkB,uIAarB,uBAAuB,KAAG,GAAG,CAAC,OA6LhC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -12,6 +12,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
import { useEffect, useMemo, useState } from 'react';
|
|
15
|
+
import { tableFromIPC } from 'apache-arrow';
|
|
15
16
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
16
17
|
import { IcicleGraphSkeleton, useParcaContext, useURLState } from '@parca/components';
|
|
17
18
|
import { capitalizeOnlyFirstLetter, divide, selectQueryParam } from '@parca/utilities';
|
|
@@ -20,23 +21,30 @@ import DiffLegend from '../components/DiffLegend';
|
|
|
20
21
|
import { IcicleGraph } from './IcicleGraph';
|
|
21
22
|
import { FIELD_FUNCTION_NAME, IcicleGraphArrow } from './IcicleGraphArrow';
|
|
22
23
|
import ColorStackLegend from './IcicleGraphArrow/ColorStackLegend';
|
|
23
|
-
import useMappingList from './IcicleGraphArrow/useMappingList';
|
|
24
|
+
import useMappingList, { useFilenamesList } from './IcicleGraphArrow/useMappingList';
|
|
24
25
|
const numberFormatter = new Intl.NumberFormat('en-US');
|
|
25
26
|
const ErrorContent = ({ errorMessage }) => {
|
|
26
27
|
return _jsx("div", { className: "flex justify-center p-10", children: errorMessage });
|
|
27
28
|
};
|
|
28
|
-
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, loading, error, width, isHalfScreen,
|
|
29
|
+
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, }) {
|
|
29
30
|
const { onError, authenticationErrorMessage, isDarkMode } = useParcaContext();
|
|
30
31
|
const { compareMode } = useProfileViewContext();
|
|
31
32
|
const [isLoading, setIsLoading] = useState(true);
|
|
32
33
|
const isColorStackLegendEnabled = selectQueryParam('color_stack_legend') === 'true';
|
|
33
|
-
const
|
|
34
|
+
const table = useMemo(() => {
|
|
35
|
+
return arrow !== undefined ? tableFromIPC(arrow.record) : null;
|
|
36
|
+
}, [arrow]);
|
|
37
|
+
const mappingsList = useMappingList(metadataMappingFiles);
|
|
38
|
+
const filenamesList = useFilenamesList(table);
|
|
34
39
|
const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState('sort_by');
|
|
40
|
+
const [colorBy, setColorBy] = useURLState('color_by');
|
|
35
41
|
// By default, we want delta profiles (CPU) to be relatively compared.
|
|
36
42
|
// For non-delta profiles, like goroutines or memory, we want the profiles to be compared absolutely.
|
|
37
43
|
const compareAbsoluteDefault = profileType?.delta === false ? 'true' : 'false';
|
|
38
44
|
const [compareAbsolute = compareAbsoluteDefault] = useURLState('compare_absolute');
|
|
39
45
|
const isCompareAbsolute = compareAbsolute === 'true';
|
|
46
|
+
const colorByValue = colorBy === undefined || colorBy === '' ? 'binary' : colorBy;
|
|
47
|
+
const mappingsListCount = useMemo(() => mappingsList.filter(m => m !== '').length, [mappingsList]);
|
|
40
48
|
const [totalFormatted, totalUnfilteredFormatted, isTrimmed, trimmedFormatted, trimmedPercentage, isFiltered, filteredPercentage,] = useMemo(() => {
|
|
41
49
|
if (graph === undefined && arrow === undefined) {
|
|
42
50
|
return ['0', '0', false, '0', '0', false, '0', '0'];
|
|
@@ -55,7 +63,14 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
55
63
|
numberFormatter.format(divide(total * 100n, totalUnfilteredDivisor)),
|
|
56
64
|
];
|
|
57
65
|
}, [graph, arrow, filtered, total]);
|
|
58
|
-
const loadingState = !loading && (arrow !== undefined || graph !== undefined) &&
|
|
66
|
+
const loadingState = !loading && (arrow !== undefined || graph !== undefined) && metadataMappingFiles !== undefined;
|
|
67
|
+
// If there is only one mapping file, we want to color by filename by default.
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (mappingsListCount === 1 && colorBy !== 'filename') {
|
|
70
|
+
setColorBy('filename');
|
|
71
|
+
}
|
|
72
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
73
|
+
}, [mappingsListCount]);
|
|
59
74
|
useEffect(() => {
|
|
60
75
|
if (loadingState) {
|
|
61
76
|
setIsLoading(false);
|
|
@@ -103,6 +118,6 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
103
118
|
if (isTrimmed) {
|
|
104
119
|
console.info(`Trimmed ${trimmedFormatted} (${trimmedPercentage}%) too small values.`);
|
|
105
120
|
}
|
|
106
|
-
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, isColorStackLegendEnabled && (_jsx(ColorStackLegend, { compareMode: compareMode, mappings:
|
|
121
|
+
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, isColorStackLegendEnabled && (_jsx(ColorStackLegend, { compareMode: compareMode, mappings: colorByValue === 'binary' ? mappingsList : filenamesList, loading: isLoading })), _jsx("div", { className: "min-h-48", id: "h-icicle-graph", children: _jsx(_Fragment, { children: icicleGraph }) }), _jsxs("p", { className: "my-2 text-xs", children: ["Showing ", totalFormatted, ' ', isFiltered ? (_jsxs("span", { children: ["(", filteredPercentage, "%) filtered of ", totalUnfilteredFormatted, ' '] })) : (_jsx(_Fragment, {})), "values.", ' '] })] }, "icicle-graph-loaded") }));
|
|
107
122
|
};
|
|
108
123
|
export default ProfileIcicleGraph;
|
|
@@ -7,9 +7,9 @@ export interface FlamegraphData {
|
|
|
7
7
|
total?: bigint;
|
|
8
8
|
filtered?: bigint;
|
|
9
9
|
error?: any;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
metadataMappingFiles?: string[];
|
|
11
|
+
metadataLoading: boolean;
|
|
12
|
+
metadataLabels?: string[];
|
|
13
13
|
}
|
|
14
14
|
export interface TopTableData {
|
|
15
15
|
loading: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA0BA,OAAO,EACL,SAAS,IAAI,aAAa,EAC1B,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,UAAU,EACV,GAAG,EACJ,MAAM,eAAe,CAAC;AAUvB,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAO/C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA0BA,OAAO,EACL,SAAS,IAAI,aAAa,EAC1B,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,UAAU,EACV,GAAG,EACJ,MAAM,eAAe,CAAC;AAUvB,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAO/C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAWD,eAAO,MAAM,WAAW,0JAYrB,gBAAgB,KAAG,GAAG,CAAC,OA6UzB,CAAC"}
|
|
@@ -102,7 +102,7 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
|
|
|
102
102
|
? isHalfScreen
|
|
103
103
|
? (dimensions.width - 40) / 2
|
|
104
104
|
: dimensions.width - 16
|
|
105
|
-
: 0,
|
|
105
|
+
: 0, metadataMappingFiles: flamegraphData.metadataMappingFiles, metadataLoading: flamegraphData.metadataLoading }) }));
|
|
106
106
|
}
|
|
107
107
|
case 'callgraph': {
|
|
108
108
|
return callgraphData?.data !== undefined &&
|
|
@@ -162,7 +162,7 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
|
|
|
162
162
|
'items-center mb-2': hasProfileSource,
|
|
163
163
|
}), children: _jsxs("div", { children: [hasProfileSource && (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("div", { className: "text-xs font-medium", children: headerParts.length > 0 ? headerParts[0].replace(/"/g, '') : '' }), _jsx("div", { className: "text-xs font-medium", children: headerParts.length > 1
|
|
164
164
|
? headerParts[headerParts.length - 1].replace(/"/g, '')
|
|
165
|
-
: '' })] })), profileViewExternalMainActions != null ? profileViewExternalMainActions : null] }) }), _jsx(VisualisationToolbar, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, hasProfileSource: hasProfileSource, pprofdownloading: pprofDownloading, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: onDownloadPProf, isMultiPanelView: isMultiPanelView, dashboardItems: dashboardItems, curPath: curPath, setNewCurPath: setNewCurPath, profileType: profileSource?.ProfileType(), total: total, filtered: filtered, currentSearchString: currentSearchString, setSearchString: setSearchString, groupByLabels: flamegraphData.
|
|
165
|
+
: '' })] })), profileViewExternalMainActions != null ? profileViewExternalMainActions : null] }) }), _jsx(VisualisationToolbar, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, hasProfileSource: hasProfileSource, pprofdownloading: pprofDownloading, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: onDownloadPProf, isMultiPanelView: isMultiPanelView, dashboardItems: dashboardItems, curPath: curPath, setNewCurPath: setNewCurPath, profileType: profileSource?.ProfileType(), total: total, filtered: filtered, currentSearchString: currentSearchString, setSearchString: setSearchString, groupByLabels: flamegraphData.metadataLabels ?? [] }), _jsx("div", { className: "w-full", ref: ref, children: _jsx(DragDropContext, { onDragEnd: onDragEnd, children: _jsx(Droppable, { droppableId: "droppable", direction: "horizontal", children: provided => (_jsx("div", { ref: provided.innerRef, className: cx('grid w-full gap-2', isMultiPanelView ? 'grid-cols-2' : 'grid-cols-1'), ...provided.droppableProps, children: dashboardItems.map((dashboardItem, index) => {
|
|
166
166
|
return (_jsx(Draggable, { draggableId: dashboardItem, index: index, isDragDisabled: !isMultiPanelView, children: (provided, snapshot) => (_createElement("div", { ref: provided.innerRef, ...provided.draggableProps, key: dashboardItem, className: cx('w-full min-h-96', snapshot.isDragging
|
|
167
167
|
? 'bg-gray-200 dark:bg-gray-500'
|
|
168
168
|
: 'bg-white dark:bg-gray-900') },
|
|
@@ -142,13 +142,13 @@ export const ProfileViewWithData = ({ queryClient, profileSource, }) => {
|
|
|
142
142
|
total: BigInt(flamegraphResponse?.total ?? '0'),
|
|
143
143
|
filtered: BigInt(flamegraphResponse?.filtered ?? '0'),
|
|
144
144
|
error: flamegraphError,
|
|
145
|
-
|
|
145
|
+
metadataMappingFiles: profileMetadataResponse?.report.oneofKind === 'profileMetadata'
|
|
146
146
|
? profileMetadataResponse?.report?.profileMetadata?.mappingFiles
|
|
147
147
|
: undefined,
|
|
148
|
-
|
|
149
|
-
groupByLabels: profileMetadataResponse?.report.oneofKind === 'profileMetadata'
|
|
148
|
+
metadataLabels: profileMetadataResponse?.report.oneofKind === 'profileMetadata'
|
|
150
149
|
? profileMetadataResponse?.report?.profileMetadata?.labels
|
|
151
|
-
:
|
|
150
|
+
: undefined,
|
|
151
|
+
metadataLoading: profileMetadataLoading,
|
|
152
152
|
}, topTableData: {
|
|
153
153
|
loading: tableLoading,
|
|
154
154
|
arrow: tableResponse?.report.oneofKind === 'tableArrow'
|