@parca/profile 0.16.444 → 0.16.446

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.d.ts.map +1 -1
  3. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.js +9 -2
  4. package/dist/ProfileIcicleGraph/index.d.ts.map +1 -1
  5. package/dist/ProfileIcicleGraph/index.js +3 -11
  6. package/dist/ProfileView/ColorStackLegend.d.ts.map +1 -0
  7. package/dist/{ProfileIcicleGraph/IcicleGraphArrow → ProfileView}/ColorStackLegend.js +2 -2
  8. package/dist/ProfileView/VisualizationPanel.d.ts +4 -1
  9. package/dist/ProfileView/VisualizationPanel.d.ts.map +1 -1
  10. package/dist/ProfileView/VisualizationPanel.js +4 -6
  11. package/dist/ProfileView/index.d.ts.map +1 -1
  12. package/dist/ProfileView/index.js +33 -10
  13. package/dist/ProfileViewWithData.d.ts.map +1 -1
  14. package/dist/ProfileViewWithData.js +1 -3
  15. package/dist/Table/index.d.ts +2 -29
  16. package/dist/Table/index.d.ts.map +1 -1
  17. package/dist/Table/index.js +65 -160
  18. package/dist/Table/utils/functions.d.ts +49 -0
  19. package/dist/Table/utils/functions.d.ts.map +1 -0
  20. package/dist/Table/utils/functions.js +181 -0
  21. package/dist/components/ActionButtons/GroupByDropdown.js +1 -1
  22. package/dist/components/ActionButtons/SortByDropdown.d.ts +3 -0
  23. package/dist/components/ActionButtons/SortByDropdown.d.ts.map +1 -0
  24. package/dist/components/ActionButtons/SortByDropdown.js +49 -0
  25. package/dist/components/VisualisationToolbar/MultiLevelDropdown.d.ts.map +1 -1
  26. package/dist/components/VisualisationToolbar/MultiLevelDropdown.js +3 -27
  27. package/dist/components/VisualisationToolbar/TableColumnsDropdown.d.ts.map +1 -1
  28. package/dist/components/VisualisationToolbar/TableColumnsDropdown.js +3 -1
  29. package/dist/components/VisualisationToolbar/index.d.ts +11 -0
  30. package/dist/components/VisualisationToolbar/index.d.ts.map +1 -1
  31. package/dist/components/VisualisationToolbar/index.js +13 -6
  32. package/dist/styles.css +1 -1
  33. package/package.json +3 -3
  34. package/src/ProfileIcicleGraph/IcicleGraphArrow/ContextMenu.tsx +19 -2
  35. package/src/ProfileIcicleGraph/index.tsx +2 -18
  36. package/src/{ProfileIcicleGraph/IcicleGraphArrow → ProfileView}/ColorStackLegend.tsx +2 -2
  37. package/src/ProfileView/VisualizationPanel.tsx +13 -10
  38. package/src/ProfileView/index.tsx +59 -9
  39. package/src/ProfileViewWithData.tsx +1 -3
  40. package/src/Table/index.tsx +138 -265
  41. package/src/Table/utils/functions.ts +284 -0
  42. package/src/components/ActionButtons/GroupByDropdown.tsx +1 -1
  43. package/src/components/ActionButtons/SortByDropdown.tsx +84 -0
  44. package/src/components/VisualisationToolbar/MultiLevelDropdown.tsx +7 -30
  45. package/src/components/VisualisationToolbar/TableColumnsDropdown.tsx +3 -1
  46. package/src/components/VisualisationToolbar/index.tsx +103 -58
  47. package/dist/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.d.ts.map +0 -1
  48. /package/dist/{ProfileIcicleGraph/IcicleGraphArrow → ProfileView}/ColorStackLegend.d.ts +0 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,14 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [0.16.446](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.445...@parca/profile@0.16.446) (2024-11-19)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
10
+ ## [0.16.445](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.444...@parca/profile@0.16.445) (2024-11-18)
11
+
12
+ **Note:** Version bump only for package @parca/profile
13
+
6
14
  ## [0.16.444](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.443...@parca/profile@0.16.444) (2024-11-14)
7
15
 
8
16
  **Note:** Version bump only for package @parca/profile
@@ -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;AAMnC,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,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,QAAA,MAAM,WAAW,2JAed,gBAAgB,KAAG,GAAG,CAAC,OA6JzB,CAAC;AAEF,eAAe,WAAW,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;AAMnC,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,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,CAAC,SAAS,EAAE,OAAO,KAAK,IAAI,CAAC;IAC9C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED,QAAA,MAAM,WAAW,2JAed,gBAAgB,KAAG,GAAG,CAAC,OA8KzB,CAAC;AAEF,eAAe,WAAW,CAAC"}
@@ -14,7 +14,7 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
14
14
  import { Icon } from '@iconify/react';
