@parca/profile 0.16.242 → 0.16.244
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/GraphTooltipArrow/Content.js +1 -1
- package/dist/ProfileExplorer/ProfileExplorerCompare.js +1 -1
- package/dist/ProfileIcicleGraph/index.d.ts +2 -2
- package/dist/ProfileIcicleGraph/index.js +2 -4
- package/dist/ProfileSelector/index.js +1 -1
- package/dist/ProfileView/index.js +5 -1
- package/package.json +2 -2
- package/src/GraphTooltipArrow/Content.tsx +2 -2
- package/src/ProfileExplorer/ProfileExplorerCompare.tsx +11 -9
- package/src/ProfileIcicleGraph/index.tsx +5 -6
- package/src/ProfileSelector/index.tsx +1 -1
- package/src/ProfileView/index.tsx +7 -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.244](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.243...@parca/profile@0.16.244) (2023-09-01)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.16.243](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.242...@parca/profile@0.16.243) (2023-09-01)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## [0.16.242](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.241...@parca/profile@0.16.242) (2023-08-31)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -95,7 +95,7 @@ onCopy, row, navigateTo, }) => {
|
|
|
95
95
|
const labelPairs = labelColumnNames
|
|
96
96
|
.map((field, i) => [
|
|
97
97
|
labelColumnNames[i].name.slice(pprofLabelPrefix.length),
|
|
98
|
-
table.getChild(field.name)?.get(row) ?? '',
|
|
98
|
+
arrowToString(table.getChild(field.name)?.get(row)) ?? '',
|
|
99
99
|
])
|
|
100
100
|
.filter(value => value[1] !== '');
|
|
101
101
|
const labels = labelPairs.map((l) => (_jsx("span", { className: "mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400", children: `${l[0]}="${l[1]}"` }, l[0])));
|
|
@@ -10,6 +10,6 @@ const ProfileExplorerCompare = ({ queryClient, queryA, queryB, profileA, profile
|
|
|
10
10
|
const closeProfileB = () => {
|
|
11
11
|
closeProfile('B');
|
|
12
12
|
};
|
|
13
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex justify-between gap-2", children: [_jsx(Card, { className: "mt-2 p-2", children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryA, profileSelection: profileA, selectProfile: selectProfileA, selectQuery: selectQueryA, closeProfile: closeProfileA, enforcedProfileName: '', comparing: true, onCompareProfile: () => { } }) }), _jsx(Card, { className: "mt-2 p-2", children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryB, profileSelection: profileB, selectProfile: selectProfileB, selectQuery: selectQueryB, closeProfile: closeProfileB, enforcedProfileName: Query.parse(queryA.expression).profileName(), comparing: true, onCompareProfile: () => { } }) })] }), _jsx("div", { className: "grid grid-cols-1", children: profileA != null && profileB != null ? (_jsx(Card, { className: "mt-2 px-6 py-4", children: _jsx(ProfileViewWithData, { navigateTo: navigateTo, queryClient: queryClient, profileSource: new ProfileDiffSource(profileA.ProfileSource(), profileB.ProfileSource()) }) })) : (_jsx("div", { children: _jsx("div", { className: "my-20 text-center", children: _jsx("p", { children: "Select a profile on both sides." }) }) })) })] }));
|
|
13
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex justify-between gap-2", children: [_jsx(Card, { className: "mt-2 p-2", children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryA, profileSelection: profileA, selectProfile: selectProfileA, selectQuery: selectQueryA, closeProfile: closeProfileA, enforcedProfileName: '', comparing: true, onCompareProfile: () => { } }) }), _jsx(Card, { className: "mt-2 p-2", children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryB, profileSelection: profileB, selectProfile: selectProfileB, selectQuery: selectQueryB, closeProfile: closeProfileB, enforcedProfileName: Query.parse(queryA.expression).profileName(), comparing: true, onCompareProfile: () => { } }) })] }), _jsx("div", { className: "grid grid-cols-1", children: profileA != null && profileB != null ? (_jsx("div", { children: _jsx(Card, { className: "mt-2 px-6 py-4", children: _jsx(ProfileViewWithData, { navigateTo: navigateTo, queryClient: queryClient, profileSource: new ProfileDiffSource(profileA.ProfileSource(), profileB.ProfileSource()) }) }) })) : (_jsx("div", { children: _jsx("div", { className: "my-20 text-center", children: _jsx("p", { children: "Select a profile on both sides." }) }) })) })] }));
|
|
14
14
|
};
|
|
15
15
|
export default ProfileExplorerCompare;
|
|
@@ -4,7 +4,7 @@ import { Flamegraph } from '@parca/client';
|
|
|
4
4
|
import { type NavigateFunction } from '@parca/utilities';
|
|
5
5
|
export type ResizeHandler = (width: number, height: number) => void;
|
|
6
6
|
interface ProfileIcicleGraphProps {
|
|
7
|
-
width
|
|
7
|
+
width: number;
|
|
8
8
|
graph?: Flamegraph;
|
|
9
9
|
table?: Table<any>;
|
|
10
10
|
total: bigint;
|
|
@@ -17,5 +17,5 @@ interface ProfileIcicleGraphProps {
|
|
|
17
17
|
setActionButtons?: (buttons: React.JSX.Element) => void;
|
|
18
18
|
error?: any;
|
|
19
19
|
}
|
|
20
|
-
declare const ProfileIcicleGraph: ({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, }: ProfileIcicleGraphProps) => JSX.Element;
|
|
20
|
+
declare const ProfileIcicleGraph: ({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, }: ProfileIcicleGraphProps) => JSX.Element;
|
|
21
21
|
export default ProfileIcicleGraph;
|
|
@@ -15,7 +15,6 @@ import { Fragment, useCallback, useEffect, useMemo } from 'react';
|
|
|
15
15
|
import { Menu, Transition } from '@headlessui/react';
|
|
16
16
|
import { Icon } from '@iconify/react';
|
|
17
17
|
import { Button, Select, useParcaContext, useURLState } from '@parca/components';
|
|
18
|
-
import { useContainerDimensions } from '@parca/hooks';
|
|
19
18
|
import { divide, selectQueryParam } from '@parca/utilities';
|
|
20
19
|
import DiffLegend from '../components/DiffLegend';
|
|
21
20
|
import IcicleGraph from './IcicleGraph';
|
|
@@ -50,10 +49,9 @@ const GroupAndSortActionButtons = ({ navigateTo }) => {
|
|
|
50
49
|
}, [groupBy, setGroupBy]);
|
|
51
50
|
return (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy }), _jsx(SortBySelect, { compareMode: compareMode, sortBy: storeSortBy, setSortBy: setStoreSortBy })] }));
|
|
52
51
|
};
|
|
53
|
-
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, }) {
|
|
52
|
+
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, }) {
|
|
54
53
|
const { loader } = useParcaContext();
|
|
55
54
|
const compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
56
|
-
const { ref, dimensions } = useContainerDimensions();
|
|
57
55
|
const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
|
|
58
56
|
param: 'sort_by',
|
|
59
57
|
navigateTo,
|
|
@@ -97,7 +95,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, to
|
|
|
97
95
|
if (isTrimmed) {
|
|
98
96
|
console.info(`Trimmed ${trimmedFormatted} (${trimmedPercentage}%) too small values.`);
|
|
99
97
|
}
|
|
100
|
-
return (_jsxs("div", { className: "relative", children: [compareMode && _jsx(DiffLegend, {}), _jsxs("div", {
|
|
98
|
+
return (_jsxs("div", { className: "relative", children: [compareMode && _jsx(DiffLegend, {}), _jsxs("div", { className: "min-h-48", children: [graph !== undefined && (_jsx(IcicleGraph, { width: width, graph: graph, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo })), table !== undefined && (_jsx(IcicleGraphArrow, { width: width, table: table, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, sampleUnit: sampleUnit, navigateTo: navigateTo, sortBy: storeSortBy }))] }), _jsxs("p", { className: "my-2 text-xs", children: ["Showing ", totalFormatted, ' ', isFiltered ? (_jsxs("span", { children: ["(", filteredPercentage, "%) filtered of ", totalUnfilteredFormatted, ' '] })) : (_jsx(_Fragment, {})), "values.", ' '] })] }));
|
|
101
99
|
};
|
|
102
100
|
const groupByOptions = [
|
|
103
101
|
{
|
|
@@ -119,7 +119,7 @@ const ProfileSelector = ({ queryClient, querySelection, selectProfile, selectQue
|
|
|
119
119
|
queryExpressionString === '' ||
|
|
120
120
|
queryExpressionString === '{}';
|
|
121
121
|
const compareDisabled = selectedProfileName === '' || querySelection.expression === undefined;
|
|
122
|
-
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mb-2 flex", children: [_jsxs("div", { className: "flex w-full flex-wrap content-start items-end justify-between gap-2", children: [_jsxs("div", { children: [_jsx("label", { className: "text-xs", children: "Profile type" }), _jsx(ProfileTypeSelector, { profileTypesData: profileTypesData, loading: profileTypesLoading, selectedKey: selectedProfileName, onSelection: setProfileName, error: error })] }), _jsxs("div", { className: "w-full flex-1", children: [_jsx("label", { className: "text-xs", children: "Query" }), _jsx(MatchersInput, { queryClient: queryClient, setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query })] }), _jsxs("div", { children: [_jsx("label", { className: "text-xs", children: "Period" }), _jsx(DateTimeRangePicker, { onRangeSelection: setTimeRangeSelection, range: timeRangeSelection })] }), _jsxs(ButtonGroup, { children: [!searchDisabled && (_jsx(_Fragment, { children: !comparing && (_jsx(CompareButton, { disabled: compareDisabled, onClick: handleCompareClick })) })), _jsx(Button, { disabled: searchDisabled, onClick: (e) => {
|
|
122
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "mb-2 flex gap-2", children: [_jsxs("div", { className: "flex w-full flex-wrap content-start items-end justify-between gap-2", children: [_jsxs("div", { children: [_jsx("label", { className: "text-xs", children: "Profile type" }), _jsx(ProfileTypeSelector, { profileTypesData: profileTypesData, loading: profileTypesLoading, selectedKey: selectedProfileName, onSelection: setProfileName, error: error })] }), _jsxs("div", { className: "w-full flex-1", children: [_jsx("label", { className: "text-xs", children: "Query" }), _jsx(MatchersInput, { queryClient: queryClient, setMatchersString: setMatchersString, runQuery: setQueryExpression, currentQuery: query })] }), _jsxs("div", { children: [_jsx("label", { className: "text-xs", children: "Period" }), _jsx(DateTimeRangePicker, { onRangeSelection: setTimeRangeSelection, range: timeRangeSelection })] }), _jsxs(ButtonGroup, { children: [!searchDisabled && (_jsx(_Fragment, { children: !comparing && (_jsx(CompareButton, { disabled: compareDisabled, onClick: handleCompareClick })) })), _jsx(Button, { disabled: searchDisabled, onClick: (e) => {
|
|
123
123
|
e.preventDefault();
|
|
124
124
|
setQueryExpression();
|
|
125
125
|
}, children: "Search" })] })] }), _jsx("div", { children: comparing && _jsx(IconButton, { onClick: () => closeProfile(), icon: _jsx(CloseIcon, {}) }) })] }), _jsx("div", { className: "rounded bg-white shadow dark:border-gray-500 dark:bg-gray-700", children: _jsx("div", { style: { height: heightStyle }, children: querySelection.expression !== undefined &&
|
|
@@ -130,7 +130,11 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
|
|
|
130
130
|
return (_jsx(ConditionalWrapper, { condition: perf?.onRender != null, WrapperComponent: Profiler, wrapperProps: {
|
|
131
131
|
id: 'icicleGraph',
|
|
132
132
|
onRender: perf?.onRender,
|
|
133
|
-
}, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, table: flamegraphData?.table, graph: flamegraphData?.data, total: total, filtered: filtered, sampleUnit: sampleUnit, navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons, error: flamegraphData.error
|
|
133
|
+
}, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, table: flamegraphData?.table, graph: flamegraphData?.data, total: total, filtered: filtered, sampleUnit: sampleUnit, navigateTo: navigateTo, loading: flamegraphData.loading, setActionButtons: setActionButtons, error: flamegraphData.error, width: dimensions?.width !== undefined
|
|
134
|
+
? isHalfScreen
|
|
135
|
+
? (dimensions.width - 40) / 2
|
|
136
|
+
: dimensions.width - 16
|
|
137
|
+
: 0 }) }));
|
|
134
138
|
}
|
|
135
139
|
case 'callgraph': {
|
|
136
140
|
return callgraphData?.data !== undefined &&
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.244",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@parca/client": "^0.16.86",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"access": "public",
|
|
50
50
|
"registry": "https://registry.npmjs.org/"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "cad92c30fc37a648d8989db61aaa8165b1db4028"
|
|
53
53
|
}
|
|
@@ -238,7 +238,7 @@ const TooltipMetaInfo = ({
|
|
|
238
238
|
const labelPairs = labelColumnNames
|
|
239
239
|
.map((field, i) => [
|
|
240
240
|
labelColumnNames[i].name.slice(pprofLabelPrefix.length),
|
|
241
|
-
table.getChild(field.name)?.get(row) ?? '',
|
|
241
|
+
arrowToString(table.getChild(field.name)?.get(row)) ?? '',
|
|
242
242
|
])
|
|
243
243
|
.filter(value => value[1] !== '');
|
|
244
244
|
const labels = labelPairs.map(
|
|
@@ -247,7 +247,7 @@ const TooltipMetaInfo = ({
|
|
|
247
247
|
key={l[0]}
|
|
248
248
|
className="mr-3 inline-block rounded-lg bg-gray-200 px-2 py-1 text-xs font-bold text-gray-700 dark:bg-gray-700 dark:text-gray-400"
|
|
249
249
|
>
|
|
250
|
-
{`${l[0]
|
|
250
|
+
{`${l[0]}="${l[1]}"`}
|
|
251
251
|
</span>
|
|
252
252
|
)
|
|
253
253
|
);
|
|
@@ -88,15 +88,17 @@ const ProfileExplorerCompare = ({
|
|
|
88
88
|
</div>
|
|
89
89
|
<div className="grid grid-cols-1">
|
|
90
90
|
{profileA != null && profileB != null ? (
|
|
91
|
-
<
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
91
|
+
<div>
|
|
92
|
+
<Card className="mt-2 px-6 py-4">
|
|
93
|
+
<ProfileViewWithData
|
|
94
|
+
navigateTo={navigateTo}
|
|
95
|
+
queryClient={queryClient}
|
|
96
|
+
profileSource={
|
|
97
|
+
new ProfileDiffSource(profileA.ProfileSource(), profileB.ProfileSource())
|
|
98
|
+
}
|
|
99
|
+
/>
|
|
100
|
+
</Card>
|
|
101
|
+
</div>
|
|
100
102
|
) : (
|
|
101
103
|
<div>
|
|
102
104
|
<div className="my-20 text-center">
|
|
@@ -19,7 +19,6 @@ import {Table} from 'apache-arrow';
|
|
|
19
19
|
|
|
20
20
|
import {Flamegraph} from '@parca/client';
|
|
21
21
|
import {Button, Select, useParcaContext, useURLState} from '@parca/components';
|
|
22
|
-
import {useContainerDimensions} from '@parca/hooks';
|
|
23
22
|
import {divide, selectQueryParam, type NavigateFunction} from '@parca/utilities';
|
|
24
23
|
|
|
25
24
|
import DiffLegend from '../components/DiffLegend';
|
|
@@ -36,7 +35,7 @@ const numberFormatter = new Intl.NumberFormat('en-US');
|
|
|
36
35
|
export type ResizeHandler = (width: number, height: number) => void;
|
|
37
36
|
|
|
38
37
|
interface ProfileIcicleGraphProps {
|
|
39
|
-
width
|
|
38
|
+
width: number;
|
|
40
39
|
graph?: Flamegraph;
|
|
41
40
|
table?: Table<any>;
|
|
42
41
|
total: bigint;
|
|
@@ -113,11 +112,11 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
113
112
|
loading,
|
|
114
113
|
setActionButtons,
|
|
115
114
|
error,
|
|
115
|
+
width,
|
|
116
116
|
}: ProfileIcicleGraphProps): JSX.Element {
|
|
117
117
|
const {loader} = useParcaContext();
|
|
118
118
|
const compareMode: boolean =
|
|
119
119
|
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
120
|
-
const {ref, dimensions} = useContainerDimensions();
|
|
121
120
|
|
|
122
121
|
const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
|
|
123
122
|
param: 'sort_by',
|
|
@@ -200,10 +199,10 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
200
199
|
return (
|
|
201
200
|
<div className="relative">
|
|
202
201
|
{compareMode && <DiffLegend />}
|
|
203
|
-
<div
|
|
202
|
+
<div className="min-h-48">
|
|
204
203
|
{graph !== undefined && (
|
|
205
204
|
<IcicleGraph
|
|
206
|
-
width={
|
|
205
|
+
width={width}
|
|
207
206
|
graph={graph}
|
|
208
207
|
total={total}
|
|
209
208
|
filtered={filtered}
|
|
@@ -215,7 +214,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
215
214
|
)}
|
|
216
215
|
{table !== undefined && (
|
|
217
216
|
<IcicleGraphArrow
|
|
218
|
-
width={
|
|
217
|
+
width={width}
|
|
219
218
|
table={table}
|
|
220
219
|
total={total}
|
|
221
220
|
filtered={filtered}
|
|
@@ -199,7 +199,7 @@ const ProfileSelector = ({
|
|
|
199
199
|
|
|
200
200
|
return (
|
|
201
201
|
<>
|
|
202
|
-
<div className="mb-2 flex">
|
|
202
|
+
<div className="mb-2 flex gap-2">
|
|
203
203
|
<div className="flex w-full flex-wrap content-start items-end justify-between gap-2">
|
|
204
204
|
<div>
|
|
205
205
|
<label className="text-xs">Profile type</label>
|
|
@@ -267,6 +267,13 @@ export const ProfileView = ({
|
|
|
267
267
|
loading={flamegraphData.loading}
|
|
268
268
|
setActionButtons={setActionButtons}
|
|
269
269
|
error={flamegraphData.error}
|
|
270
|
+
width={
|
|
271
|
+
dimensions?.width !== undefined
|
|
272
|
+
? isHalfScreen
|
|
273
|
+
? (dimensions.width - 40) / 2
|
|
274
|
+
: dimensions.width - 16
|
|
275
|
+
: 0
|
|
276
|
+
}
|
|
270
277
|
/>
|
|
271
278
|
</ConditionalWrapper>
|
|
272
279
|
);
|