@parca/profile 0.14.37 → 0.15.0

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 CHANGED
@@ -3,6 +3,52 @@
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.0](https://github.com/parca-dev/parca/compare/ui-v0.14.37...ui-v0.15.0) (2022-08-24)
7
+
8
+
9
+
10
+ ## [0.14.32](https://github.com/parca-dev/parca/compare/ui-v0.14.30...ui-v0.14.32) (2022-08-18)
11
+
12
+
13
+
14
+ ## [0.14.30](https://github.com/parca-dev/parca/compare/ui-v0.14.24...ui-v0.14.30) (2022-08-17)
15
+
16
+
17
+ ### Features
18
+
19
+ * implement callgraph report api ([83c81c6](https://github.com/parca-dev/parca/commit/83c81c67a140b4b723094ee0d6c2308b112b800c))
20
+ * tooltip for callgraph ([c1d0195](https://github.com/parca-dev/parca/commit/c1d0195e45a5aa065a89c936861646f1455336ff))
21
+
22
+
23
+
24
+ ## [0.14.16](https://github.com/parca-dev/parca/compare/ui-v0.14.11...ui-v0.14.16) (2022-08-03)
25
+
26
+
27
+
28
+ ## [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)
29
+
30
+
31
+
32
+ ## [0.13.14](https://github.com/parca-dev/parca/compare/ui-v0.13.12...ui-v0.13.14) (2022-06-29)
33
+
34
+
35
+ ### Features
36
+
37
+ * add tooltip to callgraph ([b261a48](https://github.com/parca-dev/parca/commit/b261a48a92739d5fb957957da929495cb206417e))
38
+ * connect callgraph component to actual data ([b7dd5d8](https://github.com/parca-dev/parca/commit/b7dd5d8b0851d11010f66a3a5ca03d50902636a1))
39
+
40
+
41
+
42
+ ## [0.13.10](https://github.com/parca-dev/parca/compare/ui-v0.13.2...ui-v0.13.10) (2022-06-22)
43
+
44
+
45
+
46
+ ## [0.13.2](https://github.com/parca-dev/parca/compare/ui-v0.13.1...ui-v0.13.2) (2022-05-31)
47
+
48
+
49
+
50
+
51
+
6
52
  ## [0.14.37](https://github.com/parca-dev/parca/compare/ui-v0.14.36...ui-v0.14.37) (2022-08-24)
7
53
 
8
54
  **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.14.37",
3
+ "version": "0.15.0",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@iconify/react": "^3.2.2",
7
- "@parca/client": "^0.14.37",
8
- "@parca/dynamicsize": "^0.14.36",
9
- "@parca/parser": "^0.14.36",
7
+ "@parca/client": "^0.15.0",
8
+ "@parca/dynamicsize": "^0.15.0",
9
+ "@parca/functions": "^0.15.0",
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": "21acf8f58da4fc28346b83a24692bcc9dabc4f46"
26
+ "gitHead": "9bba12f8523b8d5763d9fb6d81c9df971a83f6fa"
26
27
  }
@@ -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 {FlamegraphTooltip} from '@parca/components';
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
- <FlamegraphTooltip
334
+ <GraphTooltip
335
335
  unit={sampleUnit}
336
336
  total={total}
337
337
  x={pos[0]}
@@ -14,8 +14,17 @@
14
14
  import React, {useEffect, useMemo, useState} from 'react';
15
15
 
16
16
  import {parseParams} from '@parca/functions';
17
- import {QueryServiceClient, Flamegraph, Top} from '@parca/client';
18
- import {Button, Card, SearchNodes, useGrpcMetadata, useParcaTheme} from '@parca/components';
17
+ import useUIFeatureFlag from '@parca/functions/useUIFeatureFlag';
18
+ import {QueryServiceClient, Flamegraph, Top, Callgraph} from '@parca/client';
19
+ import {
20
+ Button,
21
+ Card,
22
+ SearchNodes,
23
+ useGrpcMetadata,
24
+ useParcaTheme,
25
+ Callgraph as CallgraphComponent,
26
+ } from '@parca/components';
27
+ import {useContainerDimensions} from '@parca/dynamicsize';
19
28
 
20
29
  import ProfileShareButton from './components/ProfileShareButton';
21
30
  import ProfileIcicleGraph from './ProfileIcicleGraph';
@@ -40,7 +49,13 @@ interface TopTableData {
40
49
  error?: any;
41
50
  }
42
51
 
43
- type VisualizationType = 'icicle' | 'table' | 'both';
52
+ interface CallgraphData {
53
+ loading: boolean;
54
+ data?: Callgraph;
55
+ error?: any;
56
+ }
57
+
58
+ type VisualizationType = 'icicle' | 'table' | 'callgraph' | 'both';
44
59
 
45
60
  interface ProfileVisState {
46
61
  currentView: VisualizationType;
@@ -50,6 +65,7 @@ interface ProfileVisState {
50
65
  interface ProfileViewProps {
51
66
  flamegraphData?: FlamegraphData;
52
67
  topTableData?: TopTableData;
68
+ callgraphData?: CallgraphData;
53
69
  sampleUnit: string;
54
70
  profileVisState: ProfileVisState;
55
71
  profileSource?: ProfileSource;
@@ -79,15 +95,19 @@ export const useProfileVisState = (): ProfileVisState => {
79
95
  export const ProfileView = ({
80
96
  flamegraphData,
81
97
  topTableData,
98
+ callgraphData,
82
99
  sampleUnit,
83
100
  profileSource,
84
101
  queryClient,
85
102
  navigateTo,
86
103
  profileVisState,
87
104
  }: ProfileViewProps): JSX.Element => {
105
+ const {ref, dimensions} = useContainerDimensions();
88
106
  const [curPath, setCurPath] = useState<string[]>([]);
89
107
  const {currentView, setCurrentView} = profileVisState;
90
108
 
109
+ const [callgraphEnabled] = useUIFeatureFlag('callgraph');
110
+
91
111
  const metadata = useGrpcMetadata();
92
112
  const {loader} = useParcaTheme();
93
113
 
@@ -100,6 +120,9 @@ export const ProfileView = ({
100
120
  if (currentView === 'icicle') {
101
121
  return Boolean(flamegraphData?.loading);
102
122
  }
123
+ if (currentView === 'callgraph') {
124
+ return !!callgraphData?.loading;
125
+ }
103
126
  if (currentView === 'table') {
104
127
  return Boolean(topTableData?.loading);
105
128
  }
@@ -107,7 +130,7 @@ export const ProfileView = ({
107
130
  return Boolean(flamegraphData?.loading) || Boolean(topTableData?.loading);
108
131
  }
109
132
  return false;
110
- }, [currentView, flamegraphData?.loading, topTableData?.loading]);
133
+ }, [currentView, callgraphData?.loading, flamegraphData?.loading, topTableData?.loading]);
111
134
 
112
135
  const isLoaderVisible = useDelayedLoader(isLoading);
113
136
 
@@ -196,6 +219,18 @@ export const ProfileView = ({
196
219
  </Button>
197
220
  </div>
198
221
 
222
+ {callgraphEnabled ? (
223
+ <div className="mr-3">
224
+ <Button
225
+ variant={`${currentView === 'callgraph' ? 'primary' : 'neutral'}`}
226
+ onClick={() => switchProfileView('callgraph')}
227
+ className="whitespace-nowrap text-ellipsis"
228
+ >
229
+ Call Graph
230
+ </Button>
231
+ </div>
232
+ ) : null}
233
+
199
234
  <Button
200
235
  variant={`${currentView === 'table' ? 'primary' : 'neutral'}`}
201
236
  className="items-center rounded-tr-none rounded-br-none w-auto px-8 whitespace-nowrap text-ellipsis no-outline-on-buttons"
@@ -222,7 +257,7 @@ export const ProfileView = ({
222
257
  </div>
223
258
  </div>
224
259
 
225
- <div className="flex space-x-4 justify-between">
260
+ <div ref={ref} className="flex space-x-4 justify-between w-full">
226
261
  {currentView === 'icicle' && flamegraphData?.data != null && (
227
262
  <div className="w-full">
228
263
  <ProfileIcicleGraph
@@ -234,6 +269,18 @@ export const ProfileView = ({
234
269
  </div>
235
270
  )}
236
271
 
272
+ {currentView === 'callgraph' && callgraphData?.data != null && (
273
+ <div className="w-full">
274
+ {dimensions?.width && (
275
+ <CallgraphComponent
276
+ graph={callgraphData.data}
277
+ sampleUnit={sampleUnit}
278
+ width={dimensions?.width}
279
+ />
280
+ )}
281
+ </div>
282
+ )}
283
+
237
284
  {currentView === 'table' && topTableData != null && (
238
285
  <div className="w-full">
239
286
  <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
+ }