15
15
  import { Item, Menu, Separator, Submenu } from 'react-contexify';
16
16
  import { Tooltip } from 'react-tooltip';
17
- import { useParcaContext } from '@parca/components';
17
+ import { useParcaContext, useURLState } from '@parca/components';
18
18
  import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
19
19
  import { getLastItem } from '@parca/utilities';
20
20
  import { useGraphTooltip } from '../../GraphTooltipArrow/useGraphTooltip';
@@ -35,6 +35,10 @@ const ContextMenu = ({ menuId, table, total, totalUnfiltered, row, level, compar
35
35
  compareAbsolute,
36
36
  });
37
37
  const { functionFilename, functionSystemName, file, openFile, isSourceAvailable, locationAddress, mappingFile, mappingBuildID, inlined, } = useGraphTooltipMetaInfo({ table, row });
38
+ const [_, setSearchString] = useURLState('search_string');
39
+ const [dashboardItems, setDashboardItems] = useURLState('dashboard_items', {
40
+ alwaysReturnArray: true,
41
+ });
38
42
  if (contextMenuData === null) {
39
43
  return _jsx(_Fragment, {});
40
44
  }
@@ -78,6 +82,9 @@ const ContextMenu = ({ menuId, table, total, totalUnfiltered, row, level, compar
78
82
  { id: 'Build Id', value: buildIdText },
79
83
  ];
80
84
  const nonEmptyValuesToCopy = valuesToCopy.filter(({ value }) => value !== '');
81
- return (_jsxs(Menu, { id: menuId, onVisibilityChange: trackVisibility, theme: isDarkMode ? 'dark' : '', 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: "reset-view", onClick: handleResetView, disabled: curPath.length === 0, 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))) }) }), _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'] }) })] }));
85
+ return (_jsxs(Menu, { id: menuId, onVisibilityChange: trackVisibility, theme: isDarkMode ? 'dark' : '', 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: () => {
86
+ setSearchString(functionName);
87
+ setDashboardItems([...dashboardItems, 'table']);
88
+ }, children: _jsxs("div", { className: "flex w-full items-center gap-2", children: [_jsx(Icon, { icon: "ph:table" }), _jsx("div", { children: "Show in table" })] }) }), _jsx(Item, { id: "reset-view", onClick: handleResetView, disabled: curPath.length === 0, 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))) }) }), _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'] }) })] }));
82
89
  };
83
90
  export default ContextMenu;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAK1D,OAAO,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAY1C,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACvB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAMD,QAAA,MAAM,kBAAkB,uIAarB,uBAAuB,KAAG,GAAG,CAAC,OA6LhC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAI1D,OAAO,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAW1C,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACvB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAMD,QAAA,MAAM,kBAAkB,uIAarB,uBAAuB,KAAG,GAAG,CAAC,OA+KhC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
@@ -12,16 +12,14 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
  import { useEffect, useMemo, useState } from 'react';
15
- import { tableFromIPC } from 'apache-arrow';
16
15
  import { AnimatePresence, motion } from 'framer-motion';
17
16
  import { IcicleGraphSkeleton, useParcaContext, useURLState } from '@parca/components';
18
- import { capitalizeOnlyFirstLetter, divide, selectQueryParam } from '@parca/utilities';
17
+ import { capitalizeOnlyFirstLetter, divide } from '@parca/utilities';
19
18
  import { useProfileViewContext } from '../ProfileView/ProfileViewContext';
20
19
  import DiffLegend from '../components/DiffLegend';
21
20
  import { IcicleGraph } from './IcicleGraph';
22
21
  import { FIELD_FUNCTION_NAME, IcicleGraphArrow } from './IcicleGraphArrow';
23
- import ColorStackLegend from './IcicleGraphArrow/ColorStackLegend';
24
- import useMappingList, { useFilenamesList } from './IcicleGraphArrow/useMappingList';
22
+ import useMappingList from './IcicleGraphArrow/useMappingList';
25
23
  const numberFormatter = new Intl.NumberFormat('en-US');
