@parca/profile 0.16.243 → 0.16.245
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +2 -2
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +5 -1
- package/dist/ProfileIcicleGraph/index.d.ts +4 -5
- package/dist/ProfileIcicleGraph/index.js +8 -11
- package/dist/ProfileView/index.d.ts +2 -3
- package/dist/ProfileView/index.js +5 -1
- package/dist/ProfileViewWithData.js +2 -3
- package/package.json +2 -2
- package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +8 -3
- package/src/ProfileIcicleGraph/index.tsx +16 -19
- package/src/ProfileView/index.tsx +10 -3
- package/src/ProfileViewWithData.tsx +2 -2
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.245](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.244...@parca/profile@0.16.245) (2023-09-01)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.16.244](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.243...@parca/profile@0.16.244) (2023-09-01)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## [0.16.243](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.242...@parca/profile@0.16.243) (2023-09-01)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { FlamegraphArrow } from '@parca/client';
|
|
3
3
|
import { type NavigateFunction } from '@parca/utilities';
|
|
4
4
|
export declare const FIELD_LABELS_ONLY = "labels_only";
|
|
5
5
|
export declare const FIELD_MAPPING_FILE = "mapping_file";
|
|
@@ -14,7 +14,7 @@ export declare const FIELD_LABELS = "labels";
|
|
|
14
14
|
export declare const FIELD_CUMULATIVE = "cumulative";
|
|
15
15
|
export declare const FIELD_DIFF = "diff";
|
|
16
16
|
interface IcicleGraphArrowProps {
|
|
17
|
-
|
|
17
|
+
arrow: FlamegraphArrow;
|
|
18
18
|
total: bigint;
|
|
19
19
|
filtered: bigint;
|
|
20
20
|
sampleUnit: string;
|
|
@@ -12,6 +12,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
|
|
|
12
12
|
// See the License for the specific language governing permissions and
|
|
13
13
|
// limitations under the License.
|
|
14
14
|
import { memo, useEffect, useMemo, useRef, useState } from 'react';
|
|
15
|
+
import { tableFromIPC } from 'apache-arrow';
|
|
15
16
|
import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
|
|
16
17
|
import { getColorForFeature, selectDarkMode, setHoveringNode, useAppDispatch, useAppSelector, } from '@parca/store';
|
|
17
18
|
import { getLastItem, scaleLinear, selectQueryParam, } from '@parca/utilities';
|
|
@@ -32,10 +33,13 @@ export const FIELD_CHILDREN = 'children';
|
|
|
32
33
|
export const FIELD_LABELS = 'labels';
|
|
33
34
|
export const FIELD_CUMULATIVE = 'cumulative';
|
|
34
35
|
export const FIELD_DIFF = 'diff';
|
|
35
|
-
export const IcicleGraphArrow = memo(function IcicleGraphArrow({
|
|
36
|
+
export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, filtered, width, setCurPath, curPath, sampleUnit, navigateTo, sortBy, }) {
|
|
36
37
|
const dispatch = useAppDispatch();
|
|
37
38
|
const [colorProfile] = useUserPreference(USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key);
|
|
38
39
|
const isDarkMode = useAppSelector(selectDarkMode);
|
|
40
|
+
const table = useMemo(() => {
|
|
41
|
+
return tableFromIPC(arrow.record);
|
|
42
|
+
}, [arrow]);
|
|
39
43
|
const [height, setHeight] = useState(0);
|
|
40
44
|
const [hoveringRow, setHoveringRow] = useState(null);
|
|
41
45
|
const [hoveringLevel, setHoveringLevel] = useState(null);
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
3
|
-
import { Flamegraph } from '@parca/client';
|
|
2
|
+
import { Flamegraph, FlamegraphArrow } from '@parca/client';
|
|
4
3
|
import { type NavigateFunction } from '@parca/utilities';
|
|
5
4
|
export type ResizeHandler = (width: number, height: number) => void;
|
|
6
5
|
interface ProfileIcicleGraphProps {
|
|
7
|
-
width
|
|
6
|
+
width: number;
|
|
8
7
|
graph?: Flamegraph;
|
|
9
|
-
|
|
8
|
+
arrow?: FlamegraphArrow;
|
|
10
9
|
total: bigint;
|
|
11
10
|
filtered: bigint;
|
|
12
11
|
sampleUnit: string;
|
|
@@ -17,5 +16,5 @@ interface ProfileIcicleGraphProps {
|
|
|
17
16
|
setActionButtons?: (buttons: React.JSX.Element) => void;
|
|
18
17
|
error?: any;
|
|
19
18
|
}
|
|
20
|
-
declare const ProfileIcicleGraph: ({ graph,
|
|
19
|
+
declare const ProfileIcicleGraph: ({ graph, arrow, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, }: ProfileIcicleGraphProps) => JSX.Element;
|
|
21
20
|
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,20 +49,18 @@ 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,
|
|
52
|
+
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, 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,
|
|
60
58
|
});
|
|
61
59
|
const [totalFormatted, totalUnfilteredFormatted, isTrimmed, trimmedFormatted, trimmedPercentage, isFiltered, filteredPercentage,] = useMemo(() => {
|
|
62
|
-
if (graph === undefined) {
|
|
60
|
+
if (graph === undefined && arrow === undefined) {
|
|
63
61
|
return ['0', '0', false, '0', '0', false, '0', '0'];
|
|
64
62
|
}
|
|
65
|
-
|
|
66
|
-
const trimmed = 0n;
|
|
63
|
+
const trimmed = graph?.trimmed ?? arrow?.trimmed ?? 0n;
|
|
67
64
|
const totalUnfiltered = total + filtered;
|
|
68
65
|
// safeguard against division by zero
|
|
69
66
|
const totalUnfilteredDivisor = totalUnfiltered > 0 ? totalUnfiltered : 1n;
|
|
@@ -76,13 +73,13 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, to
|
|
|
76
73
|
filtered > 0,
|
|
77
74
|
numberFormatter.format(divide(total * 100n, totalUnfilteredDivisor)),
|
|
78
75
|
];
|
|
79
|
-
}, [graph, filtered, total]);
|
|
76
|
+
}, [graph, arrow, filtered, total]);
|
|
80
77
|
useEffect(() => {
|
|
81
78
|
if (setActionButtons === undefined) {
|
|
82
79
|
return;
|
|
83
80
|
}
|
|
84
|
-
setActionButtons(_jsx("div", { className: "flex w-full justify-end gap-2 pb-2", children: _jsxs("div", { className: "ml-2 flex w-full items-end justify-between gap-2", children: [
|
|
85
|
-
}, [navigateTo,
|
|
81
|
+
setActionButtons(_jsx("div", { className: "flex w-full justify-end gap-2 pb-2", children: _jsxs("div", { className: "ml-2 flex w-full items-end justify-between gap-2", children: [arrow !== undefined && _jsx(GroupAndSortActionButtons, { navigateTo: navigateTo }), _jsx("div", { children: _jsx(Button, { color: "neutral", onClick: () => setNewCurPath([]), disabled: curPath.length === 0, variant: "neutral", children: "Reset View" }) })] }) }));
|
|
82
|
+
}, [navigateTo, arrow, curPath, setNewCurPath, setActionButtons]);
|
|
86
83
|
if (loading) {
|
|
87
84
|
return _jsx("div", { className: "h-96", children: loader });
|
|
88
85
|
}
|
|
@@ -90,14 +87,14 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, to
|
|
|
90
87
|
console.error('Error: ', error);
|
|
91
88
|
return _jsxs("div", { className: "flex justify-center p-10", children: ["An error occurred: ", error.message] });
|
|
92
89
|
}
|
|
93
|
-
if (graph === undefined &&
|
|
90
|
+
if (graph === undefined && arrow === undefined)
|
|
94
91
|
return _jsx("div", { className: "mx-auto text-center", children: "No data..." });
|
|
95
92
|
if (total === 0n && !loading)
|
|
96
93
|
return _jsx("div", { className: "mx-auto text-center", children: "Profile has no samples" });
|
|
97
94
|
if (isTrimmed) {
|
|
98
95
|
console.info(`Trimmed ${trimmedFormatted} (${trimmedPercentage}%) too small values.`);
|
|
99
96
|
}
|
|
100
|
-
return (_jsxs("div", { className: "relative", children: [compareMode && _jsx(DiffLegend, {}), _jsxs("div", {
|
|
97
|
+
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 })), arrow !== undefined && (_jsx(IcicleGraphArrow, { width: width, arrow: arrow, 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
98
|
};
|
|
102
99
|
const groupByOptions = [
|
|
103
100
|
{
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Callgraph as CallgraphType, Flamegraph, QueryServiceClient, Source, TableArrow, Top } from '@parca/client';
|
|
1
|
+
import { Callgraph as CallgraphType, Flamegraph, FlamegraphArrow, QueryServiceClient, Source, TableArrow, Top } from '@parca/client';
|
|
3
2
|
import { ProfileSource } from '../ProfileSource';
|
|
4
3
|
type NavigateFunction = (path: string, queryParams: any, options?: {
|
|
5
4
|
replace?: boolean;
|
|
@@ -7,7 +6,7 @@ type NavigateFunction = (path: string, queryParams: any, options?: {
|
|
|
7
6
|
export interface FlamegraphData {
|
|
8
7
|
loading: boolean;
|
|
9
8
|
data?: Flamegraph;
|
|
10
|
-
|
|
9
|
+
arrow?: FlamegraphArrow;
|
|
11
10
|
total?: bigint;
|
|
12
11
|
filtered?: bigint;
|
|
13
12
|
error?: any;
|
|
@@ -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,
|
|
133
|
+
}, children: _jsx(ProfileIcicleGraph, { curPath: curPath, setNewCurPath: setNewCurPath, arrow: flamegraphData?.arrow, 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 &&
|
|
@@ -12,7 +12,6 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
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 { QueryRequest_ReportType } from '@parca/client';
|
|
17
16
|
import { useGrpcMetadata, useParcaContext, useURLState } from '@parca/components';
|
|
18
17
|
import { USER_PREFERENCES, useUIFeatureFlag, useUserPreference } from '@parca/hooks';
|
|
@@ -129,8 +128,8 @@ export const ProfileViewWithData = ({ queryClient, profileSource, navigateTo, })
|
|
|
129
128
|
data: flamegraphResponse?.report.oneofKind === 'flamegraph'
|
|
130
129
|
? flamegraphResponse?.report?.flamegraph
|
|
131
130
|
: undefined,
|
|
132
|
-
|
|
133
|
-
?
|
|
131
|
+
arrow: flamegraphResponse?.report.oneofKind === 'flamegraphArrow'
|
|
132
|
+
? flamegraphResponse?.report?.flamegraphArrow
|
|
134
133
|
: undefined,
|
|
135
134
|
total: BigInt(flamegraphResponse?.total ?? '0'),
|
|
136
135
|
filtered: BigInt(flamegraphResponse?.filtered ?? '0'),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.245",
|
|
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": "6f9a132da7b7598c0aed2854f6c525f8ee97d67b"
|
|
53
53
|
}
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
|
|
14
14
|
import React, {memo, useEffect, useMemo, useRef, useState} from 'react';
|
|
15
15
|
|
|
16
|
-
import {Dictionary, Table, Vector} from 'apache-arrow';
|
|
16
|
+
import {Dictionary, Table, Vector, tableFromIPC} from 'apache-arrow';
|
|
17
17
|
|
|
18
|
+
import {FlamegraphArrow} from '@parca/client';
|
|
18
19
|
import {USER_PREFERENCES, useUserPreference} from '@parca/hooks';
|
|
19
20
|
import {
|
|
20
21
|
getColorForFeature,
|
|
@@ -51,7 +52,7 @@ export const FIELD_CUMULATIVE = 'cumulative';
|
|
|
51
52
|
export const FIELD_DIFF = 'diff';
|
|
52
53
|
|
|
53
54
|
interface IcicleGraphArrowProps {
|
|
54
|
-
|
|
55
|
+
arrow: FlamegraphArrow;
|
|
55
56
|
total: bigint;
|
|
56
57
|
filtered: bigint;
|
|
57
58
|
sampleUnit: string;
|
|
@@ -63,7 +64,7 @@ interface IcicleGraphArrowProps {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
export const IcicleGraphArrow = memo(function IcicleGraphArrow({
|
|
66
|
-
|
|
67
|
+
arrow,
|
|
67
68
|
total,
|
|
68
69
|
filtered,
|
|
69
70
|
width,
|
|
@@ -79,6 +80,10 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({
|
|
|
79
80
|
);
|
|
80
81
|
const isDarkMode = useAppSelector(selectDarkMode);
|
|
81
82
|
|
|
83
|
+
const table: Table<any> = useMemo(() => {
|
|
84
|
+
return tableFromIPC(arrow.record);
|
|
85
|
+
}, [arrow]);
|
|
86
|
+
|
|
82
87
|
const [height, setHeight] = useState(0);
|
|
83
88
|
const [hoveringRow, setHoveringRow] = useState<number | null>(null);
|
|
84
89
|
const [hoveringLevel, setHoveringLevel] = useState<number | null>(null);
|
|
@@ -15,11 +15,9 @@ import React, {Fragment, useCallback, useEffect, useMemo} from 'react';
|
|
|
15
15
|
|
|
16
16
|
import {Menu, Transition} from '@headlessui/react';
|
|
17
17
|
import {Icon} from '@iconify/react';
|
|
18
|
-
import {Table} from 'apache-arrow';
|
|
19
18
|
|
|
20
|
-
import {Flamegraph} from '@parca/client';
|
|
19
|
+
import {Flamegraph, FlamegraphArrow} from '@parca/client';
|
|
21
20
|
import {Button, Select, useParcaContext, useURLState} from '@parca/components';
|
|
22
|
-
import {useContainerDimensions} from '@parca/hooks';
|
|
23
21
|
import {divide, selectQueryParam, type NavigateFunction} from '@parca/utilities';
|
|
24
22
|
|
|
25
23
|
import DiffLegend from '../components/DiffLegend';
|
|
@@ -36,9 +34,9 @@ const numberFormatter = new Intl.NumberFormat('en-US');
|
|
|
36
34
|
export type ResizeHandler = (width: number, height: number) => void;
|
|
37
35
|
|
|
38
36
|
interface ProfileIcicleGraphProps {
|
|
39
|
-
width
|
|
37
|
+
width: number;
|
|
40
38
|
graph?: Flamegraph;
|
|
41
|
-
|
|
39
|
+
arrow?: FlamegraphArrow;
|
|
42
40
|
total: bigint;
|
|
43
41
|
filtered: bigint;
|
|
44
42
|
sampleUnit: string;
|
|
@@ -103,7 +101,7 @@ const GroupAndSortActionButtons = ({navigateTo}: {navigateTo?: NavigateFunction}
|
|
|
103
101
|
|
|
104
102
|
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
105
103
|
graph,
|
|
106
|
-
|
|
104
|
+
arrow,
|
|
107
105
|
total,
|
|
108
106
|
filtered,
|
|
109
107
|
curPath,
|
|
@@ -113,11 +111,11 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
113
111
|
loading,
|
|
114
112
|
setActionButtons,
|
|
115
113
|
error,
|
|
114
|
+
width,
|
|
116
115
|
}: ProfileIcicleGraphProps): JSX.Element {
|
|
117
116
|
const {loader} = useParcaContext();
|
|
118
117
|
const compareMode: boolean =
|
|
119
118
|
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
120
|
-
const {ref, dimensions} = useContainerDimensions();
|
|
121
119
|
|
|
122
120
|
const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
|
|
123
121
|
param: 'sort_by',
|
|
@@ -133,12 +131,11 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
133
131
|
isFiltered,
|
|
134
132
|
filteredPercentage,
|
|
135
133
|
] = useMemo(() => {
|
|
136
|
-
if (graph === undefined) {
|
|
134
|
+
if (graph === undefined && arrow === undefined) {
|
|
137
135
|
return ['0', '0', false, '0', '0', false, '0', '0'];
|
|
138
136
|
}
|
|
139
137
|
|
|
140
|
-
|
|
141
|
-
const trimmed = 0n;
|
|
138
|
+
const trimmed: bigint = graph?.trimmed ?? arrow?.trimmed ?? 0n;
|
|
142
139
|
|
|
143
140
|
const totalUnfiltered = total + filtered;
|
|
144
141
|
// safeguard against division by zero
|
|
@@ -153,7 +150,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
153
150
|
filtered > 0,
|
|
154
151
|
numberFormatter.format(divide(total * 100n, totalUnfilteredDivisor)),
|
|
155
152
|
];
|
|
156
|
-
}, [graph, filtered, total]);
|
|
153
|
+
}, [graph, arrow, filtered, total]);
|
|
157
154
|
|
|
158
155
|
useEffect(() => {
|
|
159
156
|
if (setActionButtons === undefined) {
|
|
@@ -162,7 +159,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
162
159
|
setActionButtons(
|
|
163
160
|
<div className="flex w-full justify-end gap-2 pb-2">
|
|
164
161
|
<div className="ml-2 flex w-full items-end justify-between gap-2">
|
|
165
|
-
{
|
|
162
|
+
{arrow !== undefined && <GroupAndSortActionButtons navigateTo={navigateTo} />}
|
|
166
163
|
<div>
|
|
167
164
|
<Button
|
|
168
165
|
color="neutral"
|
|
@@ -176,7 +173,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
176
173
|
</div>
|
|
177
174
|
</div>
|
|
178
175
|
);
|
|
179
|
-
}, [navigateTo,
|
|
176
|
+
}, [navigateTo, arrow, curPath, setNewCurPath, setActionButtons]);
|
|
180
177
|
|
|
181
178
|
if (loading) {
|
|
182
179
|
return <div className="h-96">{loader}</div>;
|
|
@@ -187,7 +184,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
187
184
|
return <div className="flex justify-center p-10">An error occurred: {error.message}</div>;
|
|
188
185
|
}
|
|
189
186
|
|
|
190
|
-
if (graph === undefined &&
|
|
187
|
+
if (graph === undefined && arrow === undefined)
|
|
191
188
|
return <div className="mx-auto text-center">No data...</div>;
|
|
192
189
|
|
|
193
190
|
if (total === 0n && !loading)
|
|
@@ -200,10 +197,10 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
200
197
|
return (
|
|
201
198
|
<div className="relative">
|
|
202
199
|
{compareMode && <DiffLegend />}
|
|
203
|
-
<div
|
|
200
|
+
<div className="min-h-48">
|
|
204
201
|
{graph !== undefined && (
|
|
205
202
|
<IcicleGraph
|
|
206
|
-
width={
|
|
203
|
+
width={width}
|
|
207
204
|
graph={graph}
|
|
208
205
|
total={total}
|
|
209
206
|
filtered={filtered}
|
|
@@ -213,10 +210,10 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
213
210
|
navigateTo={navigateTo}
|
|
214
211
|
/>
|
|
215
212
|
)}
|
|
216
|
-
{
|
|
213
|
+
{arrow !== undefined && (
|
|
217
214
|
<IcicleGraphArrow
|
|
218
|
-
width={
|
|
219
|
-
|
|
215
|
+
width={width}
|
|
216
|
+
arrow={arrow}
|
|
220
217
|
total={total}
|
|
221
218
|
filtered={filtered}
|
|
222
219
|
curPath={curPath}
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
import {Profiler, ProfilerProps, useEffect, useMemo, useState} from 'react';
|
|
15
15
|
|
|
16
16
|
import {Icon} from '@iconify/react';
|
|
17
|
-
import {Table as ArrowTable} from 'apache-arrow';
|
|
18
17
|
import cx from 'classnames';
|
|
19
18
|
import {scaleLinear} from 'd3';
|
|
20
19
|
import graphviz from 'graphviz-wasm';
|
|
@@ -29,6 +28,7 @@ import {
|
|
|
29
28
|
import {
|
|
30
29
|
Callgraph as CallgraphType,
|
|
31
30
|
Flamegraph,
|
|
31
|
+
FlamegraphArrow,
|
|
32
32
|
QueryServiceClient,
|
|
33
33
|
Source,
|
|
34
34
|
TableArrow,
|
|
@@ -64,7 +64,7 @@ type NavigateFunction = (path: string, queryParams: any, options?: {replace?: bo
|
|
|
64
64
|
export interface FlamegraphData {
|
|
65
65
|
loading: boolean;
|
|
66
66
|
data?: Flamegraph;
|
|
67
|
-
|
|
67
|
+
arrow?: FlamegraphArrow;
|
|
68
68
|
total?: bigint;
|
|
69
69
|
filtered?: bigint;
|
|
70
70
|
error?: any;
|
|
@@ -258,7 +258,7 @@ export const ProfileView = ({
|
|
|
258
258
|
<ProfileIcicleGraph
|
|
259
259
|
curPath={curPath}
|
|
260
260
|
setNewCurPath={setNewCurPath}
|
|
261
|
-
|
|
261
|
+
arrow={flamegraphData?.arrow}
|
|
262
262
|
graph={flamegraphData?.data}
|
|
263
263
|
total={total}
|
|
264
264
|
filtered={filtered}
|
|
@@ -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
|
);
|
|
@@ -184,9 +184,9 @@ export const ProfileViewWithData = ({
|
|
|
184
184
|
flamegraphResponse?.report.oneofKind === 'flamegraph'
|
|
185
185
|
? flamegraphResponse?.report?.flamegraph
|
|
186
186
|
: undefined,
|
|
187
|
-
|
|
187
|
+
arrow:
|
|
188
188
|
flamegraphResponse?.report.oneofKind === 'flamegraphArrow'
|
|
189
|
-
?
|
|
189
|
+
? flamegraphResponse?.report?.flamegraphArrow
|
|
190
190
|
: undefined,
|
|
191
191
|
total: BigInt(flamegraphResponse?.total ?? '0'),
|
|
192
192
|
filtered: BigInt(flamegraphResponse?.filtered ?? '0'),
|