@parca/profile 0.19.12 → 0.19.13
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 +4 -0
- package/dist/GraphTooltipArrow/Content.js +1 -1
- package/dist/GraphTooltipArrow/index.js +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.js +12 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.d.ts +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.js +9 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts +1 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.js +7 -3
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.js +17 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +2 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +23 -8
- package/dist/ProfileIcicleGraph/index.d.ts +3 -1
- package/dist/ProfileIcicleGraph/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/index.js +6 -4
- package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
- package/dist/ProfileView/components/DashboardItems/index.js +1 -1
- package/dist/ProfileView/components/ShareButton/index.d.ts.map +1 -1
- package/dist/ProfileView/components/ShareButton/index.js +1 -1
- package/dist/ProfileView/components/Toolbars/index.d.ts +0 -2
- package/dist/ProfileView/components/Toolbars/index.d.ts.map +1 -1
- package/dist/ProfileView/components/Toolbars/index.js +4 -5
- package/dist/ProfileView/components/ViewSelector/index.d.ts.map +1 -1
- package/dist/ProfileView/components/ViewSelector/index.js +18 -11
- package/dist/ProfileView/context/DashboardContext.d.ts.map +1 -1
- package/dist/ProfileView/context/DashboardContext.js +5 -0
- package/dist/ProfileView/index.d.ts.map +1 -1
- package/dist/ProfileView/index.js +4 -3
- package/dist/Sandwich/components/CalleesSection.d.ts +1 -2
- package/dist/Sandwich/components/CalleesSection.d.ts.map +1 -1
- package/dist/Sandwich/components/CalleesSection.js +2 -6
- package/dist/Sandwich/components/CallersSection.d.ts +4 -2
- package/dist/Sandwich/components/CallersSection.d.ts.map +1 -1
- package/dist/Sandwich/components/CallersSection.js +45 -9
- package/dist/Sandwich/components/TableSection.js +1 -1
- package/dist/Sandwich/index.d.ts +0 -1
- package/dist/Sandwich/index.d.ts.map +1 -1
- package/dist/Sandwich/index.js +27 -79
- package/dist/Table/MoreDropdown.d.ts.map +1 -1
- package/dist/Table/MoreDropdown.js +1 -2
- package/dist/Table/TableContextMenu.d.ts +9 -0
- package/dist/Table/TableContextMenu.d.ts.map +1 -0
- package/dist/Table/TableContextMenu.js +38 -0
- package/dist/Table/TableContextMenuWrapper.d.ts +10 -0
- package/dist/Table/TableContextMenuWrapper.d.ts.map +1 -0
- package/dist/Table/TableContextMenuWrapper.js +30 -0
- package/dist/Table/hooks/useTableConfiguration.d.ts.map +1 -1
- package/dist/Table/hooks/useTableConfiguration.js +2 -20
- package/dist/Table/index.d.ts.map +1 -1
- package/dist/Table/index.js +65 -5
- package/dist/styles.css +1 -1
- package/package.json +3 -3
- package/src/GraphTooltipArrow/Content.tsx +3 -3
- package/src/GraphTooltipArrow/index.tsx +2 -2
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx +19 -3
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.tsx +10 -2
- package/src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx +19 -2
- package/src/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.tsx +20 -2
- package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +40 -6
- package/src/ProfileIcicleGraph/index.tsx +20 -2
- package/src/ProfileView/components/DashboardItems/index.tsx +0 -1
- package/src/ProfileView/components/ShareButton/index.tsx +9 -3
- package/src/ProfileView/components/Toolbars/index.tsx +7 -23
- package/src/ProfileView/components/ViewSelector/index.tsx +20 -11
- package/src/ProfileView/context/DashboardContext.tsx +6 -0
- package/src/ProfileView/index.tsx +12 -4
- package/src/Sandwich/components/CalleesSection.tsx +1 -7
- package/src/Sandwich/components/CallersSection.tsx +92 -35
- package/src/Sandwich/components/TableSection.tsx +2 -2
- package/src/Sandwich/index.tsx +20 -107
- package/src/Table/MoreDropdown.tsx +1 -2
- package/src/Table/TableContextMenu.tsx +70 -0
- package/src/Table/TableContextMenuWrapper.tsx +48 -0
- package/src/Table/hooks/useTableConfiguration.tsx +2 -25
- package/src/Table/index.tsx +84 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [0.19.13](https://github.com/parca-dev/parca/compare/@parca/profile@0.19.12...@parca/profile@0.19.13) (2025-07-03)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
6
10
|
## 0.19.12 (2025-07-02)
|
|
7
11
|
|
|
8
12
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -27,7 +27,7 @@ const GraphTooltipArrowContent = ({ table, profileType, unit, total, totalUnfilt
|
|
|
27
27
|
? name
|
|
28
28
|
: locationAddress !== 0n
|
|
29
29
|
? hexifyAddress(locationAddress)
|
|
30
|
-
: 'unknown' })) }), _jsx("table", { className: "my-2 w-full table-fixed pr-0 text-gray-700 dark:text-gray-300", children: _jsxs("tbody", { children: [_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Cumulative" }), _jsx("td", { className: "w-3/4", children: _jsx("
|
|
30
|
+
: 'unknown' })) }), _jsx("table", { className: "my-2 w-full table-fixed pr-0 text-gray-700 dark:text-gray-300", children: _jsxs("tbody", { children: [_jsxs("tr", { children: [_jsx("td", { className: "w-1/4", children: "Cumulative" }), _jsx("td", { className: "w-3/4", children: _jsx("p", { children: cumulativeText }) })] }), _jsxs("tr", { children: [_jsx("td", { className: "w-1/4 pt-2", children: "Flat" }), _jsx("td", { className: "w-3/4 pt-2", children: _jsx("p", { children: flatText }) })] }), diff !== 0n && (_jsxs("tr", { children: [_jsx("td", { className: "w-1/4 pt-2", children: "Diff" }), _jsx("td", { className: "w-3/4 pt-2", children: _jsx("p", { children: diffText }) })] })), _jsx(TooltipMetaInfo, { table: table, row: rowNumber })] }) })] }) }), _jsxs("div", { className: "flex w-full items-center gap-1 text-xs text-gray-500", children: [_jsx(Icon, { icon: "iconoir:mouse-button-right" }), _jsx("div", { children: "Right click to show context menu" })] })] }) }) }));
|
|
31
31
|
};
|
|
32
32
|
const TooltipMetaInfo = ({ table, row }) => {
|
|
33
33
|
const { labelPairs, functionFilename, file, locationAddress, mappingFile, mappingBuildID, inlined, timestamp, } = useGraphTooltipMetaInfo({ table, row });
|
|
@@ -34,7 +34,7 @@ const GraphTooltip = ({ children, contextElement }) => {
|
|
|
34
34
|
const [isPositioned, setIsPositioned] = useState(false);
|
|
35
35
|
const { refs, floatingStyles, update } = useFloating({
|
|
36
36
|
placement: 'bottom-start',
|
|
37
|
-
strategy: '
|
|
37
|
+
strategy: 'fixed',
|
|
38
38
|
middleware: [
|
|
39
39
|
offset({
|
|
40
40
|
mainAxis: 30,
|
|
@@ -42,7 +42,7 @@ const GraphTooltip = ({ children, contextElement }) => {
|
|
|
42
42
|
}),
|
|
43
43
|
flip(),
|
|
44
44
|
shift({
|
|
45
|
-
padding:
|
|
45
|
+
padding: 20,
|
|
46
46
|
}),
|
|
47
47
|
],
|
|
48
48
|
whileElementsMounted: undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"ContextMenu.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx"],"names":[],"mappings":"AAcA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAOnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAO1C,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,QAAA,MAAM,WAAW,qIAad,gBAAgB,KAAG,GAAG,CAAC,OAmOzB,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -12,6 +12,7 @@ import { Fragment as _Fragment, jsx as _jsx, 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 { Icon } from '@iconify/react';
|
|
15
|
+
import cx from 'classnames';
|
|
15
16
|
import { Item, Menu, Separator, Submenu } from 'react-contexify';
|
|
16
17
|
import { Tooltip } from 'react-tooltip';
|
|
17
18
|
import { useParcaContext, useURLState } from '@parca/components';
|
|
@@ -83,7 +84,9 @@ const ContextMenu = ({ menuId, table, total, totalUnfiltered, row, compareAbsolu
|
|
|
83
84
|
{ id: 'Build Id', value: buildIdText },
|
|
84
85
|
];
|
|
85
86
|
const nonEmptyValuesToCopy = valuesToCopy.filter(({ value }) => value !== '');
|
|
86
|
-
return (_jsxs(Menu, { id: menuId, theme: isDarkMode ? 'dark' : '', className:
|
|
87
|
+
return (_jsxs(Menu, { id: menuId, theme: isDarkMode ? 'dark' : '', className: cx(dashboardItems.includes('sandwich')
|
|
88
|
+
? 'min-w-[350px] w-[350px]'
|
|
89
|
+
: 'min-w-[260px] w-fit-content'), children: [_jsxs(Item, { id: "view-source-file", onClick: handleViewSourceFile, disabled: enableSourcesView === false || !isSourceAvailable, children: [_jsx("div", { "data-tooltip-id": "view-source-file-help", "data-tooltip-content": "There is no source code uploaded for this build", children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "wpf:view-file" }), _jsx("div", { children: "View source file" })] }) }), !isSourceAvailable ? _jsx(Tooltip, { id: "view-source-file-help" }) : null] }), _jsx(Item, { id: "show-in-table", onClick: () => {
|
|
87
90
|
setSearchString(functionName);
|
|
88
91
|
if (isSandwich) {
|
|
89
92
|
setDashboardItems(['table']);
|
|
@@ -92,8 +95,14 @@ const ContextMenu = ({ menuId, table, total, totalUnfiltered, row, compareAbsolu
|
|
|
92
95
|
setDashboardItems([...dashboardItems, 'table']);
|
|
93
96
|
}
|
|
94
97
|
}, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "ph:table" }), _jsx("div", { children: "Show in table" })] }) }), enableSandwichView === true && (_jsx(Item, { id: "show-in-sandwich", onClick: () => {
|
|
98
|
+
if (dashboardItems.includes('sandwich')) {
|
|
99
|
+
setSandwichFunctionName(functionName);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
95
102
|
setSandwichFunctionName(functionName);
|
|
96
|
-
setDashboardItems(['sandwich']);
|
|
97
|
-
}, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "tdesign:sandwich-filled" }), _jsxs("div", { className: "relative", children: [
|
|
103
|
+
setDashboardItems([...dashboardItems, 'sandwich']);
|
|
104
|
+
}, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "tdesign:sandwich-filled" }), _jsxs("div", { className: "relative", children: [dashboardItems.includes('sandwich')
|
|
105
|
+
? 'Focus sandwich on this frame.'
|
|
106
|
+
: 'Show in sandwich', _jsx("span", { className: "absolute top-[-2px] text-xs lowercase text-red-500", children: "\u00A0alpha" })] })] }) })), _jsx(Item, { id: "reset-view", onClick: handleResetView, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "system-uicons:reset" }), _jsx("div", { children: "Reset graph" })] }) }), _jsxs(Item, { id: "hide-binary", onClick: () => hideBinary(getLastItem(mappingFile)), disabled: mappingFile === null || mappingFile === '', children: [_jsx("div", { "data-tooltip-id": "hide-binary-help", "data-tooltip-content": "Hide all frames for this binary", children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "bx:bxs-hide" }), _jsxs("div", { children: ["Hide binary ", mappingFile !== null && `(${getLastItem(mappingFile)})`] })] }) }), _jsx(Tooltip, { place: "left", id: "hide-binary-help" })] }), _jsx(Submenu, { label: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "ph:copy" }), _jsx("div", { children: "Copy" })] }), children: _jsx("div", { className: "max-h-[300px] overflow-scroll", children: nonEmptyValuesToCopy.map(({ id, value }) => (_jsx(Item, { id: id, onClick: () => handleCopyItem(value), className: "dark:bg-gray-800", children: _jsxs("div", { className: "flex flex-col dark:text-gray-300 hover:dark:text-gray-100", children: [_jsx("div", { className: "text-sm", children: id }), _jsx("div", { className: "text-xs", children: truncateString(value, 30) })] }) }, id))) }) }), checkDebuginfoStatusHandler !== undefined ? (_jsx(Item, { id: "check-debuginfo-status", onClick: () => checkDebuginfoStatusHandler(mappingBuildID), disabled: !isMappingBuildIDAvailable, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "bx:bx-info-circle" }), _jsx("div", { className: "relative pr-4", children: "Check debuginfo status" })] }) })) : null, _jsx(Separator, {}), _jsx(Item, { id: "dock-tooltip", onClick: handleDockTooltip, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "bx:dock-bottom" }), isGraphTooltipDocked ? 'Undock tooltip' : 'Dock tooltip'] }) })] }));
|
|
98
107
|
};
|
|
99
108
|
export default ContextMenu;
|
|
@@ -14,7 +14,7 @@ interface ContextMenuWrapperProps {
|
|
|
14
14
|
isSandwich?: boolean;
|
|
15
15
|
}
|
|
16
16
|
export interface ContextMenuWrapperRef {
|
|
17
|
-
setRow: (row: number) => void;
|
|
17
|
+
setRow: (row: number, callback?: () => void) => void;
|
|
18
18
|
}
|
|
19
19
|
declare const ContextMenuWrapper: import("react").ForwardRefExoticComponent<ContextMenuWrapperProps & import("react").RefAttributes<ContextMenuWrapperRef>>;
|
|
20
20
|
export default ContextMenuWrapper;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContextMenuWrapper.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAI1C,UAAU,uBAAuB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"ContextMenuWrapper.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenuWrapper.tsx"],"names":[],"mappings":"AAeA,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAI1C,UAAU,uBAAuB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,eAAe,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;CACtD;AAED,QAAA,MAAM,kBAAkB,2HAkBvB,CAAC;AAIF,eAAe,kBAAkB,CAAC"}
|
|
@@ -14,9 +14,17 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
14
14
|
import { forwardRef, useImperativeHandle, useState } from 'react';
|
|
15
15
|
import ContextMenu from './ContextMenu';
|
|
16
16
|
const ContextMenuWrapper = forwardRef((props, ref) => {
|
|
17
|
+
// Fix for race condition: Always render ContextMenu to maintain component tree stability
|
|
18
|
+
// but use callback timing to ensure correct data is available when menu shows
|
|
17
19
|
const [row, setRow] = useState(0);
|
|
18
20
|
useImperativeHandle(ref, () => ({
|
|
19
|
-
setRow,
|
|
21
|
+
setRow: (newRow, callback) => {
|
|
22
|
+
setRow(newRow);
|
|
23
|
+
// Execute callback after state update using requestAnimationFrame
|
|
24
|
+
if (callback != null) {
|
|
25
|
+
requestAnimationFrame(callback);
|
|
26
|
+
}
|
|
27
|
+
},
|
|
20
28
|
}));
|
|
21
29
|
return _jsx(ContextMenu, { ...props, row: row });
|
|
22
30
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IcicleGraphNodes.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAErC,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAMnC,OAAO,yCAAyC,CAAC;AAIjD,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAgBlD,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;CACnD;AAED,eAAO,MAAM,gBAAgB;;;CAG5B,CAAC;AACF,eAAO,MAAM,qBAAqB;;;;CAIjC,CAAC;AAEF,eAAO,MAAM,UAAU,
|
|
1
|
+
{"version":3,"file":"IcicleGraphNodes.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/IcicleGraphNodes.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAErC,OAAO,EAAC,KAAK,EAAC,MAAM,cAAc,CAAC;AAMnC,OAAO,yCAAyC,CAAC;AAIjD,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAgBlD,eAAO,MAAM,SAAS,KAAK,CAAC;AAE5B,MAAM,WAAW,aAAa;IAC5B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,aAAa,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,aAAa,EAAE,aAAa,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IAGnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;CACnD;AAED,eAAO,MAAM,gBAAgB;;;CAG5B,CAAC;AACF,eAAO,MAAM,qBAAqB;;;;CAIjC,CAAC;AAEF,eAAO,MAAM,UAAU,6CA2NrB,CAAC"}
|
|
@@ -30,7 +30,7 @@ export const fadedIcicleRectStyles = {
|
|
|
30
30
|
transition: 'opacity .15s linear',
|
|
31
31
|
opacity: '0.5',
|
|
32
32
|
};
|
|
33
|
-
export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, colors, colorBy, height, totalWidth, searchString, darkMode, compareMode, colorForSimilarNodes, selectedRow, onClick, onContextMenu, hoveringRow, setHoveringRow, isIcicleChart, profileSource, isFlamegraph = false, isSandwich = false, maxDepth = 0, tooltipId = 'default', }) {
|
|
33
|
+
export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, colors, colorBy, height, totalWidth, searchString, darkMode, compareMode, colorForSimilarNodes, selectedRow, onClick, onContextMenu, hoveringRow, setHoveringRow, isIcicleChart, profileSource, isFlamegraph = false, isSandwich = false, maxDepth = 0, effectiveDepth, tooltipId = 'default', }) {
|
|
34
34
|
// get the columns to read from
|
|
35
35
|
const mappingColumn = table.getChild(FIELD_MAPPING_FILE);
|
|
36
36
|
const functionNameColumn = table.getChild(FIELD_FUNCTION_NAME);
|
|
@@ -41,6 +41,7 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, col
|
|
|
41
41
|
const valueOffsetColumn = table.getChild(FIELD_VALUE_OFFSET);
|
|
42
42
|
const tsColumn = table.getChild(FIELD_TIMESTAMP);
|
|
43
43
|
// get the actual values from the columns
|
|
44
|
+
const binaries = useAppSelector(selectBinaries);
|
|
44
45
|
const mappingFile = arrowToString(mappingColumn?.get(row));
|
|
45
46
|
const functionName = arrowToString(functionNameColumn?.get(row));
|
|
46
47
|
const cumulative = cumulativeColumn?.get(row) !== null ? BigInt(cumulativeColumn?.get(row)) : 0n;
|
|
@@ -54,7 +55,6 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, col
|
|
|
54
55
|
const colorsMap = colors;
|
|
55
56
|
const hoveringName = hoveringRow !== undefined ? arrowToString(functionNameColumn?.get(hoveringRow)) : '';
|
|
56
57
|
const shouldBeHighlighted = functionName != null && hoveringName != null && functionName === hoveringName;
|
|
57
|
-
const binaries = useAppSelector(selectBinaries);
|
|
58
58
|
const colorResult = useNodeColor({
|
|
59
59
|
isDarkMode: darkMode,
|
|
60
60
|
compareMode,
|
|
@@ -72,6 +72,10 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, col
|
|
|
72
72
|
}
|
|
73
73
|
return { isHighlightEnabled: true, isHighlighted: isSearchMatch(searchString, name) };
|
|
74
74
|
}, [searchString, name]);
|
|
75
|
+
// Hide frames beyond effective depth limit
|
|
76
|
+
if (effectiveDepth !== undefined && depth > effectiveDepth) {
|
|
77
|
+
return _jsx(_Fragment, {});
|
|
78
|
+
}
|
|
75
79
|
const selectionOffset = valueOffsetColumn?.get(selectedRow) !== null &&
|
|
76
80
|
valueOffsetColumn?.get(selectedRow) !== undefined
|
|
77
81
|
? BigInt(valueOffsetColumn?.get(selectedRow))
|
|
@@ -128,7 +132,7 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, col
|
|
|
128
132
|
}
|
|
129
133
|
return depth * height;
|
|
130
134
|
};
|
|
131
|
-
const y = calculateY(isFlamegraph, isSandwich, isIcicleChart, maxDepth, depth, height);
|
|
135
|
+
const y = calculateY(isFlamegraph, isSandwich, isIcicleChart, effectiveDepth ?? maxDepth, depth, height);
|
|
132
136
|
return (_jsx(_Fragment, { children: _jsxs("g", { id: row === 0 ? 'root-span' : undefined, transform: `translate(${x + 1}, ${y + 1})`, style: styles, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onClick, onContextMenu: handleContextMenu, children: [_jsx("rect", { x: 0, y: 0, width: width, height: height, style: {
|
|
133
137
|
fill: colorResult,
|
|
134
138
|
}, className: cx(shouldBeHighlighted
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoizedTooltip.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAOvD,UAAU,oBAAoB;IAC5B,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,eAAe,
|
|
1
|
+
{"version":3,"file":"MemoizedTooltip.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/MemoizedTooltip.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAkC,MAAM,OAAO,CAAC;AAOvD,UAAU,oBAAoB;IAC5B,cAAc,EAAE,OAAO,GAAG,IAAI,CAAC;IAC/B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,eAAO,MAAM,eAAe,kDAwE1B,CAAC"}
|
|
@@ -26,16 +26,31 @@ export const MemoizedTooltip = memo(function MemoizedTooltip({ contextElement, d
|
|
|
26
26
|
setTooltipRow(event.detail.row);
|
|
27
27
|
};
|
|
28
28
|
const eventName = `icicle-tooltip-update-${tooltipId}`;
|
|
29
|
-
|
|
29
|
+
// Delay to ensure all DOM updates and React renders are complete
|
|
30
|
+
// This fixes the race condition in sandwich view
|
|
31
|
+
const timeoutId = setTimeout(() => {
|
|
32
|
+
window.addEventListener(eventName, handleTooltipUpdate);
|
|
33
|
+
}, 200);
|
|
30
34
|
return () => {
|
|
35
|
+
clearTimeout(timeoutId);
|
|
31
36
|
window.removeEventListener(eventName, handleTooltipUpdate);
|
|
32
37
|
};
|
|
33
|
-
}, [tooltipId]);
|
|
38
|
+
}, [tooltipId, table]);
|
|
39
|
+
// Re-render when contextElement becomes available (fixes sandwich view timing issue)
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
// Force re-render when contextElement transitions from null to valid element
|
|
42
|
+
// This ensures tooltips work immediately in sandwich view
|
|
43
|
+
}, [contextElement, tooltipId]);
|
|
34
44
|
if (dockedMetainfo) {
|
|
35
45
|
return (_jsx(DockedGraphTooltip, { table: table, row: tooltipRow, total: total, totalUnfiltered: totalUnfiltered, profileType: profileType, unit: unit, compareAbsolute: compareAbsolute }));
|
|
36
46
|
}
|
|
37
47
|
if (tooltipRow === null) {
|
|
38
48
|
return null;
|
|
39
49
|
}
|
|
50
|
+
// Fix for sandwich view tooltip issue: Don't render tooltip if contextElement is null
|
|
51
|
+
// This happens when the SVG ref isn't ready yet during initial sandwich view render
|
|
52
|
+
if (contextElement === null) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
40
55
|
return (_jsx(GraphTooltipArrow, { contextElement: contextElement, children: _jsx(GraphTooltipArrowContent, { table: table, row: tooltipRow, isFixed: false, total: total, totalUnfiltered: totalUnfiltered, profileType: profileType, unit: unit, compareAbsolute: compareAbsolute }) }));
|
|
41
56
|
});
|
|
@@ -42,6 +42,8 @@ interface IcicleGraphArrowProps {
|
|
|
42
42
|
isFlamegraph?: boolean;
|
|
43
43
|
isSandwich?: boolean;
|
|
44
44
|
tooltipId?: string;
|
|
45
|
+
maxFrameCount?: number;
|
|
46
|
+
isExpanded?: boolean;
|
|
45
47
|
}
|
|
46
48
|
export declare const getMappingColors: (mappingsList: string[], isDarkMode: boolean, currentColorProfile: ColorConfig) => colorByColors;
|
|
47
49
|
export declare const getFilenameColors: (filenamesList: string[], isDarkMode: boolean, currentColorProfile: ColorConfig) => colorByColors;
|
|
@@ -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,KAQN,MAAM,OAAO,CAAC;AAKf,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAc,KAAK,WAAW,EAAC,MAAM,kBAAkB,CAAC;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;IACxB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;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;AAeF,eAAO,MAAM,gBAAgB,mDA+P3B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
|
|
@@ -11,7 +11,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
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, useMemo, useRef, useState } from 'react';
|
|
14
|
+
import { memo, useCallback, useDeferredValue, useEffect, useMemo, useRef, useState, } from 'react';
|
|
15
15
|
import { tableFromIPC } from 'apache-arrow';
|
|
16
16
|
import { useContextMenu } from 'react-contexify';
|
|
17
17
|
import { useURLState } from '@parca/components';
|
|
@@ -74,7 +74,7 @@ function getMaxDepth(depthColumn) {
|
|
|
74
74
|
}
|
|
75
75
|
return max;
|
|
76
76
|
}
|
|
77
|
-
export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, profileType, profileSource, mappingsListFromMetadata, compareAbsolute, isIcicleChart = false, isFlamegraph = false, isSandwich = false, tooltipId = 'default', }) {
|
|
77
|
+
export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, profileType, profileSource, mappingsListFromMetadata, compareAbsolute, isIcicleChart = false, isFlamegraph = false, isSandwich = false, tooltipId = 'default', maxFrameCount, isExpanded = false, }) {
|
|
78
78
|
const [highlightSimilarStacksPreference] = useUserPreference(USER_PREFERENCES.HIGHLIGHT_SIMILAR_STACKS.key);
|
|
79
79
|
const [hoveringRow, setHoveringRow] = useState(undefined);
|
|
80
80
|
const [dockedMetainfo] = useUserPreference(USER_PREFERENCES.GRAPH_METAINFO_DOCKED.key);
|
|
@@ -83,6 +83,10 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
83
83
|
return tableFromIPC(arrow.record);
|
|
84
84
|
}, [arrow]);
|
|
85
85
|
const svg = useRef(null);
|
|
86
|
+
const [svgElement, setSvgElement] = useState(null);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
setSvgElement(svg.current);
|
|
89
|
+
}, [tooltipId]);
|
|
86
90
|
const [binaryFrameFilter, setBinaryFrameFilter] = useURLState('binary_frame_filter');
|
|
87
91
|
const [currentSearchString] = useURLState('search_string');
|
|
88
92
|
const { compareMode } = useProfileViewContext();
|
|
@@ -135,9 +139,14 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
135
139
|
id: MENU_ID,
|
|
136
140
|
});
|
|
137
141
|
const displayMenu = useCallback((e, row) => {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
// Race condition fix: Use callback to ensure context menu shows only after
|
|
144
|
+
// row state has been updated and propagated through the hook chain.
|
|
145
|
+
// This prevents empty function names on first click.
|
|
146
|
+
contextMenuRef.current?.setRow(row, () => {
|
|
147
|
+
show({
|
|
148
|
+
event: e,
|
|
149
|
+
});
|
|
141
150
|
});
|
|
142
151
|
}, [show]);
|
|
143
152
|
const hideBinary = (binaryToRemove) => {
|
|
@@ -167,7 +176,13 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
167
176
|
};
|
|
168
177
|
const depthColumn = table.getChild(FIELD_DEPTH);
|
|
169
178
|
const maxDepth = getMaxDepth(depthColumn);
|
|
170
|
-
|
|
179
|
+
// Apply frame limit if maxFrameCount is provided and not expanded
|
|
180
|
+
const effectiveDepth = maxFrameCount !== undefined && !isExpanded ? Math.min(maxDepth, maxFrameCount) : maxDepth;
|
|
181
|
+
// Use deferred value to prevent UI blocking when expanding frames
|
|
182
|
+
const deferredEffectiveDepth = useDeferredValue(effectiveDepth);
|
|
183
|
+
const height = isSandwich
|
|
184
|
+
? deferredEffectiveDepth * RowHeight
|
|
185
|
+
: (deferredEffectiveDepth + 1) * RowHeight;
|
|
171
186
|
// To find the selected row, we must walk the current path and look at which
|
|
172
187
|
// children of the current frame matches the path element exactly. Until the
|
|
173
188
|
// end, the row we find at the end is our selected row.
|
|
@@ -192,12 +207,12 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
192
207
|
currentRow = childRows[0];
|
|
193
208
|
}
|
|
194
209
|
const selectedRow = currentRow;
|
|
195
|
-
return (_jsx(TooltipProvider, { table: table, total: total, totalUnfiltered: total + filtered, profileType: profileType, unit: arrow.unit, compareAbsolute: compareAbsolute, tooltipId: tooltipId, 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, isSandwich: isSandwich }), _jsx(MemoizedTooltip, { contextElement:
|
|
210
|
+
return (_jsx(TooltipProvider, { table: table, total: total, totalUnfiltered: total + filtered, profileType: profileType, unit: arrow.unit, compareAbsolute: compareAbsolute, tooltipId: tooltipId, 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, isSandwich: isSandwich }), _jsx(MemoizedTooltip, { contextElement: svgElement, 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: () => {
|
|
196
211
|
if (isIcicleChart) {
|
|
197
212
|
// We don't want to expand in icicle charts.
|
|
198
213
|
return;
|
|
199
214
|
}
|
|
200
215
|
handleRowClick(row);
|
|
201
|
-
}, onContextMenu: displayMenu, hoveringRow: highlightSimilarStacksPreference ? hoveringRow : undefined, setHoveringRow: highlightSimilarStacksPreference ? setHoveringRow : noop, isIcicleChart: isIcicleChart, profileSource: profileSource, isFlamegraph: isFlamegraph, isSandwich: isSandwich, maxDepth: maxDepth, tooltipId: tooltipId }, row))) })] }) }));
|
|
216
|
+
}, onContextMenu: displayMenu, hoveringRow: highlightSimilarStacksPreference ? hoveringRow : undefined, setHoveringRow: highlightSimilarStacksPreference ? setHoveringRow : noop, isIcicleChart: isIcicleChart, profileSource: profileSource, isFlamegraph: isFlamegraph, isSandwich: isSandwich, maxDepth: maxDepth, effectiveDepth: deferredEffectiveDepth, tooltipId: tooltipId }, row))) })] }) }));
|
|
202
217
|
});
|
|
203
218
|
export default IcicleGraphArrow;
|
|
@@ -23,12 +23,14 @@ interface ProfileIcicleGraphProps {
|
|
|
23
23
|
isSandwichIcicleGraph?: boolean;
|
|
24
24
|
isFlamegraph?: boolean;
|
|
25
25
|
tooltipId?: string;
|
|
26
|
+
maxFrameCount?: number;
|
|
27
|
+
isExpanded?: boolean;
|
|
26
28
|
}
|
|
27
29
|
export declare const validateIcicleChartQuery: (profileSource: MergedProfileSource) => {
|
|
28
30
|
isValid: boolean;
|
|
29
31
|
isNonDelta: boolean;
|
|
30
32
|
isDurationTooLong: boolean;
|
|
31
33
|
};
|
|
32
|
-
declare const ProfileIcicleGraph: ({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isIcicleChart, profileSource, isSandwichIcicleGraph, isFlamegraph, tooltipId, }: ProfileIcicleGraphProps) => JSX.Element;
|
|
34
|
+
declare const ProfileIcicleGraph: ({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isIcicleChart, profileSource, isSandwichIcicleGraph, isFlamegraph, tooltipId, maxFrameCount, isExpanded, }: ProfileIcicleGraphProps) => JSX.Element;
|
|
33
35
|
export default ProfileIcicleGraph;
|
|
34
36
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAM7F,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAwE,MAAM,OAAO,CAAC;AAM7F,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAO9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;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;IACxB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;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,mPAmBrB,uBAAuB,KAAG,GAAG,CAAC,OA8ShC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -15,7 +15,7 @@ import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
|
15
15
|
import cx from 'classnames';
|
|
16
16
|
import { AnimatePresence, motion } from 'framer-motion';
|
|
17
17
|
import { useMeasure } from 'react-use';
|
|
18
|
-
import { IcicleGraphSkeleton, useParcaContext, useURLState } from '@parca/components';
|
|
18
|
+
import { FlamegraphSkeleton, IcicleGraphSkeleton, useParcaContext, useURLState, } from '@parca/components';
|
|
19
19
|
import { capitalizeOnlyFirstLetter, divide } from '@parca/utilities';
|
|
20
20
|
import DiffLegend from '../ProfileView/components/DiffLegend';
|
|
21
21
|
import { useProfileViewContext } from '../ProfileView/context/ProfileViewContext';
|
|
@@ -32,7 +32,7 @@ export const validateIcicleChartQuery = (profileSource) => {
|
|
|
32
32
|
const isDurationTooLong = profileSource.mergeTo - profileSource.mergeFrom > 60000;
|
|
33
33
|
return { isValid: !isNonDelta && !isDurationTooLong, isNonDelta, isDurationTooLong };
|
|
34
34
|
};
|
|
35
|
-
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isIcicleChart = false, profileSource, isSandwichIcicleGraph = false, isFlamegraph = false, tooltipId, }) {
|
|
35
|
+
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ arrow, total, filtered, curPathArrow, setNewCurPathArrow, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, isIcicleChart = false, profileSource, isSandwichIcicleGraph = false, isFlamegraph = false, tooltipId, maxFrameCount, isExpanded = false, }) {
|
|
36
36
|
const { onError, authenticationErrorMessage, isDarkMode, iciclechartHelpText } = useParcaContext();
|
|
37
37
|
const { compareMode } = useProfileViewContext();
|
|
38
38
|
const [isLoading, setIsLoading] = useState(true);
|
|
@@ -97,7 +97,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ arrow, total, fi
|
|
|
97
97
|
: { isValid: true, isNonDelta: false, isDurationTooLong: false };
|
|
98
98
|
const isInvalidIcicleChartQuery = isIcicleChart && !isIcicleChartValid;
|
|
99
99
|
if (isLoading && !isInvalidIcicleChartQuery) {
|
|
100
|
-
return (_jsx("div", { className: "h-auto overflow-clip", children: _jsx(IcicleGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode }) }));
|
|
100
|
+
return (_jsx("div", { className: "h-auto overflow-clip", children: isFlamegraph ? (_jsx(FlamegraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) : (_jsx(IcicleGraphSkeleton, { isHalfScreen: isHalfScreen, isDarkMode: isDarkMode })) }));
|
|
101
101
|
}
|
|
102
102
|
// Do necessary checks to ensure that icicle chart can be rendered for this query.
|
|
103
103
|
if (isInvalidIcicleChartQuery) {
|
|
@@ -116,7 +116,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ arrow, total, fi
|
|
|
116
116
|
if (total === 0n && !loading)
|
|
117
117
|
return _jsx("div", { className: "mx-auto text-center", children: "Profile has no samples" });
|
|
118
118
|
if (arrow !== undefined) {
|
|
119
|
-
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: effectiveCurPathArrow, setCurPath: setCurPathArrowWrapper, profileType: profileType, isHalfScreen: isHalfScreen, mappingsListFromMetadata: mappingsList, compareAbsolute: isCompareAbsolute, isIcicleChart: isIcicleChart, profileSource: profileSource, isFlamegraph: isFlamegraph, isSandwich: isSandwichIcicleGraph, tooltipId: tooltipId }) })] }));
|
|
119
|
+
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: effectiveCurPathArrow, setCurPath: setCurPathArrowWrapper, profileType: profileType, isHalfScreen: isHalfScreen, mappingsListFromMetadata: mappingsList, compareAbsolute: isCompareAbsolute, isIcicleChart: isIcicleChart, profileSource: profileSource, isFlamegraph: isFlamegraph, isSandwich: isSandwichIcicleGraph, tooltipId: tooltipId, maxFrameCount: maxFrameCount, isExpanded: isExpanded }) })] }));
|
|
120
120
|
}
|
|
121
121
|
}, [
|
|
122
122
|
isLoading,
|
|
@@ -140,6 +140,8 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ arrow, total, fi
|
|
|
140
140
|
effectiveCurPathArrow,
|
|
141
141
|
setCurPathArrowWrapper,
|
|
142
142
|
tooltipId,
|
|
143
|
+
maxFrameCount,
|
|
144
|
+
isExpanded,
|
|
143
145
|
]);
|
|
144
146
|
useEffect(() => {
|
|
145
147
|
if (isTrimmed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,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;IACF,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,eAAO,MAAM,gBAAgB,6NAiB1B,qBAAqB,KAAG,GAAG,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;AAEzD,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAIjD,OAAO,EAAC,gBAAgB,EAAC,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAIrD,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;IACF,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,eAAO,MAAM,gBAAgB,6NAiB1B,qBAAqB,KAAG,GAAG,CAAC,OA2G9B,CAAC"}
|
|
@@ -37,7 +37,7 @@ export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphDat
|
|
|
37
37
|
case 'table':
|
|
38
38
|
return topTableData != null ? (_jsx(Table, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(), currentSearchString: currentSearchString, setSearchString: setSearchString, isHalfScreen: isHalfScreen, metadataMappingFiles: flamegraphData.metadataMappingFiles })) : (_jsx(_Fragment, {}));
|
|
39
39
|
case 'sandwich':
|
|
40
|
-
return topTableData != null ? (_jsx(Sandwich, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(),
|
|
40
|
+
return topTableData != null ? (_jsx(Sandwich, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(), metadataMappingFiles: flamegraphData.metadataMappingFiles, profileSource: profileSource, queryClient: queryClient })) : (_jsx(_Fragment, {}));
|
|
41
41
|
case 'source':
|
|
42
42
|
return sourceData != null ? (_jsx(SourceView, { loading: sourceData.loading, data: sourceData.data, total: total, filtered: filtered })) : (_jsx(_Fragment, {}));
|
|
43
43
|
default:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ShareButton/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAItC,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAG/D,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,UAAU,KAAK;IACb,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6BAA6B,EAAE,KAAK,CAAC,SAAS,CAAC;CAChD;AAmGD,QAAA,MAAM,WAAW,oHAOd,KAAK,KAAG,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ShareButton/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAItC,OAAO,EAAC,YAAY,EAAE,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAG/D,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,UAAU,KAAK;IACb,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6BAA6B,EAAE,KAAK,CAAC,SAAS,CAAC;CAChD;AAmGD,QAAA,MAAM,WAAW,oHAOd,KAAK,KAAG,GAAG,CAAC,OAsFd,CAAC;AAEF,eAAe,WAAW,CAAC"}
|
|
@@ -77,7 +77,7 @@ const ShareButton = ({ queryRequest, queryClient, profileSource, onDownloadPProf
|
|
|
77
77
|
return (_jsx(_Fragment, { children: profileViewExternalSubActions != null ? (_jsx(_Fragment, { children: _jsxs(Button, { className: "gap-2", variant: "neutral", onClick: e => {
|
|
78
78
|
e.preventDefault();
|
|
79
79
|
onDownloadPProf();
|
|
80
|
-
}, disabled: pprofdownloading, id: "h-download-pprof", children: [pprofdownloading != null && pprofdownloading ? 'Downloading...' : 'Download pprof', _jsx(Icon, { icon: "material-symbols:download", width: 20 })] }) })) : (_jsxs(_Fragment, { children: [_jsxs(Dropdown, { dropdownWidth: "w-48", element: _jsxs(Button, { variant: "neutral", className: "flex items-center gap-2", id: "h-share-dropdown-button", children: [_jsx(Icon, { icon: "material-symbols:share", className: "
|
|
80
|
+
}, disabled: pprofdownloading, id: "h-download-pprof", children: [pprofdownloading != null && pprofdownloading ? 'Downloading...' : 'Download pprof', _jsx(Icon, { icon: "material-symbols:download", width: 20 })] }) })) : (_jsxs(_Fragment, { children: [_jsxs(Dropdown, { dropdownWidth: "w-48", element: _jsxs(Button, { variant: "neutral", className: "flex items-center gap-2 pr-[1.7rem]", id: "h-share-dropdown-button", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Icon, { icon: "material-symbols:share", className: "w-4 h-4" }), _jsx("span", { children: "Share" })] }), _jsx("div", { className: "pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2 text-gray-400", children: _jsx(Icon, { icon: "heroicons:chevron-down-20-solid", "aria-hidden": "true" }) })] }), children: [_jsx("span", { className: "text-xs text-gray-400 capitalize px-2", children: "actions" }), actions.map(item => (_jsx(Dropdown.Item, { onSelect: item.onSelect, children: _jsxs("div", { id: item.id, className: "flex items-center gap-2", children: [_jsx(Icon, { icon: item.icon, className: "h-4 w-4" }), _jsx("span", { children: item.label })] }) }, item.key)))] }), profileSource !== undefined &&
|
|
81
81
|
queryClient !== undefined &&
|
|
82
82
|
queryRequest !== undefined && (_jsx(ProfileShareModal, { isOpen: showProfileShareModal, closeModal: () => setShowProfileShareModal(false), queryRequest: queryRequest, queryClient: queryClient }))] })) }));
|
|
83
83
|
};
|
|
@@ -25,8 +25,6 @@ export interface VisualisationToolbarProps {
|
|
|
25
25
|
setGroupByLabels: (labels: string[]) => void;
|
|
26
26
|
showVisualizationSelector?: boolean;
|
|
27
27
|
sandwichFunctionName?: string;
|
|
28
|
-
setSandwichFunctionName: (sandwichFunctionName: string | undefined) => void;
|
|
29
|
-
resetSandwichFunctionName: () => void;
|
|
30
28
|
}
|
|
31
29
|
export interface TableToolbarProps {
|
|
32
30
|
profileType?: ProfileType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAIzB,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAC,gBAAgB,EAAC,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAUrD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6BAA6B,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7C,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/Toolbars/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,EAAE,EAAC,MAAM,OAAO,CAAC;AAIzB,OAAO,EAAC,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAEjD,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAE1C,OAAO,EAAC,gBAAgB,EAAC,MAAM,oDAAoD,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAUrD,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,6BAA6B,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChD,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7C,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,aAAa,EAAE,CAAC,IAAI,EAAE,gBAAgB,EAAE,KAAK,IAAI,CAAC;CACnD;AAED,MAAM,WAAW,+BAA+B;IAC9C,yBAAyB,EAAE,MAAM,IAAI,CAAC;IACtC,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,iBAAiB,CAwB9C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,uBAAuB,CAiB1D,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,EAAE,CAAC,+BAA+B,CAmB1E,CAAC;AAMF,eAAO,MAAM,oBAAoB,EAAE,EAAE,CAAC,yBAAyB,CA+F9D,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Icon } from '@iconify/react';
|
|
3
|
-
import { Button
|
|
3
|
+
import { Button } from '@parca/components';
|
|
4
4
|
import { useDashboard } from '../../context/DashboardContext';
|
|
5
5
|
import GroupByDropdown from '../ActionButtons/GroupByDropdown';
|
|
6
6
|
import FilterByFunctionButton from '../FilterByFunctionButton';
|
|
@@ -19,18 +19,17 @@ export const SandwichIcicleGraphToolbar = ({ resetSandwichFunctionName, sandwich
|
|
|
19
19
|
return (_jsx(_Fragment, { children: _jsx("div", { className: "flex w-full gap-2 items-end justify-between", children: _jsx(Button, { color: "neutral", onClick: () => resetSandwichFunctionName(), className: "w-auto", variant: "neutral", disabled: sandwichFunctionName === undefined || sandwichFunctionName.length === 0, children: "Reset view" }) }) }));
|
|
20
20
|
};
|
|
21
21
|
const Divider = () => (_jsx("div", { className: "border-t mt-4 border-gray-200 dark:border-gray-700 h-[1px] w-full pb-4" }));
|
|
22
|
-
export const VisualisationToolbar = ({ groupBy, toggleGroupBy, groupByLabels, setGroupByLabels, profileType,
|
|
22
|
+
export const VisualisationToolbar = ({ groupBy, toggleGroupBy, groupByLabels, setGroupByLabels, profileType, profileSource, queryClient, onDownloadPProf, pprofdownloading, profileViewExternalSubActions, curPath, setNewCurPath, total, filtered, currentSearchString, clearSelection, showVisualizationSelector = true, }) => {
|
|
23
23
|
const { dashboardItems } = useDashboard();
|
|
24
24
|
const isTableViz = dashboardItems?.includes('table');
|
|
25
25
|
const isTableVizOnly = dashboardItems?.length === 1 && isTableViz;
|
|
26
26
|
const isGraphViz = dashboardItems?.includes('icicle');
|
|
27
|
-
const
|
|
28
|
-
const isTableView = isTableVizOnly || isSandwichIcicleGraphViz;
|
|
27
|
+
const isGraphVizOnly = dashboardItems?.length === 1 && isGraphViz;
|
|
29
28
|
const req = profileSource?.QueryRequest();
|
|
30
29
|
if (req !== null && req !== undefined) {
|
|
31
30
|
req.groupBy = {
|
|
32
31
|
fields: groupBy ?? [],
|
|
33
32
|
};
|
|
34
33
|
}
|
|
35
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full justify-between items-end", children: [_jsxs("div", { className: "flex gap-3 items-end", children: [
|
|
34
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full justify-between items-end", children: [_jsxs("div", { className: "flex gap-3 items-end", children: [isGraphViz && (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, labels: groupByLabels, setGroupByLabels: setGroupByLabels }), _jsx(InvertCallStack, {})] })), _jsx(FilterByFunctionButton, {}), profileViewExternalSubActions != null ? profileViewExternalSubActions : null] }), _jsxs("div", { className: "flex gap-3", children: [_jsx(MultiLevelDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, profileType: profileType, onSelect: () => { }, isTableVizOnly: isTableVizOnly }), _jsx(ShareButton, { profileSource: profileSource, queryClient: queryClient, queryRequest: req, onDownloadPProf: onDownloadPProf, pprofdownloading: pprofdownloading ?? false, profileViewExternalSubActions: profileViewExternalSubActions }), showVisualizationSelector ? _jsx(ViewSelector, { profileSource: profileSource }) : null] })] }), isGraphVizOnly && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(IcicleGraphToolbar, { curPath: curPath, setNewCurPath: setNewCurPath })] })), isTableVizOnly && (_jsxs(_Fragment, { children: [_jsx(Divider, {}), _jsx(TableToolbar, { profileType: profileType, total: total, filtered: filtered, clearSelection: clearSelection, currentSearchString: currentSearchString })] }))] }));
|
|
36
35
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ViewSelector/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,UAAU,KAAK;IACb,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,QAAA,MAAM,YAAY,sBAAqB,KAAK,KAAG,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/ViewSelector/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,UAAU,KAAK;IACb,aAAa,CAAC,EAAE,aAAa,CAAC;CAC/B;AAED,QAAA,MAAM,YAAY,sBAAqB,KAAK,KAAG,GAAG,CAAC,OAqJlD,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -5,10 +5,11 @@ const ViewSelector = ({ profileSource }) => {
|
|
|
5
5
|
const [dashboardItems = ['icicle'], setDashboardItems] = useURLState('dashboard_items', {
|
|
6
6
|
alwaysReturnArray: true,
|
|
7
7
|
});
|
|
8
|
+
const [, setSandwichFunctionName] = useURLState('sandwich_function_name');
|
|
8
9
|
const { enableSourcesView, enableSandwichView } = useParcaContext();
|
|
9
10
|
const allItems = [
|
|
10
|
-
{ key: 'table', label: 'Table', canBeSelected: !dashboardItems.includes('table') },
|
|
11
11
|
{ key: 'icicle', label: 'icicle', canBeSelected: !dashboardItems.includes('icicle') },
|
|
12
|
+
{ key: 'table', label: 'Table', canBeSelected: !dashboardItems.includes('table') },
|
|
12
13
|
{
|
|
13
14
|
key: 'iciclechart',
|
|
14
15
|
label: (_jsxs("span", { className: "relative", children: ["Iciclechart", _jsx("span", { className: "absolute top-[-2px] text-xs lowercase text-red-500", children: "\u00A0alpha" })] })),
|
|
@@ -38,26 +39,28 @@ const ViewSelector = ({ profileSource }) => {
|
|
|
38
39
|
const getInnerActionForItem = (item) => {
|
|
39
40
|
if (dashboardItems.length === 1 && item.key === dashboardItems[0])
|
|
40
41
|
return undefined;
|
|
41
|
-
//
|
|
42
|
-
if (item.key
|
|
43
|
-
return
|
|
44
|
-
text: 'Add Panel',
|
|
45
|
-
onClick: () => { },
|
|
46
|
-
isDisabled: true, // Custom property to control button state
|
|
47
|
-
};
|
|
48
|
-
}
|
|
42
|
+
// If we already have 2 panels and this item isn't selected, don't show any action
|
|
43
|
+
if (dashboardItems.length >= 2 && !dashboardItems.includes(item.key))
|
|
44
|
+
return undefined;
|
|
49
45
|
return {
|
|
50
46
|
text: !item.canBeSelected && item.key === 'source'
|
|
51
47
|
? 'Add Panel'
|
|
52
48
|
: item.canBeSelected
|
|
53
49
|
? 'Add Panel'
|
|
54
|
-
:
|
|
50
|
+
: dashboardItems.includes(item.key)
|
|
51
|
+
? 'Close Panel'
|
|
52
|
+
: 'Add Panel',
|
|
55
53
|
onClick: () => {
|
|
56
54
|
if (item.canBeSelected) {
|
|
57
55
|
setDashboardItems([...dashboardItems, item.key]);
|
|
58
56
|
}
|
|
59
57
|
else {
|
|
60
|
-
|
|
58
|
+
const newDashboardItems = dashboardItems.filter(v => v !== item.key);
|
|
59
|
+
setDashboardItems(newDashboardItems);
|
|
60
|
+
// Reset sandwich function name when removing sandwich panel
|
|
61
|
+
if (item.key === 'sandwich') {
|
|
62
|
+
setSandwichFunctionName(undefined);
|
|
63
|
+
}
|
|
61
64
|
}
|
|
62
65
|
},
|
|
63
66
|
isDisabled: dashboardItems.length === 1 && dashboardItems.includes('sandwich'),
|
|
@@ -72,6 +75,10 @@ const ViewSelector = ({ profileSource }) => {
|
|
|
72
75
|
}));
|
|
73
76
|
const onSelection = (value) => {
|
|
74
77
|
const isOnlyChart = dashboardItems.length === 1;
|
|
78
|
+
if (isOnlyChart && value === 'sandwich') {
|
|
79
|
+
setDashboardItems([...dashboardItems, value]);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
75
82
|
if (isOnlyChart) {
|
|
76
83
|
setDashboardItems([value]);
|
|
77
84
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardContext.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/context/DashboardContext.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,EAAE,EAAE,iBAAiB,EAA4B,MAAM,OAAO,CAAC;AAIvE,OAAO,EAAC,iBAAiB,EAAC,MAAM,wBAAwB,CAAC;AAEzD,UAAU,oBAAoB;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7C,gBAAgB,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAID,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"DashboardContext.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/context/DashboardContext.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,EAAE,EAAE,iBAAiB,EAA4B,MAAM,OAAO,CAAC;AAIvE,OAAO,EAAC,iBAAiB,EAAC,MAAM,wBAAwB,CAAC;AAEzD,UAAU,oBAAoB;IAC5B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IAC7C,gBAAgB,EAAE,CAAC,iBAAiB,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACjE,gBAAgB,EAAE,OAAO,CAAC;CAC3B;AAID,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CA8BnD,CAAC;AAEF,eAAO,MAAM,YAAY,QAAO,oBAM/B,CAAC"}
|