@parca/profile 0.17.2 → 0.17.4
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/GraphTooltipArrow/Content.d.ts +1 -2
- package/dist/GraphTooltipArrow/Content.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/Content.js +1 -2
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.d.ts +1 -2
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/DockedGraphTooltip/index.js +1 -2
- package/dist/GraphTooltipArrow/useGraphTooltip/index.d.ts +1 -2
- package/dist/GraphTooltipArrow/useGraphTooltip/index.d.ts.map +1 -1
- package/dist/GraphTooltipArrow/useGraphTooltip/index.js +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts +2 -6
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.js +4 -5
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.d.ts +20 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.d.ts.map +1 -0
- package/{src/Callgraph/constants.ts → dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.js} +12 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts +8 -51
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.js +59 -136
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.d.ts +8 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.d.ts.map +1 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.js +40 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/TooltipContext.d.ts +32 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/TooltipContext.d.ts.map +1 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/TooltipContext.js +40 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +4 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +62 -76
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/utils.d.ts +3 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/utils.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/utils.js +9 -7
- package/dist/ProfileIcicleGraph/index.d.ts +3 -6
- package/dist/ProfileIcicleGraph/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/index.js +8 -16
- package/dist/ProfileView/components/DashboardItems/index.d.ts +3 -5
- package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
- package/dist/ProfileView/components/DashboardItems/index.js +4 -9
- package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/index.js +1 -2
- package/dist/ProfileView/index.d.ts +1 -1
- package/dist/ProfileView/index.d.ts.map +1 -1
- package/dist/ProfileView/index.js +1 -13
- package/dist/ProfileView/types/visualization.d.ts +1 -1
- package/dist/ProfileView/types/visualization.d.ts.map +1 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/styles.css +1 -1
- package/package.json +5 -5
- package/src/GraphTooltipArrow/Content.tsx +0 -3
- package/src/GraphTooltipArrow/DockedGraphTooltip/index.tsx +0 -3
- package/src/GraphTooltipArrow/useGraphTooltip/index.ts +1 -3
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx +5 -13
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.tsx +53 -0
- package/src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx +96 -310
- package/src/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.tsx +78 -0
- package/src/ProfileIcicleGraph/IcicleGraphArrow/TooltipContext.tsx +93 -0
- package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +110 -213
- package/src/ProfileIcicleGraph/IcicleGraphArrow/utils.ts +8 -15
- package/src/ProfileIcicleGraph/index.tsx +7 -36
- package/src/ProfileView/components/DashboardItems/index.tsx +2 -27
- package/src/ProfileView/components/Toolbars/index.tsx +0 -2
- package/src/ProfileView/index.tsx +0 -14
- package/src/ProfileView/types/visualization.ts +1 -1
- package/src/index.tsx +0 -5
- package/dist/Callgraph/constants.d.ts +0 -3
- package/dist/Callgraph/constants.d.ts.map +0 -1
- package/dist/Callgraph/constants.js +0 -14
- package/dist/Callgraph/index.d.ts +0 -11
- package/dist/Callgraph/index.d.ts.map +0 -1
- package/dist/Callgraph/index.js +0 -104
- package/dist/Callgraph/mockData/index.d.ts +0 -149
- package/dist/Callgraph/mockData/index.d.ts.map +0 -1
- package/dist/Callgraph/mockData/index.js +0 -594
- package/dist/Callgraph/utils.d.ts +0 -20
- package/dist/Callgraph/utils.d.ts.map +0 -1
- package/dist/Callgraph/utils.js +0 -97
- package/dist/GraphTooltip/ExpandOnHoverValue.d.ts +0 -7
- package/dist/GraphTooltip/ExpandOnHoverValue.d.ts.map +0 -1
- package/dist/GraphTooltip/ExpandOnHoverValue.js +0 -4
- package/dist/GraphTooltip/index.d.ts +0 -41
- package/dist/GraphTooltip/index.d.ts.map +0 -1
- package/dist/GraphTooltip/index.js +0 -201
- package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.d.ts +0 -6
- package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.d.ts.map +0 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.js +0 -59
- package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.d.ts +0 -47
- package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.d.ts.map +0 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.js +0 -93
- package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts +0 -14
- package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts.map +0 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/index.js +0 -48
- package/dist/ProfileIcicleGraph/IcicleGraph/useColoredGraph.d.ts +0 -15
- package/dist/ProfileIcicleGraph/IcicleGraph/useColoredGraph.d.ts.map +0 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/useColoredGraph.js +0 -57
- package/dist/ProfileIcicleGraph/IcicleGraph/useNodeColor.d.ts +0 -8
- package/dist/ProfileIcicleGraph/IcicleGraph/useNodeColor.d.ts.map +0 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/useNodeColor.js +0 -32
- package/dist/ProfileIcicleGraph/IcicleGraph/utils.d.ts +0 -7
- package/dist/ProfileIcicleGraph/IcicleGraph/utils.d.ts.map +0 -1
- package/dist/ProfileIcicleGraph/IcicleGraph/utils.js +0 -66
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleChartRootNode.d.ts +0 -9
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleChartRootNode.d.ts.map +0 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleChartRootNode.js +0 -45
- package/dist/ProfileView/hooks/useGraphviz.d.ts +0 -12
- package/dist/ProfileView/hooks/useGraphviz.d.ts.map +0 -1
- package/dist/ProfileView/hooks/useGraphviz.js +0 -42
- package/src/Callgraph/index.tsx +0 -177
- package/src/Callgraph/mockData/index.ts +0 -605
- package/src/Callgraph/utils.ts +0 -141
- package/src/GraphTooltip/ExpandOnHoverValue.tsx +0 -30
- package/src/GraphTooltip/index.tsx +0 -509
- package/src/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.tsx +0 -96
- package/src/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.tsx +0 -266
- package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +0 -123
- package/src/ProfileIcicleGraph/IcicleGraph/useColoredGraph.ts +0 -117
- package/src/ProfileIcicleGraph/IcicleGraph/useNodeColor.ts +0 -54
- package/src/ProfileIcicleGraph/IcicleGraph/utils.ts +0 -102
- package/src/ProfileIcicleGraph/IcicleGraphArrow/IcicleChartRootNode.tsx +0 -130
- package/src/ProfileView/hooks/useGraphviz.ts +0 -69
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2022 The Parca Authors
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { memo, useEffect, useState } from 'react';
|
|
15
|
+
import GraphTooltipArrow from '../../GraphTooltipArrow';
|
|
16
|
+
import GraphTooltipArrowContent from '../../GraphTooltipArrow/Content';
|
|
17
|
+
import { DockedGraphTooltip } from '../../GraphTooltipArrow/DockedGraphTooltip';
|
|
18
|
+
import { useTooltipContext } from './TooltipContext';
|
|
19
|
+
export const MemoizedTooltip = memo(function MemoizedTooltip({ contextElement, dockedMetainfo, }) {
|
|
20
|
+
const [tooltipRow, setTooltipRow] = useState(null);
|
|
21
|
+
const { table, total, totalUnfiltered, profileType, unit, compareAbsolute } = useTooltipContext();
|
|
22
|
+
// This component subscribes to tooltip updates through a callback
|
|
23
|
+
// passed to the TooltipProvider, avoiding the need to lift state
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const handleTooltipUpdate = (event) => {
|
|
26
|
+
setTooltipRow(event.detail.row);
|
|
27
|
+
};
|
|
28
|
+
window.addEventListener('icicle-tooltip-update', handleTooltipUpdate);
|
|
29
|
+
return () => {
|
|
30
|
+
window.removeEventListener('icicle-tooltip-update', handleTooltipUpdate);
|
|
31
|
+
};
|
|
32
|
+
}, []);
|
|
33
|
+
if (dockedMetainfo) {
|
|
34
|
+
return (_jsx(DockedGraphTooltip, { table: table, row: tooltipRow, total: total, totalUnfiltered: totalUnfiltered, profileType: profileType, unit: unit, compareAbsolute: compareAbsolute }));
|
|
35
|
+
}
|
|
36
|
+
if (tooltipRow === null) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
return (_jsx(GraphTooltipArrow, { contextElement: contextElement, children: _jsx(GraphTooltipArrowContent, { table: table, row: tooltipRow, isFixed: false, total: total, totalUnfiltered: totalUnfiltered, profileType: profileType, unit: unit, compareAbsolute: compareAbsolute }) }));
|
|
40
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Table } from 'apache-arrow';
|
|
3
|
+
import { ProfileType } from '@parca/parser';
|
|
4
|
+
interface TooltipState {
|
|
5
|
+
row: number | null;
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
}
|
|
9
|
+
interface TooltipContextValue {
|
|
10
|
+
table: Table<any>;
|
|
11
|
+
total: bigint;
|
|
12
|
+
totalUnfiltered: bigint;
|
|
13
|
+
profileType?: ProfileType;
|
|
14
|
+
unit?: string;
|
|
15
|
+
compareAbsolute: boolean;
|
|
16
|
+
updateTooltip: (row: number | null, x?: number, y?: number) => void;
|
|
17
|
+
tooltipState: TooltipState;
|
|
18
|
+
}
|
|
19
|
+
export declare const useTooltipContext: () => TooltipContextValue;
|
|
20
|
+
interface TooltipProviderProps {
|
|
21
|
+
children: React.ReactNode;
|
|
22
|
+
table: Table<any>;
|
|
23
|
+
total: bigint;
|
|
24
|
+
totalUnfiltered: bigint;
|
|
25
|
+
profileType?: ProfileType;
|
|
26
|
+
unit?: string;
|
|
27
|
+
compareAbsolute: boolean;
|
|
28
|
+
onTooltipUpdate?: (state: TooltipState) => void;
|
|
29
|
+
}
|
|
30
|
+
export declare const TooltipProvider: React.FC<TooltipProviderProps>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=TooltipContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TooltipContext.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/TooltipContext.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgE,MAAM,OAAO,CAAC;AAErF,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,UAAU,YAAY;IACpB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,UAAU,mBAAmB;IAC3B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IACpE,YAAY,EAAE,YAAY,CAAC;CAC5B;AAID,eAAO,MAAM,iBAAiB,QAAO,mBAMpC,CAAC;AAEF,UAAU,oBAAoB;IAC5B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CACjD;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAmC1D,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Copyright 2022 The Parca Authors
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
import { createContext, useCallback, useContext, useMemo, useRef } from 'react';
|
|
15
|
+
const TooltipContext = createContext(null);
|
|
16
|
+
export const useTooltipContext = () => {
|
|
17
|
+
const context = useContext(TooltipContext);
|
|
18
|
+
if (context === undefined || context === null) {
|
|
19
|
+
throw new Error('useTooltipContext must be used within TooltipProvider');
|
|
20
|
+
}
|
|
21
|
+
return context;
|
|
22
|
+
};
|
|
23
|
+
export const TooltipProvider = ({ children, table, total, totalUnfiltered, profileType, unit, compareAbsolute, onTooltipUpdate, }) => {
|
|
24
|
+
const tooltipStateRef = useRef({ row: null, x: 0, y: 0 });
|
|
25
|
+
const updateTooltip = useCallback((row, x = 0, y = 0) => {
|
|
26
|
+
tooltipStateRef.current = { row, x, y };
|
|
27
|
+
onTooltipUpdate?.(tooltipStateRef.current);
|
|
28
|
+
}, [onTooltipUpdate]);
|
|
29
|
+
const value = useMemo(() => ({
|
|
30
|
+
table,
|
|
31
|
+
total,
|
|
32
|
+
totalUnfiltered,
|
|
33
|
+
profileType,
|
|
34
|
+
unit,
|
|
35
|
+
compareAbsolute,
|
|
36
|
+
updateTooltip,
|
|
37
|
+
tooltipState: tooltipStateRef.current,
|
|
38
|
+
}), [table, total, totalUnfiltered, profileType, unit, compareAbsolute, updateTooltip]);
|
|
39
|
+
return _jsx(TooltipContext.Provider, { value: value, children: children });
|
|
40
|
+
};
|
|
@@ -23,17 +23,18 @@ export declare const FIELD_LABELS = "labels";
|
|
|
23
23
|
export declare const FIELD_CUMULATIVE = "cumulative";
|
|
24
24
|
export declare const FIELD_FLAT = "flat";
|
|
25
25
|
export declare const FIELD_DIFF = "diff";
|
|
26
|
+
export declare const FIELD_PARENT = "parent";
|
|
27
|
+
export declare const FIELD_DEPTH = "depth";
|
|
28
|
+
export declare const FIELD_VALUE_OFFSET = "value_offset";
|
|
26
29
|
interface IcicleGraphArrowProps {
|
|
27
30
|
arrow: FlamegraphArrow;
|
|
28
31
|
total: bigint;
|
|
29
32
|
filtered: bigint;
|
|
30
33
|
profileType?: ProfileType;
|
|
31
|
-
profileSource
|
|
34
|
+
profileSource: ProfileSource;
|
|
32
35
|
width?: number;
|
|
33
36
|
curPath: CurrentPathFrame[];
|
|
34
37
|
setCurPath: (path: CurrentPathFrame[]) => void;
|
|
35
|
-
sortBy: string;
|
|
36
|
-
flamegraphLoading: boolean;
|
|
37
38
|
isHalfScreen: boolean;
|
|
38
39
|
mappingsListFromMetadata: string[];
|
|
39
40
|
compareAbsolute: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx"],"names":[],"mappings":"AAaA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAqD,MAAM,OAAO,CAAC;AAK1E,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAc,KAAK,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAE/D,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAGlD,OAAO,EAAwB,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAIxE,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,qBAAqB;IAC7B,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,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;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,mDA8N3B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
// Copyright 2022 The Parca Authors
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -11,22 +11,20 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
11
11
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
|
-
import { memo, useCallback,
|
|
14
|
+
import { memo, useCallback, useMemo, useRef, useState } from 'react';
|
|
15
15
|
import { tableFromIPC } from 'apache-arrow';
|
|
16
16
|
import { useContextMenu } from 'react-contexify';
|
|
17
17
|
import { useURLState } from '@parca/components';
|
|
18
18
|
import { USER_PREFERENCES, useCurrentColorProfile, useUserPreference } from '@parca/hooks';
|
|
19
|
-
import { getColorForFeature, selectDarkMode,
|
|
20
|
-
import { getLastItem
|
|
21
|
-
import GraphTooltipArrow from '../../GraphTooltipArrow';
|
|
22
|
-
import GraphTooltipArrowContent from '../../GraphTooltipArrow/Content';
|
|
23
|
-
import { DockedGraphTooltip } from '../../GraphTooltipArrow/DockedGraphTooltip';
|
|
19
|
+
import { getColorForFeature, selectDarkMode, useAppSelector } from '@parca/store';
|
|
20
|
+
import { getLastItem } from '@parca/utilities';
|
|
24
21
|
import { useProfileViewContext } from '../../ProfileView/context/ProfileViewContext';
|
|
25
|
-
import
|
|
26
|
-
import { IcicleChartRootNode } from './IcicleChartRootNode';
|
|
22
|
+
import ContextMenuWrapper from './ContextMenuWrapper';
|
|
27
23
|
import { IcicleNode, RowHeight } from './IcicleGraphNodes';
|
|
24
|
+
import { MemoizedTooltip } from './MemoizedTooltip';
|
|
25
|
+
import { TooltipProvider } from './TooltipContext';
|
|
28
26
|
import { useFilenamesList } from './useMappingList';
|
|
29
|
-
import { arrowToString, extractFeature, extractFilenameFeature } from './utils';
|
|
27
|
+
import { arrowToString, extractFeature, extractFilenameFeature, getCurrentPathFrameData, isCurrentPathFrameMatch, } from './utils';
|
|
30
28
|
export const FIELD_LABELS_ONLY = 'labels_only';
|
|
31
29
|
export const FIELD_MAPPING_FILE = 'mapping_file';
|
|
32
30
|
export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
|
|
@@ -45,6 +43,9 @@ export const FIELD_LABELS = 'labels';
|
|
|
45
43
|
export const FIELD_CUMULATIVE = 'cumulative';
|
|
46
44
|
export const FIELD_FLAT = 'flat';
|
|
47
45
|
export const FIELD_DIFF = 'diff';
|
|
46
|
+
export const FIELD_PARENT = 'parent';
|
|
47
|
+
export const FIELD_DEPTH = 'depth';
|
|
48
|
+
export const FIELD_VALUE_OFFSET = 'value_offset';
|
|
48
49
|
export const getMappingColors = (mappingsList, isDarkMode, currentColorProfile) => {
|
|
49
50
|
const mappingFeatures = mappingsList.map(mapping => extractFeature(mapping));
|
|
50
51
|
const colors = {};
|
|
@@ -62,21 +63,15 @@ export const getFilenameColors = (filenamesList, isDarkMode, currentColorProfile
|
|
|
62
63
|
return colors;
|
|
63
64
|
};
|
|
64
65
|
const noop = () => { };
|
|
65
|
-
export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, profileType, profileSource,
|
|
66
|
-
const [isContextMenuOpen, setIsContextMenuOpen] = useState(false);
|
|
67
|
-
const dispatch = useAppDispatch();
|
|
66
|
+
export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, profileType, profileSource, mappingsListFromMetadata, compareAbsolute, isIcicleChart = false, }) {
|
|
68
67
|
const [highlightSimilarStacksPreference] = useUserPreference(USER_PREFERENCES.HIGHLIGHT_SIMILAR_STACKS.key);
|
|
68
|
+
const [hoveringRow, setHoveringRow] = useState(undefined);
|
|
69
69
|
const [dockedMetainfo] = useUserPreference(USER_PREFERENCES.GRAPH_METAINFO_DOCKED.key);
|
|
70
70
|
const isDarkMode = useAppSelector(selectDarkMode);
|
|
71
71
|
const table = useMemo(() => {
|
|
72
72
|
return tableFromIPC(arrow.record);
|
|
73
73
|
}, [arrow]);
|
|
74
|
-
const [height, setHeight] = useState(0);
|
|
75
|
-
const [hoveringRow, setHoveringRow] = useState(null);
|
|
76
|
-
const [hoveringLevel, setHoveringLevel] = useState(null);
|
|
77
|
-
const [hoveringName, setHoveringName] = useState(null);
|
|
78
74
|
const svg = useRef(null);
|
|
79
|
-
const ref = useRef(null);
|
|
80
75
|
const [binaryFrameFilter, setBinaryFrameFilter] = useURLState('binary_frame_filter');
|
|
81
76
|
const [currentSearchString] = useURLState('search_string');
|
|
82
77
|
const { compareMode } = useProfileViewContext();
|
|
@@ -123,32 +118,17 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
123
118
|
binary: mappingColors,
|
|
124
119
|
};
|
|
125
120
|
const colorByColors = colorByList[colorByValue];
|
|
126
|
-
useEffect(() => {
|
|
127
|
-
if (ref.current != null) {
|
|
128
|
-
setHeight(ref?.current.getBoundingClientRect().height);
|
|
129
|
-
}
|
|
130
|
-
}, [width, flamegraphLoading]);
|
|
131
|
-
const xScale = useMemo(() => {
|
|
132
|
-
if (total === 0n) {
|
|
133
|
-
return () => 0;
|
|
134
|
-
}
|
|
135
|
-
if (width === undefined) {
|
|
136
|
-
return () => 0;
|
|
137
|
-
}
|
|
138
|
-
return scaleLinear([0n, total], [0, width]);
|
|
139
|
-
}, [total, width]);
|
|
140
121
|
const MENU_ID = 'icicle-graph-context-menu';
|
|
122
|
+
const contextMenuRef = useRef(null);
|
|
141
123
|
const { show, hideAll } = useContextMenu({
|
|
142
124
|
id: MENU_ID,
|
|
143
125
|
});
|
|
144
|
-
const displayMenu = useCallback((e) => {
|
|
126
|
+
const displayMenu = useCallback((e, row) => {
|
|
127
|
+
contextMenuRef.current?.setRow(row);
|
|
145
128
|
show({
|
|
146
129
|
event: e,
|
|
147
130
|
});
|
|
148
131
|
}, [show]);
|
|
149
|
-
const trackVisibility = (isVisible) => {
|
|
150
|
-
setIsContextMenuOpen(isVisible);
|
|
151
|
-
};
|
|
152
132
|
const hideBinary = (binaryToRemove) => {
|
|
153
133
|
// second/subsequent time filtering out a binary i.e. a binary has already been hidden
|
|
154
134
|
// and we want to hide more binaries, we simply remove the binary from the binaryFrameFilter array in the URL.
|
|
@@ -161,46 +141,52 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
161
141
|
const newMappingsList = mappingsListFromMetadata.filter(mapping => mapping !== binaryToRemove);
|
|
162
142
|
setBinaryFrameFilter(newMappingsList);
|
|
163
143
|
};
|
|
164
|
-
const
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
144
|
+
const handleRowClick = (row) => {
|
|
145
|
+
// Walk down the stack starting at row until we reach the root (row 0).
|
|
146
|
+
const path = [];
|
|
147
|
+
let currentRow = row;
|
|
148
|
+
while (currentRow > 0) {
|
|
149
|
+
const frame = getCurrentPathFrameData(table, currentRow);
|
|
150
|
+
path.push(frame);
|
|
151
|
+
currentRow = table.getChild(FIELD_PARENT)?.get(currentRow) ?? 0;
|
|
152
|
+
}
|
|
153
|
+
// Reverse the path so that the root is first.
|
|
154
|
+
path.reverse();
|
|
155
|
+
setCurPath(path);
|
|
156
|
+
};
|
|
157
|
+
const depthColumn = table.getChild(FIELD_DEPTH);
|
|
158
|
+
const maxDepth = depthColumn === null ? 0 : Math.max(...depthColumn.toArray());
|
|
159
|
+
const height = maxDepth * RowHeight;
|
|
160
|
+
// To find the selected row, we must walk the current path and look at which
|
|
161
|
+
// children of the current frame matches the path element exactly. Until the
|
|
162
|
+
// end, the row we find at the end is our selected row.
|
|
163
|
+
let currentRow = 0;
|
|
164
|
+
for (const frame of curPath) {
|
|
165
|
+
let childRows = Array.from(table.getChild(FIELD_CHILDREN)?.get(currentRow) ?? []);
|
|
166
|
+
if (childRows.length === 0) {
|
|
167
|
+
// If there are no children, we can stop here.
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
childRows = childRows.filter(c => isCurrentPathFrameMatch(table, c, frame));
|
|
171
|
+
if (childRows.length === 0) {
|
|
172
|
+
// If there are no children that match the current path frame, we can stop here.
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
if (childRows.length > 1) {
|
|
176
|
+
// If there are multiple children that match the current path frame, we can stop here.
|
|
177
|
+
// This is a case where the path is ambiguous and we cannot determine a single row.
|
|
178
|
+
break;
|
|
176
179
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
xScale,
|
|
189
|
-
currentSearchString,
|
|
190
|
-
sortBy,
|
|
191
|
-
isDarkMode,
|
|
192
|
-
compareMode,
|
|
193
|
-
profileType,
|
|
194
|
-
isContextMenuOpen,
|
|
195
|
-
highlightSimilarStacksName,
|
|
196
|
-
highlightSimilarStacksRow,
|
|
197
|
-
colorForSimilarNodes,
|
|
198
|
-
highlightSimilarStacksPreference,
|
|
199
|
-
path,
|
|
200
|
-
highlightSimilarStacksSetName,
|
|
201
|
-
isIcicleChart,
|
|
202
|
-
profileSource,
|
|
203
|
-
]);
|
|
204
|
-
return (_jsx(_Fragment, { children: _jsxs("div", { className: "relative", onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [_jsx(ContextMenu, { menuId: MENU_ID, table: table, row: hoveringRow ?? 0, level: hoveringLevel ?? 0, total: total, totalUnfiltered: total + filtered, profileType: profileType, compareAbsolute: compareAbsolute, trackVisibility: trackVisibility, curPath: curPath, setCurPath: setCurPath, hideMenu: hideAll, hideBinary: hideBinary, unit: arrow.unit }), dockedMetainfo ? (_jsx(DockedGraphTooltip, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, total: total, totalUnfiltered: total + filtered, profileType: profileType, unit: arrow.unit, compareAbsolute: compareAbsolute })) : (!isContextMenuOpen && (_jsx(GraphTooltipArrow, { contextElement: svg.current, isContextMenuOpen: isContextMenuOpen, children: _jsx(GraphTooltipArrowContent, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, isFixed: false, total: total, totalUnfiltered: total + filtered, profileType: profileType, unit: arrow.unit, compareAbsolute: compareAbsolute }) }))), root] }) }));
|
|
180
|
+
// If there is exactly one child that matches the current path frame, we can continue.
|
|
181
|
+
currentRow = childRows[0];
|
|
182
|
+
}
|
|
183
|
+
const selectedRow = currentRow;
|
|
184
|
+
return (_jsx(TooltipProvider, { table: table, total: total, totalUnfiltered: total + filtered, profileType: profileType, unit: arrow.unit, compareAbsolute: compareAbsolute, children: _jsxs("div", { className: "relative", children: [_jsx(ContextMenuWrapper, { ref: contextMenuRef, menuId: MENU_ID, table: table, total: total, totalUnfiltered: total + filtered, compareAbsolute: compareAbsolute, resetPath: () => setCurPath([]), hideMenu: hideAll, hideBinary: hideBinary, unit: arrow.unit, profileType: profileType }), _jsx(MemoizedTooltip, { contextElement: svg.current, dockedMetainfo: dockedMetainfo }), _jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, children: Array.from({ length: table.numRows }, (_, row) => (_jsx(IcicleNode, { table: table, row: row, colors: colorByColors, colorBy: colorByValue, totalWidth: width ?? 1, height: RowHeight, searchString: currentSearchString ?? '', darkMode: isDarkMode, compareMode: compareMode, colorForSimilarNodes: colorForSimilarNodes, selectedRow: selectedRow, onClick: () => {
|
|
185
|
+
if (isIcicleChart) {
|
|
186
|
+
// We don't want to expand in icicle charts.
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
handleRowClick(row);
|
|
190
|
+
}, onContextMenu: displayMenu, hoveringRow: highlightSimilarStacksPreference ? hoveringRow : undefined, setHoveringRow: highlightSimilarStacksPreference ? setHoveringRow : noop, isIcicleChart: isIcicleChart, profileSource: profileSource }, row))) })] }) }));
|
|
205
191
|
});
|
|
206
192
|
export default IcicleGraphArrow;
|
|
@@ -2,7 +2,7 @@ import { Table } from 'apache-arrow';
|
|
|
2
2
|
import { type BinaryFeature, type FilenameFeature } from '@parca/store';
|
|
3
3
|
import { ProfileSource } from '../../ProfileSource';
|
|
4
4
|
import { BigIntDuo } from '../../utils';
|
|
5
|
-
export declare function nodeLabel(table: Table<any>, row: number,
|
|
5
|
+
export declare function nodeLabel(table: Table<any>, row: number, showBinaryName: boolean): string;
|
|
6
6
|
export declare const extractFeature: (mapping: string) => BinaryFeature;
|
|
7
7
|
export declare const extractFilenameFeature: (filename: string) => FilenameFeature;
|
|
8
8
|
export declare const getTextForCumulative: (hoveringNodeCumulative: bigint, totalUnfiltered: bigint, total: bigint, unit: string) => string;
|
|
@@ -18,6 +18,6 @@ export interface CurrentPathFrame {
|
|
|
18
18
|
inlined: boolean;
|
|
19
19
|
labels?: string;
|
|
20
20
|
}
|
|
21
|
-
export declare const getCurrentPathFrameData: (table: Table<any>, row: number
|
|
22
|
-
export declare function isCurrentPathFrameMatch(table: Table<any>, row: number,
|
|
21
|
+
export declare const getCurrentPathFrameData: (table: Table<any>, row: number) => CurrentPathFrame;
|
|
22
|
+
export declare function isCurrentPathFrameMatch(table: Table<any>, row: number, b: CurrentPathFrame): boolean;
|
|
23
23
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -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,EAIL,KAAK,aAAa,EAClB,KAAK,eAAe,EACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAsB,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAC,SAAS,EAAgB,MAAM,aAAa,CAAC;
|
|
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;AAGtB,OAAO,EAAsB,aAAa,EAAC,MAAM,qBAAqB,CAAC;AACvE,OAAO,EAAC,SAAS,EAAgB,MAAM,aAAa,CAAC;AAWrD,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,GAAG,MAAM,CAuBzF;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;AAEF,eAAO,MAAM,uBAAuB,mBAAoB,aAAa,KAAG,SAyBvE,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,uBAAuB,UAAW,KAAK,CAAC,GAAG,CAAC,OAAO,MAAM,KAAG,gBAwBxE,CAAC;AAgBF,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,GAAG,EAAE,MAAM,EACX,CAAC,EAAE,gBAAgB,GAClB,OAAO,CAWT"}
|
|
@@ -14,10 +14,11 @@ import { BINARY_FEATURE_TYPES, EVERYTHING_ELSE, FILENAMES_FEATURE_TYPES, } from
|
|
|
14
14
|
import { divide, getLastItem, valueFormatter } from '@parca/utilities';
|
|
15
15
|
import { MergedProfileSource } from '../../ProfileSource';
|
|
16
16
|
import { hexifyAddress } from '../../utils';
|
|
17
|
-
import { FIELD_FUNCTION_NAME, FIELD_FUNCTION_START_LINE, FIELD_INLINED, FIELD_LABELS_ONLY, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE, } from './index';
|
|
18
|
-
export function nodeLabel(table, row,
|
|
17
|
+
import { FIELD_DEPTH, FIELD_FUNCTION_NAME, FIELD_FUNCTION_START_LINE, FIELD_INLINED, FIELD_LABELS_ONLY, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE, } from './index';
|
|
18
|
+
export function nodeLabel(table, row, showBinaryName) {
|
|
19
19
|
const labelsOnly = table.getChild(FIELD_LABELS_ONLY)?.get(row);
|
|
20
|
-
|
|
20
|
+
const depth = table.getChild(FIELD_DEPTH)?.get(row) ?? 0;
|
|
21
|
+
if (depth === 1 && labelsOnly !== null && labelsOnly) {
|
|
21
22
|
return getLabelSet(table, row);
|
|
22
23
|
}
|
|
23
24
|
const functionName = arrowToString(table.getChild(FIELD_FUNCTION_NAME)?.get(row));
|
|
@@ -84,7 +85,7 @@ export const boundsFromProfileSource = (profileSource) => {
|
|
|
84
85
|
const end = request.options.merge.end.seconds * 1000000000n + BigInt(request.options.merge.end.nanos);
|
|
85
86
|
return [start, end];
|
|
86
87
|
};
|
|
87
|
-
export const getCurrentPathFrameData = (table, row
|
|
88
|
+
export const getCurrentPathFrameData = (table, row) => {
|
|
88
89
|
const functionName = arrowToString(table.getChild(FIELD_FUNCTION_NAME)?.get(row));
|
|
89
90
|
const systemName = arrowToString(table.getChild(FIELD_FUNCTION_NAME)?.get(row));
|
|
90
91
|
const fileName = arrowToString(table.getChild(FIELD_MAPPING_FILE)?.get(row));
|
|
@@ -93,8 +94,9 @@ export const getCurrentPathFrameData = (table, row, level) => {
|
|
|
93
94
|
const address = hexifyAddress(addressBigInt);
|
|
94
95
|
const inlined = table.getChild(FIELD_INLINED)?.get(row);
|
|
95
96
|
const labelsOnly = table.getChild(FIELD_LABELS_ONLY)?.get(row);
|
|
97
|
+
const depth = table.getChild(FIELD_DEPTH)?.get(row) ?? 0;
|
|
96
98
|
let labels;
|
|
97
|
-
if (
|
|
99
|
+
if (depth === 1 && labelsOnly !== null && labelsOnly) {
|
|
98
100
|
labels = getLabelSet(table, row);
|
|
99
101
|
}
|
|
100
102
|
return {
|
|
@@ -119,8 +121,8 @@ function getLabelSet(table, row) {
|
|
|
119
121
|
.map(([k, v]) => `${k}="${v}"`)
|
|
120
122
|
.join(', ');
|
|
121
123
|
}
|
|
122
|
-
export function isCurrentPathFrameMatch(table, row,
|
|
123
|
-
const a = getCurrentPathFrameData(table, row
|
|
124
|
+
export function isCurrentPathFrameMatch(table, row, b) {
|
|
125
|
+
const a = getCurrentPathFrameData(table, row);
|
|
124
126
|
return (a.functionName === b.functionName &&
|
|
125
127
|
a.systemName === b.systemName &&
|
|
126
128
|
a.fileName === b.fileName &&
|
|
@@ -1,19 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { FlamegraphArrow } from '@parca/client';
|
|
3
3
|
import { ProfileType } from '@parca/parser';
|
|
4
4
|
import { MergedProfileSource, ProfileSource } from '../ProfileSource';
|
|
5
5
|
import { CurrentPathFrame } from './IcicleGraphArrow/utils';
|
|
6
6
|
export type ResizeHandler = (width: number, height: number) => void;
|
|
7
7
|
interface ProfileIcicleGraphProps {
|
|
8
8
|
width: number;
|
|
9
|
-
graph?: Flamegraph;
|
|
10
9
|
arrow?: FlamegraphArrow;
|
|
11
10
|
total: bigint;
|
|
12
11
|
filtered: bigint;
|
|
13
12
|
profileType?: ProfileType;
|
|
14
|
-
profileSource
|
|
15
|
-
curPath: string[] | [];
|
|
16
|
-
setNewCurPath: (path: string[]) => void;
|
|
13
|
+
profileSource: ProfileSource;
|
|
17
14
|
curPathArrow: CurrentPathFrame[] | [];
|
|
18
15
|
setNewCurPathArrow: (path: CurrentPathFrame[]) => void;
|
|
19
16
|
loading: boolean;
|
|
@@ -29,6 +26,6 @@ export declare const validateIcicleChartQuery: (profileSource: MergedProfileSour
|
|
|
29
26
|
isNonDelta: boolean;
|
|
30
27
|
isDurationTooLong: boolean;
|
|
31
28
|
};
|
|
32
|
-
declare const ProfileIcicleGraph: ({
|
|
29
|
+
declare const ProfileIcicleGraph: ({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isIcicleChart, profileSource, }: ProfileIcicleGraphProps) => JSX.Element;
|
|
33
30
|
export default ProfileIcicleGraph;
|
|
34
31
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAKhF,OAAO,EAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA2D,MAAM,OAAO,CAAC;AAKhF,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAE9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAG1C,OAAO,EAAC,mBAAmB,EAAE,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAMpE,OAAO,EAAC,gBAAgB,EAA0B,MAAM,0BAA0B,CAAC;AAInF,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,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,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAUD,eAAO,MAAM,wBAAwB,kBACpB,mBAAmB,KACjC;IAAC,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,EAAE,OAAO,CAAC;IAAC,iBAAiB,EAAE,OAAO,CAAA;CAIpE,CAAC;AAEF,QAAA,MAAM,kBAAkB,wKAcrB,uBAAuB,KAAG,GAAG,CAAC,OA8OhC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -19,8 +19,7 @@ import { capitalizeOnlyFirstLetter, divide } from '@parca/utilities';
|
|
|
19
19
|
import DiffLegend from '../ProfileView/components/DiffLegend';
|
|
20
20
|
import { useProfileViewContext } from '../ProfileView/context/ProfileViewContext';
|
|
21
21
|
import { TimelineGuide } from '../TimelineGuide';
|
|
22
|
-
import {
|
|
23
|
-
import { FIELD_FUNCTION_NAME, IcicleGraphArrow } from './IcicleGraphArrow';
|
|
22
|
+
import { IcicleGraphArrow } from './IcicleGraphArrow';
|
|
24
23
|
import useMappingList from './IcicleGraphArrow/useMappingList';
|
|
25
24
|
import { boundsFromProfileSource } from './IcicleGraphArrow/utils';
|
|
26
25
|
const numberFormatter = new Intl.NumberFormat('en-US');
|
|
@@ -32,13 +31,12 @@ export const validateIcicleChartQuery = (profileSource) => {
|
|
|
32
31
|
const isDurationTooLong = profileSource.mergeTo - profileSource.mergeFrom > 60000;
|
|
33
32
|
return { isValid: !isNonDelta && !isDurationTooLong, isNonDelta, isDurationTooLong };
|
|
34
33
|
};
|
|
35
|
-
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
34
|
+
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isIcicleChart = false, profileSource, }) {
|
|
36
35
|
const { onError, authenticationErrorMessage, isDarkMode, iciclechartHelpText } = useParcaContext();
|
|
37
36
|
const { compareMode } = useProfileViewContext();
|
|
38
37
|
const [isLoading, setIsLoading] = useState(true);
|
|
39
38
|
const [icicleChartRef, { height: icicleChartHeight }] = useMeasure();
|
|
40
39
|
const mappingsList = useMappingList(metadataMappingFiles);
|
|
41
|
-
const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState('sort_by');
|
|
42
40
|
const [colorBy, setColorBy] = useURLState('color_by');
|
|
43
41
|
// By default, we want delta profiles (CPU) to be relatively compared.
|
|
44
42
|
// For non-delta profiles, like goroutines or memory, we want the profiles to be compared absolutely.
|
|
@@ -47,10 +45,10 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
47
45
|
const isCompareAbsolute = compareAbsolute === 'true';
|
|
48
46
|
const mappingsListCount = useMemo(() => mappingsList.filter(m => m !== '').length, [mappingsList]);
|
|
49
47
|
const [totalFormatted, totalUnfilteredFormatted, isTrimmed, trimmedFormatted, trimmedPercentage, isFiltered, filteredPercentage,] = useMemo(() => {
|
|
50
|
-
if (
|
|
48
|
+
if (arrow === undefined) {
|
|
51
49
|
return ['0', '0', false, '0', '0', false, '0', '0'];
|
|
52
50
|
}
|
|
53
|
-
const trimmed =
|
|
51
|
+
const trimmed = arrow?.trimmed ?? 0n;
|
|
54
52
|
const totalUnfiltered = total + filtered;
|
|
55
53
|
// safeguard against division by zero
|
|
56
54
|
const totalUnfilteredDivisor = totalUnfiltered > 0 ? totalUnfiltered : 1n;
|
|
@@ -63,8 +61,8 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
63
61
|
filtered > 0,
|
|
64
62
|
numberFormatter.format(divide(total * 100n, totalUnfilteredDivisor)),
|
|
65
63
|
];
|
|
66
|
-
}, [
|
|
67
|
-
const loadingState = !loading &&
|
|
64
|
+
}, [arrow, filtered, total]);
|
|
65
|
+
const loadingState = !loading && arrow !== undefined && metadataMappingFiles !== undefined;
|
|
68
66
|
// If there is only one mapping file, we want to color by filename by default.
|
|
69
67
|
useEffect(() => {
|
|
70
68
|
if (mappingsListCount === 1 && colorBy !== 'filename') {
|
|
@@ -100,29 +98,23 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
100
98
|
return (_jsx(ErrorContent, { errorMessage: _jsxs(_Fragment, { children: [_jsx("span", { children: "The Icicle chart is not available for this query." }), iciclechartHelpText ?? null] }) }));
|
|
101
99
|
}
|
|
102
100
|
}
|
|
103
|
-
if (
|
|
101
|
+
if (arrow === undefined)
|
|
104
102
|
return _jsx("div", { className: "mx-auto text-center", children: "No data..." });
|
|
105
103
|
if (total === 0n && !loading)
|
|
106
104
|
return _jsx("div", { className: "mx-auto text-center", children: "Profile has no samples" });
|
|
107
|
-
if (graph !== undefined)
|
|
108
|
-
return (_jsx(IcicleGraph, { width: width, graph: graph, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, profileType: profileType }));
|
|
109
105
|
if (arrow !== undefined) {
|
|
110
|
-
return (_jsxs("div", { className: "relative", children: [isIcicleChart ? (_jsx(TimelineGuide, { bounds: boundsFromProfileSource(profileSource), width: width, height: icicleChartHeight ?? 420, margin: 0, ticks: 12, timeUnit: "nanoseconds" })) : null, _jsx("div", { ref: icicleChartRef, children: _jsx(IcicleGraphArrow, { width: width, arrow: arrow, total: total, filtered: filtered, curPath: curPathArrow, setCurPath: setNewCurPathArrow, profileType: profileType,
|
|
106
|
+
return (_jsxs("div", { className: "relative", children: [isIcicleChart ? (_jsx(TimelineGuide, { bounds: boundsFromProfileSource(profileSource), width: width, height: icicleChartHeight ?? 420, margin: 0, ticks: 12, timeUnit: "nanoseconds" })) : null, _jsx("div", { ref: icicleChartRef, children: _jsx(IcicleGraphArrow, { width: width, arrow: arrow, total: total, filtered: filtered, curPath: curPathArrow, setCurPath: setNewCurPathArrow, profileType: profileType, isHalfScreen: isHalfScreen, mappingsListFromMetadata: mappingsList, compareAbsolute: isCompareAbsolute, isIcicleChart: isIcicleChart, profileSource: profileSource }) })] }));
|
|
111
107
|
}
|
|
112
108
|
}, [
|
|
113
109
|
isLoading,
|
|
114
|
-
graph,
|
|
115
110
|
arrow,
|
|
116
111
|
total,
|
|
117
112
|
loading,
|
|
118
113
|
width,
|
|
119
114
|
filtered,
|
|
120
|
-
curPath,
|
|
121
|
-
setNewCurPath,
|
|
122
115
|
curPathArrow,
|
|
123
116
|
setNewCurPathArrow,
|
|
124
117
|
profileType,
|
|
125
|
-
storeSortBy,
|
|
126
118
|
isHalfScreen,
|
|
127
119
|
isDarkMode,
|
|
128
120
|
mappingsList,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ProfilerOnRenderCallback } from 'react';
|
|
2
2
|
import { CurrentPathFrame } from '../../../ProfileIcicleGraph/IcicleGraphArrow/utils';
|
|
3
3
|
import { ProfileSource } from '../../../ProfileSource';
|
|
4
|
-
import type {
|
|
4
|
+
import type { FlamegraphData, SourceData, TopTableData, VisualizationType } from '../../types/visualization';
|
|
5
5
|
interface GetDashboardItemProps {
|
|
6
6
|
type: VisualizationType;
|
|
7
7
|
isHalfScreen: boolean;
|
|
@@ -9,9 +9,8 @@ interface GetDashboardItemProps {
|
|
|
9
9
|
flamegraphData: FlamegraphData;
|
|
10
10
|
flamechartData: FlamegraphData;
|
|
11
11
|
topTableData?: TopTableData;
|
|
12
|
-
callgraphData?: CallgraphData;
|
|
13
12
|
sourceData?: SourceData;
|
|
14
|
-
profileSource
|
|
13
|
+
profileSource: ProfileSource;
|
|
15
14
|
total: bigint;
|
|
16
15
|
filtered: bigint;
|
|
17
16
|
curPath: string[];
|
|
@@ -20,11 +19,10 @@ interface GetDashboardItemProps {
|
|
|
20
19
|
setNewCurPathArrow: (path: CurrentPathFrame[]) => void;
|
|
21
20
|
currentSearchString?: string;
|
|
22
21
|
setSearchString?: (value: string) => void;
|
|
23
|
-
callgraphSVG?: string;
|
|
24
22
|
perf?: {
|
|
25
23
|
onRender?: ProfilerOnRenderCallback;
|
|
26
24
|
};
|
|
27
25
|
}
|
|
28
|
-
export declare const getDashboardItem: ({ type, isHalfScreen, dimensions, flamegraphData, flamechartData, topTableData,
|
|
26
|
+
export declare const getDashboardItem: ({ type, isHalfScreen, dimensions, flamegraphData, flamechartData, topTableData, sourceData, profileSource, total, filtered, curPathArrow, setNewCurPathArrow, currentSearchString, setSearchString, perf, }: GetDashboardItemProps) => JSX.Element;
|
|
29
27
|
export {};
|
|
30
28
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -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;
|
|
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;AAKzD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,OAAO,KAAK,EACV,cAAc,EACd,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,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,EAAE,aAAa,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,gBAAgB,EAAE,CAAC;IACjC,kBAAkB,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IACvD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;CACH;AAED,eAAO,MAAM,gBAAgB,gNAgB1B,qBAAqB,KAAG,GAAG,CAAC,OA2F9B,CAAC"}
|