26
24
  const ErrorContent = ({ errorMessage }) => {
27
25
  return _jsx("div", { className: "flex justify-center p-10", children: errorMessage });
@@ -30,12 +28,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
30
28
  const { onError, authenticationErrorMessage, isDarkMode } = useParcaContext();
31
29
  const { compareMode } = useProfileViewContext();
32
30
  const [isLoading, setIsLoading] = useState(true);
33
- const isColorStackLegendEnabled = selectQueryParam('color_stack_legend') === 'true';
34
- const table = useMemo(() => {
35
- return arrow !== undefined ? tableFromIPC(arrow.record) : null;
36
- }, [arrow]);
37
31
  const mappingsList = useMappingList(metadataMappingFiles);
38
- const filenamesList = useFilenamesList(table);
39
32
  const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState('sort_by');
40
33
  const [colorBy, setColorBy] = useURLState('color_by');
41
34
  // By default, we want delta profiles (CPU) to be relatively compared.
@@ -43,7 +36,6 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
43
36
  const compareAbsoluteDefault = profileType?.delta === false ? 'true' : 'false';
44
37
  const [compareAbsolute = compareAbsoluteDefault] = useURLState('compare_absolute');
45
38
  const isCompareAbsolute = compareAbsolute === 'true';
46
- const colorByValue = colorBy === undefined || colorBy === '' ? 'binary' : colorBy;
47
39
  const mappingsListCount = useMemo(() => mappingsList.filter(m => m !== '').length, [mappingsList]);
48
40
  const [totalFormatted, totalUnfilteredFormatted, isTrimmed, trimmedFormatted, trimmedPercentage, isFiltered, filteredPercentage,] = useMemo(() => {
49
41
  if (graph === undefined && arrow === undefined) {
@@ -118,6 +110,6 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
118
110
  if (isTrimmed) {
119
111
  console.info(`Trimmed ${trimmedFormatted} (${trimmedPercentage}%) too small values.`);
120
112
  }
121
- return (_jsx(AnimatePresence, { children: _jsxs(motion.div, { className: "relative h-full w-full", initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.5 }, children: [compareMode ? _jsx(DiffLegend, {}) : null, isColorStackLegendEnabled && (_jsx(ColorStackLegend, { compareMode: compareMode, mappings: colorByValue === 'binary' ? mappingsList : filenamesList, loading: isLoading })), _jsx("div", { className: "min-h-48", id: "h-icicle-graph", children: _jsx(_Fragment, { children: icicleGraph }) }), _jsxs("p", { className: "my-2 text-xs", children: ["Showing ", totalFormatted, ' ', isFiltered ? (_jsxs("span", { children: ["(", filteredPercentage, "%) filtered of ", totalUnfilteredFormatted, ' '] })) : (_jsx(_Fragment, {})), "values.", ' '] })] }, "icicle-graph-loaded") }));
113
+ return (_jsx(AnimatePresence, { children: _jsxs(motion.div, { className: "relative h-full w-full", initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.5 }, children: [compareMode ? _jsx(DiffLegend, {}) : null, _jsx("div", { className: "min-h-48", id: "h-icicle-graph", children: _jsx(_Fragment, { children: icicleGraph }) }), _jsxs("p", { className: "my-2 text-xs", children: ["Showing ", totalFormatted, ' ', isFiltered ? (_jsxs("span", { children: ["(", filteredPercentage, "%) filtered of ", totalUnfilteredFormatted, ' '] })) : (_jsx(_Fragment, {})), "values.", ' '] })] }, "icicle-graph-loaded") }));
122
114
  };
123
115
  export default ProfileIcicleGraph;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColorStackLegend.d.ts","sourceRoot":"","sources":["../../src/ProfileView/ColorStackLegend.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgB,MAAM,OAAO,CAAC;AAYrC,UAAU,KAAK;IACb,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,QAAA,MAAM,gBAAgB,uCAA8C,KAAK,KAAG,KAAK,CAAC,GAAG,CAAC,OAmGrF,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -17,8 +17,8 @@ import cx from 'classnames';
17
17
  import { useURLState } from '@parca/components';
18
18
  import { USER_PREFERENCES, useCurrentColorProfile, useUserPreference } from '@parca/hooks';
19
19
  import { EVERYTHING_ELSE, selectDarkMode, useAppSelector } from '@parca/store';
20
- import { getMappingColors } from '.';
21
- import useMappingList from './useMappingList';
20
+ import { getMappingColors } from '../ProfileIcicleGraph/IcicleGraphArrow/';
21
+ import useMappingList from '../ProfileIcicleGraph/IcicleGraphArrow/useMappingList';
22
22
  const ColorStackLegend = ({ mappings, compareMode = false, loading }) => {
23
23
  const isDarkMode = useAppSelector(selectDarkMode);
24
24
  const currentColorProfile = useCurrentColorProfile();
@@ -9,8 +9,11 @@ interface Props {
9
9
  getDashboardItemByType: (props: {
10
10
  type: string;
11
11
  isHalfScreen: boolean;
12
- setActionButtons: (actionButtons: JSX.Element) => void;
13
12
  }) => JSX.Element;
13
+ actionButtons: {
14
+ icicle: JSX.Element;
15
+ table: JSX.Element;
16
+ };
14
17
  }
15
18
  export declare const VisualizationPanel: React.NamedExoticComponent<Props>;
16
19
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"VisualizationPanel.d.ts","sourceRoot":"","sources":["../../src/ProfileView/VisualizationPanel.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAiB,MAAM,OAAO,CAAC;AAItC,OAAO,KAAK,EAAC,gCAAgC,EAAC,MAAM,qBAAqB,CAAC;AAK1E,UAAU,KAAK;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,gCAAgC,GAAG,IAAI,GAAG,SAAS,CAAC;IACrE,sBAAsB,EAAE,CAAC,KAAK,EAAE;QAC9B,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,OAAO,CAAC;QACtB,gBAAgB,EAAE,CAAC,aAAa,EAAE,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;KACxD,KAAK,GAAG,CAAC,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,kBAAkB,mCAsD7B,CAAC"}
1
+ {"version":3,"file":"VisualizationPanel.d.ts","sourceRoot":"","sources":["../../src/ProfileView/VisualizationPanel.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,KAAK,EAAC,gCAAgC,EAAC,MAAM,qBAAqB,CAAC;AAK1E,UAAU,KAAK;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,IAAI,CAAC;IAClD,eAAe,EAAE,gCAAgC,GAAG,IAAI,GAAG,SAAS,CAAC;IACrE,sBAAsB,EAAE,CAAC,KAAK,EAAE;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAC,KAAK,GAAG,CAAC,OAAO,CAAC;IACtF,aAAa,EAAE;QACb,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC;QACpB,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC;KACpB,CAAC;CACH;AAED,eAAO,MAAM,kBAAkB,mCAyD7B,CAAC"}
@@ -1,4 +1,4 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } 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,17 +11,15 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } 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 React, { useState } from 'react';
14
+ import React from 'react';
15
15
  import { Icon } from '@iconify/react';
16
16
  import cx from 'classnames';
17
17
  import { IconButton, useParcaContext } from '@parca/components';
18
18
  import { CloseIcon } from '@parca/icons';
19
- export const VisualizationPanel = React.memo(function VisualizationPanel({ dashboardItem, isMultiPanelView, handleClosePanel, dragHandleProps, getDashboardItemByType, }) {
20
- const [actionButtons, setActionButtons] = useState(_jsx(_Fragment, {}));
19
+ export const VisualizationPanel = React.memo(function VisualizationPanel({ dashboardItem, isMultiPanelView, handleClosePanel, dragHandleProps, getDashboardItemByType, actionButtons, }) {
21
20
  const { flamegraphHint } = useParcaContext();
22
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full items-center justify-end gap-2 pb-2", children: [_jsxs("div", { className: cx('flex w-full justify-between flex-col-reverse md:flex-row', isMultiPanelView && dashboardItem === 'icicle' ? 'items-end gap-x-2' : 'items-end'), children: [_jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: cx(isMultiPanelView ? '' : 'hidden', 'flex items-center'), ...dragHandleProps, children: _jsx(Icon, { className: "text-xl", icon: "material-symbols:drag-indicator" }) }), _jsx("div", { className: "flex gap-2", children: actionButtons })] }), _jsx("div", { className: cx('flex flex-row items-center gap-4', isMultiPanelView && dashboardItem === 'icicle' && 'pb-[10px]'), children: dashboardItem === 'icicle' && flamegraphHint != null ? (_jsx("div", { className: "px-2", children: flamegraphHint })) : null })] }), isMultiPanelView && (_jsx(IconButton, { className: "py-0", onClick: () => handleClosePanel(dashboardItem), icon: _jsx(CloseIcon, {}) }))] }), getDashboardItemByType({
21
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex w-full items-center justify-end gap-2 pb-2", children: [_jsxs("div", { className: cx('flex w-full justify-between flex-col-reverse md:flex-row', isMultiPanelView && dashboardItem === 'icicle' ? 'items-end gap-x-2' : 'items-end'), children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: cx(isMultiPanelView ? '' : 'hidden', 'flex items-center'), ...dragHandleProps, children: _jsx(Icon, { className: "text-xl", icon: "material-symbols:drag-indicator" }) }), isMultiPanelView ? (_jsx("div", { className: "flex gap-2", children: actionButtons[dashboardItem] })) : null] }), _jsx("div", { className: cx('flex flex-row items-center gap-4', isMultiPanelView && dashboardItem === 'icicle' && 'pb-[10px]'), children: dashboardItem === 'icicle' && flamegraphHint != null ? (_jsx("div", { className: "px-2", children: flamegraphHint })) : null })] }), isMultiPanelView && (_jsx(IconButton, { className: "py-0", onClick: () => handleClosePanel(dashboardItem), icon: _jsx(CloseIcon, {}) }))] }), getDashboardItemByType({
23
22
  type: dashboardItem,
24
23
  isHalfScreen: isMultiPanelView,
25
- setActionButtons,
26
24
  })] }));
