@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 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.14.37",
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.14.37",
8
- "@parca/dynamicsize": "^0.14.36",
9
- "@parca/parser": "^0.14.36",
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": "21acf8f58da4fc28346b83a24692bcc9dabc4f46"
26
+ "gitHead": "dfdd9847f875aadab59fa812955f1f689d7870e7"
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]}
@@ -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 {QueryServiceClient, Flamegraph, Top} from '@parca/client';
18
- import {Button, Card, SearchNodes, useGrpcMetadata, useParcaTheme} from '@parca/components';
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
- type VisualizationType = 'icicle' | 'table' | 'both';
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
+ }