@parca/profile 0.14.37 → 0.15.3
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 +66 -0
- package/package.json +6 -5
- package/src/IcicleGraph.tsx +2 -2
- package/src/ProfileView.tsx +53 -5
- package/src/ProfileViewWithData.tsx +16 -0
- package/src/testdata/link_data.json +56 -0
- package/src/testdata/tabular.json +30 -0
- package/src/testdata/test_graph.json +53 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,72 @@
|
|
|
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.15.3](https://github.com/parca-dev/parca/compare/ui-v0.15.2...ui-v0.15.3) (2022-08-25)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
## 0.15.1 (2022-08-25)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
## [0.15.2](https://github.com/parca-dev/parca/compare/ui-v0.15.1...ui-v0.15.2) (2022-08-25)
|
|
19
|
+
|
|
20
|
+
**Note:** Version bump only for package @parca/profile
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# [0.15.0](https://github.com/parca-dev/parca/compare/ui-v0.14.37...ui-v0.15.0) (2022-08-24)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
## [0.14.32](https://github.com/parca-dev/parca/compare/ui-v0.14.30...ui-v0.14.32) (2022-08-18)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## [0.14.30](https://github.com/parca-dev/parca/compare/ui-v0.14.24...ui-v0.14.30) (2022-08-17)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Features
|
|
38
|
+
|
|
39
|
+
* implement callgraph report api ([83c81c6](https://github.com/parca-dev/parca/commit/83c81c67a140b4b723094ee0d6c2308b112b800c))
|
|
40
|
+
* tooltip for callgraph ([c1d0195](https://github.com/parca-dev/parca/commit/c1d0195e45a5aa065a89c936861646f1455336ff))
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
## [0.14.16](https://github.com/parca-dev/parca/compare/ui-v0.14.11...ui-v0.14.16) (2022-08-03)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
## [0.14.3-alpha.0](https://github.com/parca-dev/parca/compare/ui-v0.14.1...ui-v0.14.3-alpha.0) (2022-07-26)
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
## [0.13.14](https://github.com/parca-dev/parca/compare/ui-v0.13.12...ui-v0.13.14) (2022-06-29)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
### Features
|
|
56
|
+
|
|
57
|
+
* add tooltip to callgraph ([b261a48](https://github.com/parca-dev/parca/commit/b261a48a92739d5fb957957da929495cb206417e))
|
|
58
|
+
* connect callgraph component to actual data ([b7dd5d8](https://github.com/parca-dev/parca/commit/b7dd5d8b0851d11010f66a3a5ca03d50902636a1))
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
## [0.13.10](https://github.com/parca-dev/parca/compare/ui-v0.13.2...ui-v0.13.10) (2022-06-22)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
## [0.13.2](https://github.com/parca-dev/parca/compare/ui-v0.13.1...ui-v0.13.2) (2022-05-31)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
|
|
6
72
|
## [0.14.37](https://github.com/parca-dev/parca/compare/ui-v0.14.36...ui-v0.14.37) (2022-08-24)
|
|
7
73
|
|
|
8
74
|
**Note:** Version bump only for package @parca/profile
|
package/package.json
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.3",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@iconify/react": "^3.2.2",
|
|
7
|
-
"@parca/client": "^0.
|
|
8
|
-
"@parca/dynamicsize": "^0.
|
|
9
|
-
"@parca/
|
|
7
|
+
"@parca/client": "^0.15.2",
|
|
8
|
+
"@parca/dynamicsize": "^0.15.0",
|
|
9
|
+
"@parca/functions": "^0.15.3",
|
|
10
|
+
"@parca/parser": "^0.15.0",
|
|
10
11
|
"d3-scale": "^4.0.2",
|
|
11
12
|
"d3-selection": "3.0.0",
|
|
12
13
|
"react-copy-to-clipboard": "^5.1.0"
|
|
@@ -22,5 +23,5 @@
|
|
|
22
23
|
"access": "public",
|
|
23
24
|
"registry": "https://registry.npmjs.org/"
|
|
24
25
|
},
|
|
25
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "dfdd9847f875aadab59fa812955f1f689d7870e7"
|
|
26
27
|
}
|
package/src/IcicleGraph.tsx
CHANGED
|
@@ -17,7 +17,7 @@ import {throttle} from 'lodash';
|
|
|
17
17
|
import {pointer} from 'd3-selection';
|
|
18
18
|
import {scaleLinear} from 'd3-scale';
|
|
19
19
|
import {Flamegraph, FlamegraphNode, FlamegraphRootNode} from '@parca/client';
|
|
20
|
-
import {
|
|
20
|
+
import {GraphTooltip} from '@parca/components';
|
|
21
21
|
import {getLastItem, diffColor, isSearchMatch} from '@parca/functions';
|
|
22
22
|
import {useAppSelector, selectDarkMode, selectSearchNodeString} from '@parca/store';
|
|
23
23
|
|
|
@@ -331,7 +331,7 @@ export default function IcicleGraph({
|
|
|
331
331
|
|
|
332
332
|
return (
|
|
333
333
|
<div onMouseLeave={() => setHoveringNode(undefined)}>
|
|
334
|
-
<
|
|
334
|
+
<GraphTooltip
|
|
335
335
|
unit={sampleUnit}
|
|
336
336
|
total={total}
|
|
337
337
|
x={pos[0]}
|
package/src/ProfileView.tsx
CHANGED
|
@@ -11,11 +11,21 @@
|
|
|
11
11
|
// See the License for the specific language governing permissions and
|
|
12
12
|
// limitations under the License.
|
|
13
13
|
|
|
14
|
+
/* eslint-disable */
|
|
14
15
|
import React, {useEffect, useMemo, useState} from 'react';
|
|
15
16
|
|
|
16
17
|
import {parseParams} from '@parca/functions';
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
18
|
+
import useUIFeatureFlag from '@parca/functions/useUIFeatureFlag';
|
|
19
|
+
import {QueryServiceClient, Flamegraph, Top, Callgraph} from '@parca/client';
|
|
20
|
+
import {
|
|
21
|
+
Button,
|
|
22
|
+
Card,
|
|
23
|
+
SearchNodes,
|
|
24
|
+
useGrpcMetadata,
|
|
25
|
+
useParcaTheme,
|
|
26
|
+
Callgraph as CallgraphComponent,
|
|
27
|
+
} from '@parca/components';
|
|
28
|
+
import {useContainerDimensions} from '@parca/dynamicsize';
|
|
19
29
|
|
|
20
30
|
import ProfileShareButton from './components/ProfileShareButton';
|
|
21
31
|
import ProfileIcicleGraph from './ProfileIcicleGraph';
|
|
@@ -40,7 +50,13 @@ interface TopTableData {
|
|
|
40
50
|
error?: any;
|
|
41
51
|
}
|
|
42
52
|
|
|
43
|
-
|
|
53
|
+
interface CallgraphData {
|
|
54
|
+
loading: boolean;
|
|
55
|
+
data?: Callgraph;
|
|
56
|
+
error?: any;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
type VisualizationType = 'icicle' | 'table' | 'callgraph' | 'both';
|
|
44
60
|
|
|
45
61
|
interface ProfileVisState {
|
|
46
62
|
currentView: VisualizationType;
|
|
@@ -50,6 +66,7 @@ interface ProfileVisState {
|
|
|
50
66
|
interface ProfileViewProps {
|
|
51
67
|
flamegraphData?: FlamegraphData;
|
|
52
68
|
topTableData?: TopTableData;
|
|
69
|
+
callgraphData?: CallgraphData;
|
|
53
70
|
sampleUnit: string;
|
|
54
71
|
profileVisState: ProfileVisState;
|
|
55
72
|
profileSource?: ProfileSource;
|
|
@@ -79,15 +96,19 @@ export const useProfileVisState = (): ProfileVisState => {
|
|
|
79
96
|
export const ProfileView = ({
|
|
80
97
|
flamegraphData,
|
|
81
98
|
topTableData,
|
|
99
|
+
callgraphData,
|
|
82
100
|
sampleUnit,
|
|
83
101
|
profileSource,
|
|
84
102
|
queryClient,
|
|
85
103
|
navigateTo,
|
|
86
104
|
profileVisState,
|
|
87
105
|
}: ProfileViewProps): JSX.Element => {
|
|
106
|
+
const {ref, dimensions} = useContainerDimensions();
|
|
88
107
|
const [curPath, setCurPath] = useState<string[]>([]);
|
|
89
108
|
const {currentView, setCurrentView} = profileVisState;
|
|
90
109
|
|
|
110
|
+
const [callgraphEnabled] = useUIFeatureFlag('callgraph');
|
|
111
|
+
|
|
91
112
|
const metadata = useGrpcMetadata();
|
|
92
113
|
const {loader} = useParcaTheme();
|
|
93
114
|
|
|
@@ -100,6 +121,9 @@ export const ProfileView = ({
|
|
|
100
121
|
if (currentView === 'icicle') {
|
|
101
122
|
return Boolean(flamegraphData?.loading);
|
|
102
123
|
}
|
|
124
|
+
if (currentView === 'callgraph') {
|
|
125
|
+
return !!callgraphData?.loading;
|
|
126
|
+
}
|
|
103
127
|
if (currentView === 'table') {
|
|
104
128
|
return Boolean(topTableData?.loading);
|
|
105
129
|
}
|
|
@@ -107,7 +131,7 @@ export const ProfileView = ({
|
|
|
107
131
|
return Boolean(flamegraphData?.loading) || Boolean(topTableData?.loading);
|
|
108
132
|
}
|
|
109
133
|
return false;
|
|
110
|
-
}, [currentView, flamegraphData?.loading, topTableData?.loading]);
|
|
134
|
+
}, [currentView, callgraphData?.loading, flamegraphData?.loading, topTableData?.loading]);
|
|
111
135
|
|
|
112
136
|
const isLoaderVisible = useDelayedLoader(isLoading);
|
|
113
137
|
|
|
@@ -196,6 +220,18 @@ export const ProfileView = ({
|
|
|
196
220
|
</Button>
|
|
197
221
|
</div>
|
|
198
222
|
|
|
223
|
+
{callgraphEnabled ? (
|
|
224
|
+
<div className="mr-3">
|
|
225
|
+
<Button
|
|
226
|
+
variant={`${currentView === 'callgraph' ? 'primary' : 'neutral'}`}
|
|
227
|
+
onClick={() => switchProfileView('callgraph')}
|
|
228
|
+
className="whitespace-nowrap text-ellipsis"
|
|
229
|
+
>
|
|
230
|
+
Call Graph
|
|
231
|
+
</Button>
|
|
232
|
+
</div>
|
|
233
|
+
) : null}
|
|
234
|
+
|
|
199
235
|
<Button
|
|
200
236
|
variant={`${currentView === 'table' ? 'primary' : 'neutral'}`}
|
|
201
237
|
className="items-center rounded-tr-none rounded-br-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons"
|
|
@@ -222,7 +258,7 @@ export const ProfileView = ({
|
|
|
222
258
|
</div>
|
|
223
259
|
</div>
|
|
224
260
|
|
|
225
|
-
<div className="flex space-x-4 justify-between">
|
|
261
|
+
<div ref={ref} className="flex space-x-4 justify-between w-full">
|
|
226
262
|
{currentView === 'icicle' && flamegraphData?.data != null && (
|
|
227
263
|
<div className="w-full">
|
|
228
264
|
<ProfileIcicleGraph
|
|
@@ -234,6 +270,18 @@ export const ProfileView = ({
|
|
|
234
270
|
</div>
|
|
235
271
|
)}
|
|
236
272
|
|
|
273
|
+
{currentView === 'callgraph' && callgraphData?.data != null && (
|
|
274
|
+
<div className="w-full">
|
|
275
|
+
{dimensions?.width && (
|
|
276
|
+
<CallgraphComponent
|
|
277
|
+
graph={callgraphData.data}
|
|
278
|
+
sampleUnit={sampleUnit}
|
|
279
|
+
width={dimensions?.width}
|
|
280
|
+
/>
|
|
281
|
+
)}
|
|
282
|
+
</div>
|
|
283
|
+
)}
|
|
284
|
+
|
|
237
285
|
{currentView === 'table' && topTableData != null && (
|
|
238
286
|
<div className="w-full">
|
|
239
287
|
<TopTable data={topTableData.data} sampleUnit={sampleUnit} />
|
|
@@ -49,6 +49,14 @@ export const ProfileViewWithData = ({
|
|
|
49
49
|
skip: currentView !== 'table' && currentView !== 'both',
|
|
50
50
|
});
|
|
51
51
|
|
|
52
|
+
const {
|
|
53
|
+
isLoading: callgraphLoading,
|
|
54
|
+
response: callgraphResponse,
|
|
55
|
+
error: callgraphError,
|
|
56
|
+
} = useQuery(queryClient, profileSource, QueryRequest_ReportType.CALLGRAPH, {
|
|
57
|
+
skip: currentView !== 'callgraph',
|
|
58
|
+
});
|
|
59
|
+
|
|
52
60
|
const sampleUnit = profileSource.ProfileType().sampleUnit;
|
|
53
61
|
|
|
54
62
|
return (
|
|
@@ -67,6 +75,14 @@ export const ProfileViewWithData = ({
|
|
|
67
75
|
topTableResponse?.report.oneofKind === 'top' ? topTableResponse.report.top : undefined,
|
|
68
76
|
error: topTableError,
|
|
69
77
|
}}
|
|
78
|
+
callgraphData={{
|
|
79
|
+
loading: callgraphLoading,
|
|
80
|
+
data:
|
|
81
|
+
callgraphResponse?.report.oneofKind === 'callgraph'
|
|
82
|
+
? callgraphResponse?.report?.callgraph
|
|
83
|
+
: undefined,
|
|
84
|
+
error: callgraphError,
|
|
85
|
+
}}
|
|
70
86
|
profileVisState={profileVisState}
|
|
71
87
|
sampleUnit={sampleUnit}
|
|
72
88
|
profileSource={profileSource}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"total": "4358676",
|
|
3
|
+
"unit": "count",
|
|
4
|
+
"height": 27,
|
|
5
|
+
"data": {
|
|
6
|
+
"nodes": {
|
|
7
|
+
"root": {
|
|
8
|
+
"id": "root",
|
|
9
|
+
"cumulative": "10",
|
|
10
|
+
"diff": "0"
|
|
11
|
+
},
|
|
12
|
+
"1": {
|
|
13
|
+
"id": "1",
|
|
14
|
+
"cumulative": "2",
|
|
15
|
+
"diff": "0"
|
|
16
|
+
},
|
|
17
|
+
"2": {
|
|
18
|
+
"id": "2",
|
|
19
|
+
"cumulative": "9",
|
|
20
|
+
"diff": "0"
|
|
21
|
+
},
|
|
22
|
+
"3": {
|
|
23
|
+
"id": "3",
|
|
24
|
+
"cumulative": "8"
|
|
25
|
+
},
|
|
26
|
+
"4": {
|
|
27
|
+
"id": "4",
|
|
28
|
+
"cumulative": "2"
|
|
29
|
+
}
|
|
30
|
+
},
|
|
31
|
+
"links": [
|
|
32
|
+
{
|
|
33
|
+
"source": "root",
|
|
34
|
+
"target": "1"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"source": "root",
|
|
38
|
+
"target": "4"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"source": "1",
|
|
42
|
+
"target": "2"
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"source": "2",
|
|
46
|
+
"target": "3"
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
"reversedLinks": [
|
|
50
|
+
{
|
|
51
|
+
"source": "3",
|
|
52
|
+
"target": "1"
|
|
53
|
+
}
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"total": "4358676",
|
|
3
|
+
"unit": "count",
|
|
4
|
+
"height": 27,
|
|
5
|
+
"data": [
|
|
6
|
+
{
|
|
7
|
+
"id": "root"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"id": "child_1",
|
|
11
|
+
"parentIds": ["root", "loop_child"]
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"id": "child_2",
|
|
15
|
+
"parentIds": ["root"]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": "grandchild_1",
|
|
19
|
+
"parentIds": ["child_1"]
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"id": "grandchild_2",
|
|
23
|
+
"parentIds": ["child_1"]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "loop_child",
|
|
27
|
+
"parentIds": ["grandchild_1"]
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"total": "4358676",
|
|
3
|
+
"unit": "count",
|
|
4
|
+
"height": 27,
|
|
5
|
+
"root": {
|
|
6
|
+
"id": "root",
|
|
7
|
+
"cumulative": "4358676",
|
|
8
|
+
"diff": "0",
|
|
9
|
+
"children": [
|
|
10
|
+
{
|
|
11
|
+
"id": "child_1",
|
|
12
|
+
"cumulative": "1",
|
|
13
|
+
"diff": "0",
|
|
14
|
+
"children": [
|
|
15
|
+
{
|
|
16
|
+
"id": "child_2",
|
|
17
|
+
"cumulative": "1",
|
|
18
|
+
"diff": "0",
|
|
19
|
+
"children": [
|
|
20
|
+
{
|
|
21
|
+
"id": "root",
|
|
22
|
+
"cumulative": "4358676",
|
|
23
|
+
"diff": "0",
|
|
24
|
+
"children": [
|
|
25
|
+
{
|
|
26
|
+
"id": "child_1",
|
|
27
|
+
"cumulative": "1",
|
|
28
|
+
"diff": "0",
|
|
29
|
+
"children": [
|
|
30
|
+
{
|
|
31
|
+
"id": "child_2",
|
|
32
|
+
"cumulative": "1",
|
|
33
|
+
"diff": "0",
|
|
34
|
+
"children": [
|
|
35
|
+
{
|
|
36
|
+
"id": "child_1",
|
|
37
|
+
"cumulative": "1",
|
|
38
|
+
"diff": "0",
|
|
39
|
+
"children": []
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
}
|