27
25
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA0BA,OAAO,EACL,SAAS,IAAI,aAAa,EAC1B,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,UAAU,EACV,GAAG,EACJ,MAAM,eAAe,CAAC;AAUvB,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAO/C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAWD,eAAO,MAAM,WAAW,0JAYrB,gBAAgB,KAAG,GAAG,CAAC,OA6UzB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA2BA,OAAO,EACL,SAAS,IAAI,aAAa,EAC1B,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,UAAU,EACV,GAAG,EACJ,MAAM,eAAe,CAAC;AAavB,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAW/C,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,UAAU,UAAU;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAWD,eAAO,MAAM,WAAW,0JAYrB,gBAAgB,KAAG,GAAG,CAAC,OAuXzB,CAAC"}
@@ -12,7 +12,8 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
12
12
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
13
  // See the License for the specific language governing permissions and
14
14
  // limitations under the License.
15
- import { Profiler, useCallback, useEffect, useState } from 'react';
15
+ import { Profiler, useCallback, useEffect, useMemo, useState } from 'react';
16
+ import { tableFromIPC } from 'apache-arrow';
16
17
  import cx from 'classnames';
17
18
  import { scaleLinear } from 'd3';
18
19
  import graphviz from 'graphviz-wasm';
@@ -25,9 +26,11 @@ import { Callgraph } from '../';
25
26
  import { jsonToDot } from '../Callgraph/utils';
26
27
  import ProfileIcicleGraph from '../ProfileIcicleGraph';
27
28
  import { FIELD_FUNCTION_NAME } from '../ProfileIcicleGraph/IcicleGraphArrow';
29
+ import useMappingList, { useFilenamesList, } from '../ProfileIcicleGraph/IcicleGraphArrow/useMappingList';
28
30
  import { SourceView } from '../SourceView';
29
31
  import { Table } from '../Table';
30
- import VisualisationToolbar from '../components/VisualisationToolbar';
32
+ import VisualisationToolbar, { IcicleGraphToolbar, TableToolbar, } from '../components/VisualisationToolbar';
33
+ import ColorStackLegend from './ColorStackLegend';
31
34
  import { ProfileViewContextProvider } from './ProfileViewContext';
32
35
  import { VisualizationPanel } from './VisualizationPanel';
33
36
  function arrayEquals(a, b) {
@@ -46,8 +49,17 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
46
49
  const [graphvizLoaded, setGraphvizLoaded] = useState(false);
47
50
  const [callgraphSVG, setCallgraphSVG] = useState(undefined);
48
51
  const [currentSearchString, setSearchString] = useURLState('search_string');
52
+ const [colorStackLegend] = useURLState('color_stack_legend');
53
+ const [colorBy] = useURLState('color_by');
54
+ const isColorStackLegendEnabled = colorStackLegend === 'true';
55
+ const colorByValue = colorBy === undefined || colorBy === '' ? 'binary' : colorBy;
49
56
  const isDarkMode = useAppSelector(selectDarkMode);
50
57
  const isMultiPanelView = dashboardItems.length > 1;
58
+ const table = useMemo(() => {
59
+ return flamegraphData.arrow !== undefined ? tableFromIPC(flamegraphData.arrow.record) : null;
60
+ }, [flamegraphData.arrow]);
61
+ const mappingsList = useMappingList(flamegraphData.metadataMappingFiles);
62
+ const filenamesList = useFilenamesList(table);
51
63
  const { perf, profileViewExternalMainActions } = useParcaContext();
52
64
  useEffect(() => {
53
65
  // Reset the current path when the profile source changes
@@ -92,15 +104,15 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
92
104
  setCurPath(path);
93
105
  }
94
106
  };
95
- const getDashboardItemByType = ({ type, isHalfScreen, setActionButtons, }) => {
107
+ const getDashboardItemByType = ({ type, isHalfScreen, }) => {
96
108
  switch (type) {
97
109
  case 'icicle': {
98
110
  return (_jsx(ConditionalWrapper, { condition: perf?.onRender != null, WrapperComponent: Profiler, wrapperProps: {
99
111
  id: 'icicleGraph',
100
112
  onRender: perf?.onRender,
101
- }, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, arrow: flamegraphData?.arrow, graph: flamegraphData?.data, total: total, filtered: filtered, profileType: profileSource?.ProfileType(), loading: flamegraphData.loading, setActionButtons: setActionButtons, error: flamegraphData.error, isHalfScreen: isHalfScreen, width: dimensions?.width !== undefined
113
+ }, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, arrow: flamegraphData?.arrow, graph: flamegraphData?.data, total: total, filtered: filtered, profileType: profileSource?.ProfileType(), loading: flamegraphData.loading, error: flamegraphData.error, isHalfScreen: isHalfScreen, width: dimensions?.width !== undefined
102
114
  ? isHalfScreen
103
- ? (dimensions.width - 40) / 2
115
+ ? (dimensions.width - 54) / 2
104
116
  : dimensions.width - 16
105
117
  : 0, metadataMappingFiles: flamegraphData.metadataMappingFiles, metadataLoading: flamegraphData.metadataLoading }) }));
106
118
  }
@@ -110,10 +122,10 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
110
122
  dimensions?.width !== undefined ? (_jsx(Callgraph, { data: callgraphData.data, svgString: callgraphSVG, profileType: profileSource?.ProfileType(), width: isHalfScreen ? dimensions?.width / 2 : dimensions?.width })) : (_jsx(_Fragment, {}));
111
123
  }
112
124
  case 'table': {
113
- return topTableData != null ? (_jsx(Table, { total: total, filtered: filtered, loading: topTableData.loading, data: topTableData.arrow?.record, unit: topTableData.unit, profileType: profileSource?.ProfileType(), setActionButtons: setActionButtons, currentSearchString: currentSearchString, setSearchString: setSearchString, isHalfScreen: isHalfScreen })) : (_jsx(_Fragment, {}));
125
+ 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, {}));
114
126
  }
115
127
  case 'source': {
116
- return sourceData != null ? (_jsx(SourceView, { loading: sourceData.loading, data: sourceData.data, total: total, filtered: filtered, setActionButtons: setActionButtons })) : (_jsx(_Fragment, {}));
128
+ return sourceData != null ? (_jsx(SourceView, { loading: sourceData.loading, data: sourceData.data, total: total, filtered: filtered })) : (_jsx(_Fragment, {}));
117
129
  }
118
130
  default: {
119
131
  return _jsx(_Fragment, {});
@@ -155,6 +167,15 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
155
167
  }, [groupBy, setGroupBy]);
156
168
  const showDivider = hasProfileSource &&
157
169
  (profileViewExternalMainActions === null || profileViewExternalMainActions === undefined);
170
+ const clearSelection = useCallback(() => {
171
+ setSearchString?.('');
172
+ }, [setSearchString]);
173
+ const getActionButtonsWithMultiPanelView = () => {
174
+ return {
175
+ icicle: _jsx(IcicleGraphToolbar, { curPath: curPath, setNewCurPath: setNewCurPath }),
176
+ table: (_jsx(TableToolbar, { profileType: profileSource?.ProfileType(), total: total, filtered: filtered, clearSelection: clearSelection, currentSearchString: currentSearchString })),
177
+ };
178
+ };
158
179
  return (_jsx(KeyDownProvider, { children: _jsxs(ProfileViewContextProvider, { value: { profileSource, compareMode }, children: [showDivider ? (_jsx(_Fragment, { children: _jsx("div", { className: "border-t border-gray-200 dark:border-gray-700 h-[1px] w-full pb-4" }) })) : null, _jsx("div", { className: cx('flex w-full', hasProfileSource || profileViewExternalMainActions != null
159
180
  ? 'justify-start'
160
181
  : 'justify-end', {
@@ -162,10 +183,12 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
162
183
  'items-center mb-2': hasProfileSource,
163
184
  }), children: _jsxs("div", { children: [hasProfileSource && (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("div", { className: "text-xs font-medium", children: headerParts.length > 0 ? headerParts[0].replace(/"/g, '') : '' }), _jsx("div", { className: "text-xs font-medium", children: headerParts.length > 1
164
185
  ? headerParts[headerParts.length - 1].replace(/"/g, '')
165
- : '' })] })), profileViewExternalMainActions != null ? profileViewExternalMainActions : null] }) }), _jsx(VisualisationToolbar, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, hasProfileSource: hasProfileSource, pprofdownloading: pprofDownloading, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: onDownloadPProf, isMultiPanelView: isMultiPanelView, dashboardItems: dashboardItems, curPath: curPath, setNewCurPath: setNewCurPath, profileType: profileSource?.ProfileType(), total: total, filtered: filtered, currentSearchString: currentSearchString, setSearchString: setSearchString, groupByLabels: flamegraphData.metadataLabels ?? [] }), _jsx("div", { className: "w-full", ref: ref, children: _jsx(DragDropContext, { onDragEnd: onDragEnd, children: _jsx(Droppable, { droppableId: "droppable", direction: "horizontal", children: provided => (_jsx("div", { ref: provided.innerRef, className: cx('grid w-full gap-2', isMultiPanelView ? 'grid-cols-2' : 'grid-cols-1'), ...provided.droppableProps, children: dashboardItems.map((dashboardItem, index) => {
186
+ : '' })] })), profileViewExternalMainActions != null ? profileViewExternalMainActions : null] }) }), _jsx(VisualisationToolbar, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, hasProfileSource: hasProfileSource, pprofdownloading: pprofDownloading, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: onDownloadPProf, isMultiPanelView: isMultiPanelView, dashboardItems: dashboardItems, curPath: curPath, setNewCurPath: setNewCurPath, profileType: profileSource?.ProfileType(), total: total, filtered: filtered, currentSearchString: currentSearchString, setSearchString: setSearchString, groupByLabels: flamegraphData.metadataLabels ?? [] }), isColorStackLegendEnabled && (_jsx(ColorStackLegend, { compareMode: compareMode, mappings: colorByValue === 'binary' ? mappingsList : filenamesList, loading: flamegraphData.metadataLoading })), _jsx("div", { className: "w-full", ref: ref, children: _jsx(DragDropContext, { onDragEnd: onDragEnd, children: _jsx(Droppable, { droppableId: "droppable", direction: "horizontal", children: provided => (_jsx("div", { ref: provided.innerRef, className: cx('grid w-full gap-2', isMultiPanelView ? 'grid-cols-2' : 'grid-cols-1'), ...provided.droppableProps, children: dashboardItems.map((dashboardItem, index) => {
166
187
  return (_jsx(Draggable, { draggableId: dashboardItem, index: index, isDragDisabled: !isMultiPanelView, children: (provided, snapshot) => (_createElement("div", { ref: provided.innerRef, ...provided.draggableProps, key: dashboardItem, className: cx('w-full min-h-96', snapshot.isDragging
167
188
  ? 'bg-gray-200 dark:bg-gray-500'
168
- : 'bg-white dark:bg-gray-900') },
169
- _jsx(VisualizationPanel, { handleClosePanel: handleClosePanel, isMultiPanelView: isMultiPanelView, dashboardItem: dashboardItem, getDashboardItemByType: getDashboardItemByType, dragHandleProps: provided.dragHandleProps, index: index }))) }, dashboardItem));
189
+ : 'bg-white dark:bg-gray-900', isMultiPanelView
190
+ ? 'border-2 border-gray-100 dark:border-gray-700 rounded-md p-3'
191
+ : '') },
192
+ _jsx(VisualizationPanel, { handleClosePanel: handleClosePanel, isMultiPanelView: isMultiPanelView, dashboardItem: dashboardItem, getDashboardItemByType: getDashboardItemByType, dragHandleProps: provided.dragHandleProps, index: index, actionButtons: getActionButtonsWithMultiPanelView() }))) }, dashboardItem));
170
193
  }) })) }) }) })] }) }));
171
194
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ProfileViewWithData.d.ts","sourceRoot":"","sources":["../src/ProfileViewWithData.tsx"],"names":[],"mappings":"AAeA,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAK1E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAK9C,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,oCAG7B,wBAAwB,KAAG,GAAG,CAAC,OAmNjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"ProfileViewWithData.d.ts","sourceRoot":"","sources":["../src/ProfileViewWithData.tsx"],"names":[],"mappings":"AAeA,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAK1E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAK9C,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,oCAG7B,wBAAwB,KAAG,GAAG,CAAC,OAiNjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -53,15 +53,13 @@ export const ProfileViewWithData = ({ queryClient, profileSource, }) => {
53
53
  binaryFrameFilter,
54
54
  });
55
55
  const { isLoading: profileMetadataLoading, response: profileMetadataResponse } = useQuery(queryClient, profileSource, QueryRequest_ReportType.PROFILE_METADATA, {
56
- skip: !dashboardItems.includes('icicle'),
57
56
  nodeTrimThreshold,
58
57
  groupBy,
59
- invertCallStack,
60
- binaryFrameFilter: undefined,
61
58
  });
62
59
  const { perf } = useParcaContext();
63
60
  const { isLoading: tableLoading, response: tableResponse, error: tableError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.TABLE_ARROW, {
64
61
  skip: !dashboardItems.includes('table'),
62
+ binaryFrameFilter,
65
63
  });
66
64
  const { isLoading: callgraphLoading, response: callgraphResponse, error: callgraphError, } = useQuery(queryClient, profileSource, QueryRequest_ReportType.CALLGRAPH, {
67
65
  skip: !dashboardItems.includes('callgraph'),
@@ -1,28 +1,6 @@
1
1
  import React from 'react';
2
- import { Vector } from 'apache-arrow';
3
2
  import { ProfileType } from '@parca/parser';
4
- export interface DataRow {
5
- id: number;
6
- name: string;
7
- flat: bigint;
8
- flatDiff: bigint;
9
- cumulative: bigint;
10
- cumulativeDiff: bigint;
11
- mappingFile: string;
12
- functionSystemName: string;
13
- functionFileName: string;
14
- callers?: DataRow[];
15
- callees?: DataRow[];
16
- subRows?: Row[];
17
- isTopSubRow?: boolean;
18
- isBottomSubRow?: boolean;
19
- }
20
- interface DummyRow {
21
- size: number;
22
- message?: string;
23
- isTopSubRow?: boolean;
24
- isBottomSubRow?: boolean;
25
- }
3
+ import { DataRow, DummyRow } from './utils/functions';
26
4
  export type Row = DataRow | DummyRow;
27
5
  export declare const isDummyRow: (row: Row) => row is DummyRow;
28
6
  interface TableProps {
@@ -36,13 +14,8 @@ interface TableProps {
36
14
  setActionButtons?: (buttons: React.JSX.Element) => void;
37
15
  isHalfScreen: boolean;
38
16
  unit?: string;
17
+ metadataMappingFiles?: string[];
39
18
  }
40
- export type ColumnName = 'flat' | 'flatPercentage' | 'flatDiff' | 'flatDiffPercentage' | 'cumulative' | 'cumulativePercentage' | 'cumulativeDiff' | 'cumulativeDiffPercentage' | 'name' | 'functionSystemName' | 'functionFileName' | 'mappingFile';
41
- export declare const getPercentageString: (value: bigint | number, total: bigint | number) => string;
42
- export declare const getRatioString: (value: bigint | number, total: bigint, filtered: bigint) => string;
43
- export declare const possibleColumns: string[];
44
19
  export declare const Table: React.NamedExoticComponent<TableProps>;
45
- export declare const addPlusSign: (num: string) => string;
46
- export declare const RowName: (mappingFileColumn: Vector | null, locationAddressColumn: Vector | null, functionNameColumn: Vector | null, row: number) => string;
47
20
  export default Table;
48
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Table/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAU/E,OAAO,EAAQ,MAAM,EAAgC,MAAM,cAAc,CAAC;AAW1E,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAmB1C,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,MAAM,GAAG,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErC,eAAO,MAAM,UAAU,QAAS,GAAG,KAAG,GAAG,IAAI,QAE5C,CAAC;AAIF,UAAU,UAAU;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,UAAU,GAClB,MAAM,GACN,gBAAgB,GAChB,UAAU,GACV,oBAAoB,GACpB,YAAY,GACZ,sBAAsB,GACtB,gBAAgB,GAChB,0BAA0B,GAC1B,MAAM,GACN,oBAAoB,GACpB,kBAAkB,GAClB,aAAa,CAAC;AA4LlB,eAAO,MAAM,mBAAmB,UAAW,MAAM,GAAG,MAAM,SAAS,MAAM,GAAG,MAAM,KAAG,MAOpF,CAAC;AAEF,eAAO,MAAM,cAAc,UAAW,MAAM,GAAG,MAAM,SAAS,MAAM,YAAY,MAAM,KAAG,MAMxF,CAAC;AAEF,eAAO,MAAM,eAAe,UAa3B,CAAC;AAEF,eAAO,MAAM,KAAK,wCAoZhB,CAAC;AAEH,eAAO,MAAM,WAAW,QAAS,MAAM,KAAG,MAMzC,CAAC;AAEF,eAAO,MAAM,OAAO,sBACC,MAAM,GAAG,IAAI,yBACT,MAAM,GAAG,IAAI,sBAChB,MAAM,GAAG,IAAI,OAC5B,MAAM,KACV,MAoBF,CAAC;AAgDF,eAAe,KAAK,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Table/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAA0D,MAAM,OAAO,CAAC;AAsB/E,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAS1C,OAAO,EAEL,OAAO,EACP,QAAQ,EAgBT,MAAM,mBAAmB,CAAC;AAe3B,MAAM,MAAM,GAAG,GAAG,OAAO,GAAG,QAAQ,CAAC;AAErC,eAAO,MAAM,UAAU,QAAS,GAAG,KAAG,GAAG,IAAI,QAE5C,CAAC;AAIF,UAAU,UAAU;IAClB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;CACjC;AAkID,eAAO,MAAM,KAAK,wCA4chB,CAAC;AAEH,eAAe,KAAK,CAAC"}