@parca/profile 0.16.107 → 0.16.108

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/GraphTooltip/index.js +2 -2
  3. package/dist/MetricsGraph/index.js +2 -3
  4. package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts +1 -1
  5. package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts +1 -1
  6. package/dist/ProfileExplorer/ProfileExplorerSingle.js +2 -1
  7. package/dist/ProfileExplorer/index.d.ts +1 -1
  8. package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.d.ts +8 -0
  9. package/dist/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.js +75 -0
  10. package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.d.ts +47 -0
  11. package/dist/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.js +98 -0
  12. package/dist/ProfileIcicleGraph/IcicleGraph/index.d.ts +13 -0
  13. package/dist/ProfileIcicleGraph/IcicleGraph/index.js +74 -0
  14. package/dist/ProfileIcicleGraph/IcicleGraph/useColoredGraph.d.ts +14 -0
  15. package/dist/ProfileIcicleGraph/IcicleGraph/useColoredGraph.js +59 -0
  16. package/dist/ProfileIcicleGraph/IcicleGraph/useNodeColor.d.ts +7 -0
  17. package/dist/ProfileIcicleGraph/IcicleGraph/useNodeColor.js +32 -0
  18. package/dist/ProfileIcicleGraph/IcicleGraph/utils.d.ts +5 -0
  19. package/dist/ProfileIcicleGraph/IcicleGraph/utils.js +59 -0
  20. package/dist/ProfileIcicleGraph/index.d.ts +3 -1
  21. package/dist/ProfileIcicleGraph/index.js +3 -3
  22. package/dist/ProfileView/FilterByFunctionButton.d.ts +1 -1
  23. package/dist/ProfileView/FilterByFunctionButton.js +1 -2
  24. package/dist/ProfileView/ViewSelector.d.ts +1 -1
  25. package/dist/ProfileView/ViewSelector.js +1 -14
  26. package/dist/ProfileView/index.js +4 -4
  27. package/dist/ProfileViewWithData.d.ts +1 -1
  28. package/dist/ProfileViewWithData.js +2 -2
  29. package/dist/TopTable/index.d.ts +1 -1
  30. package/dist/index.d.ts +1 -1
  31. package/dist/index.js +1 -1
  32. package/dist/styles.css +1 -1
  33. package/package.json +6 -5
  34. package/src/GraphTooltip/index.tsx +2 -2
  35. package/src/MetricsGraph/index.tsx +2 -3
  36. package/src/ProfileExplorer/ProfileExplorerCompare.tsx +1 -1
  37. package/src/ProfileExplorer/ProfileExplorerSingle.tsx +4 -3
  38. package/src/ProfileExplorer/index.tsx +1 -1
  39. package/src/ProfileIcicleGraph/IcicleGraph/ColorStackLegend.tsx +93 -0
  40. package/src/ProfileIcicleGraph/IcicleGraph/IcicleGraphNodes.tsx +262 -0
  41. package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +160 -0
  42. package/src/ProfileIcicleGraph/IcicleGraph/useColoredGraph.ts +106 -0
  43. package/src/ProfileIcicleGraph/IcicleGraph/useNodeColor.ts +42 -0
  44. package/src/ProfileIcicleGraph/IcicleGraph/utils.ts +94 -0
  45. package/src/ProfileIcicleGraph/index.tsx +5 -1
  46. package/src/ProfileView/FilterByFunctionButton.tsx +2 -2
  47. package/src/ProfileView/ViewSelector.tsx +2 -2
  48. package/src/ProfileView/index.tsx +6 -5
  49. package/src/ProfileViewWithData.tsx +3 -2
  50. package/src/TopTable/index.tsx +1 -1
  51. package/src/index.tsx +1 -1
  52. package/dist/IcicleGraph.d.ts +0 -45
  53. package/dist/IcicleGraph.js +0 -180
  54. package/src/IcicleGraph.tsx +0 -481
@@ -11,8 +11,8 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
 
14
- import {Input} from '@parca/components';
15
- import {useURLState, NavigateFunction} from '@parca/functions';
14
+ import {Input, useURLState} from '@parca/components';
15
+ import type {NavigateFunction} from '@parca/functions';
16
16
  import {Icon} from '@iconify/react';
17
17
  import {useCallback, useMemo, useState} from 'react';
18
18
 
@@ -11,9 +11,9 @@
11
11
  // See the License for the specific language governing permissions and
12
12
  // limitations under the License.
13
13
 
14
- import {Select} from '@parca/components';
14
+ import type {NavigateFunction} from '@parca/functions';
15
+ import {Select, useURLState} from '@parca/components';
15
16
  import type {SelectElement} from '@parca/components';
16
- import {useURLState, NavigateFunction} from '@parca/functions';
17
17
  import useUIFeatureFlag from '@parca/functions/useUIFeatureFlag';
18
18
 
19
19
  interface Props {
@@ -15,11 +15,11 @@ import {Profiler, useEffect, useMemo, useState} from 'react';
15
15
  import {scaleLinear} from 'd3';
16
16
 
17
17
  import cx from 'classnames';
18
- import {getNewSpanColor, useURLState} from '@parca/functions';
18
+ import {getNewSpanColor} from '@parca/functions';
19
19
  import {CloseIcon} from '@parca/icons';
20
20
  import {Icon} from '@iconify/react';
21
21
  import {QueryServiceClient, Flamegraph, Top, Callgraph as CallgraphType} from '@parca/client';
22
- import {Button, Card, useParcaContext} from '@parca/components';
22
+ import {Button, Card, useParcaContext, KeyDownProvider, useURLState} from '@parca/components';
23
23
  import {useContainerDimensions} from '@parca/dynamicsize';
24
24
  import {useAppSelector, selectDarkMode} from '@parca/store';
25
25
  import {DragDropContext, Droppable, Draggable} from 'react-beautiful-dnd';
@@ -157,11 +157,12 @@ export const ProfileView = ({
157
157
  graph={flamegraphData.data}
158
158
  sampleUnit={sampleUnit}
159
159
  onContainerResize={onFlamegraphContainerResize}
160
+ navigateTo={navigateTo}
160
161
  loading={flamegraphData.loading}
161
162
  />
162
163
  </Profiler>
163
164
  ) : (
164
- <></>
165
+ <> </>
165
166
  );
166
167
  }
167
168
  case 'callgraph': {
@@ -215,7 +216,7 @@ export const ProfileView = ({
215
216
  };
216
217
 
217
218
  return (
218
- <>
219
+ <KeyDownProvider>
219
220
  <div className="py-3">
220
221
  <Card>
221
222
  <Card.Body>
@@ -335,6 +336,6 @@ export const ProfileView = ({
335
336
  </Card.Body>
336
337
  </Card>
337
338
  </div>
338
- </>
339
+ </KeyDownProvider>
339
340
  );
340
341
  };
@@ -17,8 +17,9 @@ import {useQuery} from './useQuery';
17
17
  import {ProfileView} from './ProfileView';
18
18
  import {ProfileSource} from './ProfileSource';
19
19
  import {downloadPprof} from './utils';
20
- import {useGrpcMetadata, useParcaContext} from '@parca/components';
21
- import {saveAsBlob, NavigateFunction, useURLState} from '@parca/functions';
20
+ import {useGrpcMetadata, useParcaContext, useURLState} from '@parca/components';
21
+ import {saveAsBlob} from '@parca/functions';
22
+ import type {NavigateFunction} from '@parca/functions';
22
23
  import useUserPreference, {USER_PREFERENCES} from '@parca/functions/useUserPreference';
23
24
 
24
25
  interface ProfileViewWithDataProps {
@@ -17,10 +17,10 @@ import {
17
17
  getLastItem,
18
18
  valueFormatter,
19
19
  isSearchMatch,
20
- NavigateFunction,
21
20
  parseParams,
22
21
  selectQueryParam,
23
22
  } from '@parca/functions';
23
+ import type {NavigateFunction} from '@parca/functions';
24
24
  import {TopNode, TopNodeMeta, Top} from '@parca/client';
25
25
  import {Table} from '@parca/components';
26
26
  import {createColumnHelper} from '@tanstack/react-table';
package/src/index.tsx CHANGED
@@ -18,7 +18,7 @@ import ProfileTypeSelector from './ProfileTypeSelector';
18
18
  import type {FlamegraphData, TopTableData} from './ProfileView';
19
19
  import {QueryServiceClient} from '@parca/client';
20
20
 
21
- export * from './IcicleGraph';
21
+ export * from './ProfileIcicleGraph/IcicleGraph';
22
22
  export * from './ProfileIcicleGraph';
23
23
  export * from './ProfileSource';
24
24
  export * from './ProfileView';
@@ -1,45 +0,0 @@
1
- /// <reference types="react" />
2
- import { Flamegraph, FlamegraphNode, FlamegraphRootNode } from '@parca/client';
3
- import { Mapping, Function as ParcaFunction, Location } from '@parca/client/dist/parca/metastore/v1alpha1/metastore';
4
- interface IcicleGraphProps {
5
- graph: Flamegraph;
6
- sampleUnit: string;
7
- width?: number;
8
- curPath: string[];
9
- setCurPath: (path: string[]) => void;
10
- }
11
- interface IcicleGraphNodesProps {
12
- data: FlamegraphNode[];
13
- strings: string[];
14
- mappings: Mapping[];
15
- locations: Location[];
16
- functions: ParcaFunction[];
17
- x: number;
18
- y: number;
19
- total: number;
20
- totalWidth: number;
21
- level: number;
22
- curPath: string[];
23
- setCurPath: (path: string[]) => void;
24
- setHoveringNode: (node: FlamegraphNode | FlamegraphRootNode | undefined) => void;
25
- path: string[];
26
- xScale: (value: number) => number;
27
- }
28
- interface IcicleGraphRootNodeProps {
29
- node: FlamegraphRootNode;
30
- strings: string[];
31
- mappings: Mapping[];
32
- locations: Location[];
33
- functions: ParcaFunction[];
34
- xScale: (value: number) => number;
35
- total: number;
36
- totalWidth: number;
37
- curPath: string[];
38
- setCurPath: (path: string[]) => void;
39
- setHoveringNode: (node: FlamegraphNode | FlamegraphRootNode | undefined) => void;
40
- }
41
- export declare function nodeLabel(node: FlamegraphNode, strings: string[], mappings: Mapping[], locations: Location[], functions: ParcaFunction[]): string;
42
- export declare function IcicleGraphNodes({ data, strings, mappings, locations, functions, x, y, xScale, total, totalWidth, level, setHoveringNode, path, setCurPath, curPath, }: IcicleGraphNodesProps): JSX.Element;
43
- export declare function IcicleGraphRootNode({ node, strings, mappings, locations, functions, xScale, total, totalWidth, setHoveringNode, setCurPath, curPath, }: IcicleGraphRootNodeProps): JSX.Element;
44
- export default function IcicleGraph({ graph, width, setCurPath, curPath, sampleUnit, }: IcicleGraphProps): JSX.Element;
45
- export {};
@@ -1,180 +0,0 @@
1
- var __assign = (this && this.__assign) || function () {
2
- __assign = Object.assign || function(t) {
3
- for (var s, i = 1, n = arguments.length; i < n; i++) {
4
- s = arguments[i];
5
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
- t[p] = s[p];
7
- }
8
- return t;
9
- };
10
- return __assign.apply(this, arguments);
11
- };
12
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
13
- // Copyright 2022 The Parca Authors
14
- // Licensed under the Apache License, Version 2.0 (the "License");
15
- // you may not use this file except in compliance with the License.
16
- // You may obtain a copy of the License at
17
- //
18
- // http://www.apache.org/licenses/LICENSE-2.0
19
- //
20
- // Unless required by applicable law or agreed to in writing, software
21
- // distributed under the License is distributed on an "AS IS" BASIS,
22
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23
- // See the License for the specific language governing permissions and
24
- // limitations under the License.
25
- import { useEffect, useMemo, useRef, useState, memo, Fragment } from 'react';
26
- import cx from 'classnames';
27
- import { throttle } from 'lodash';
28
- import { pointer } from 'd3-selection';
29
- import { scaleLinear } from 'd3-scale';
30
- import GraphTooltip from './GraphTooltip';
31
- import { diffColor, getLastItem, isSearchMatch, selectQueryParam, useURLState, } from '@parca/functions';
32
- import { selectDarkMode, useAppSelector } from '@parca/store';
33
- import useIsShiftDown from '@parca/components/src/hooks/useIsShiftDown';
34
- import { Button } from '@parca/components';
35
- import { hexifyAddress } from './utils';
36
- var RowHeight = 26;
37
- var icicleRectStyles = {
38
- cursor: 'pointer',
39
- transition: 'opacity .15s linear',
40
- };
41
- var fadedIcicleRectStyles = {
42
- cursor: 'pointer',
43
- transition: 'opacity .15s linear',
44
- opacity: '0.5',
45
- };
46
- function IcicleRect(_a) {
47
- var _b;
48
- var x = _a.x, y = _a.y, width = _a.width, height = _a.height, color = _a.color, name = _a.name, onMouseEnter = _a.onMouseEnter, onMouseLeave = _a.onMouseLeave, onClick = _a.onClick, curPath = _a.curPath;
49
- var currentSearchString = (_b = selectQueryParam('search_string')) !== null && _b !== void 0 ? _b : '';
50
- var isFaded = curPath.length > 0 && name !== curPath[curPath.length - 1];
51
- var styles = isFaded ? fadedIcicleRectStyles : icicleRectStyles;
52
- return (_jsxs("g", __assign({ transform: "translate(".concat(x + 1, ", ").concat(y + 1, ")"), style: styles, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: onClick }, { children: [_jsx("rect", { x: 0, y: 0, width: width - 1, height: height - 1, style: {
53
- opacity: currentSearchString !== undefined &&
54
- currentSearchString !== '' &&
55
- !isSearchMatch(currentSearchString, name)
56
- ? 0.5
57
- : 1,
58
- fill: color,
59
- } }), width > 5 && (_jsx("svg", __assign({ width: width - 5, height: height }, { children: _jsx("text", __assign({ x: 5, y: 15, style: { fontSize: '12px' } }, { children: name })) })))] })));
60
- }
61
- export function nodeLabel(node, strings, mappings, locations, functions) {
62
- var _a, _b, _c;
63
- if (((_a = node.meta) === null || _a === void 0 ? void 0 : _a.locationIndex) === undefined)
64
- return '<unknown>';
65
- if (((_b = node.meta) === null || _b === void 0 ? void 0 : _b.locationIndex) === 0)
66
- return '<unknown>';
67
- var location = locations[node.meta.locationIndex - 1];
68
- var mapping = location.mappingIndex !== undefined || location.mappingIndex !== 0
69
- ? mappings[location.mappingIndex - 1]
70
- : undefined;
71
- var mappingFile = (mapping === null || mapping === void 0 ? void 0 : mapping.fileStringIndex) !== undefined ? strings[mapping.fileStringIndex] : '';
72
- var mappingString = "".concat(mappingFile !== '' ? '[' + ((_c = getLastItem(mappingFile)) !== null && _c !== void 0 ? _c : '') + '] ' : '');
73
- if (location.lines.length > 0) {
74
- var funcName = strings[functions[location.lines[node.meta.lineIndex].functionIndex - 1].nameStringIndex];
75
- return "".concat(mappingString, " ").concat(funcName);
76
- }
77
- var address = hexifyAddress(location.address);
78
- var fallback = "".concat(mappingString).concat(address);
79
- return fallback === '' ? '<unknown>' : fallback;
80
- }
81
- export function IcicleGraphNodes(_a) {
82
- var data = _a.data, strings = _a.strings, mappings = _a.mappings, locations = _a.locations, functions = _a.functions, x = _a.x, y = _a.y, xScale = _a.xScale, total = _a.total, totalWidth = _a.totalWidth, level = _a.level, setHoveringNode = _a.setHoveringNode, path = _a.path, setCurPath = _a.setCurPath, curPath = _a.curPath;
83
- var isDarkMode = useAppSelector(selectDarkMode);
84
- var isShiftDown = useIsShiftDown();
85
- var nodes = curPath.length === 0
86
- ? data
87
- : data.filter(function (d) { return d != null && curPath[0] === nodeLabel(d, strings, mappings, locations, functions); });
88
- var nextLevel = level + 1;
89
- return (_jsx("g", __assign({ transform: "translate(".concat(x, ", ").concat(y, ")") }, { children: nodes.map(function (d, i) {
90
- var cumulative = parseFloat(d.cumulative);
91
- var diff = parseFloat(d.diff);
92
- var start = nodes.slice(0, i).reduce(function (sum, d) { return sum + parseFloat(d.cumulative); }, 0);
93
- var nextCurPath = curPath.length === 0 ? [] : curPath.slice(1);
94
- var width = nextCurPath.length > 0 || (nextCurPath.length === 0 && curPath.length === 1)
95
- ? totalWidth
96
- : xScale(cumulative);
97
- if (width <= 1) {
98
- return null;
99
- }
100
- var name = nodeLabel(d, strings, mappings, locations, functions);
101
- var key = "".concat(level, "-").concat(i);
102
- var nextPath = path.concat([name]);
103
- var color = diffColor(diff, cumulative, isDarkMode);
104
- var onClick = function () {
105
- setCurPath(nextPath);
106
- };
107
- var xStart = xScale(start);
108
- var newXScale = nextCurPath.length === 0 && curPath.length === 1
109
- ? scaleLinear().domain([0, cumulative]).range([0, totalWidth])
110
- : xScale;
111
- var onMouseEnter = function () {
112
- if (isShiftDown)
113
- return;
114
- setHoveringNode(d);
115
- };
116
- var onMouseLeave = function () {
117
- if (isShiftDown)
118
- return;
119
- setHoveringNode(undefined);
120
- };
121
- return (_jsxs(Fragment, { children: [_jsx(IcicleRect, { x: xStart, y: 0, width: width, height: RowHeight, name: name, color: color, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, curPath: curPath }, "rect-".concat(key)), data !== undefined && data.length > 0 && (_jsx(IcicleGraphNodes, { data: d.children, strings: strings, mappings: mappings, locations: locations, functions: functions, x: xStart, y: RowHeight, xScale: newXScale, total: total, totalWidth: totalWidth, level: nextLevel, setHoveringNode: setHoveringNode, path: nextPath, curPath: nextCurPath, setCurPath: setCurPath }, "node-".concat(key)))] }, "node-".concat(key)));
122
- }) })));
123
- }
124
- var MemoizedIcicleGraphNodes = memo(IcicleGraphNodes);
125
- export function IcicleGraphRootNode(_a) {
126
- var node = _a.node, strings = _a.strings, mappings = _a.mappings, locations = _a.locations, functions = _a.functions, xScale = _a.xScale, total = _a.total, totalWidth = _a.totalWidth, setHoveringNode = _a.setHoveringNode, setCurPath = _a.setCurPath, curPath = _a.curPath;
127
- var isDarkMode = useAppSelector(selectDarkMode);
128
- var isShiftDown = useIsShiftDown();
129
- var cumulative = parseFloat(node.cumulative);
130
- var diff = parseFloat(node.diff);
131
- var color = diffColor(diff, cumulative, isDarkMode);
132
- var onClick = function () { return setCurPath([]); };
133
- var onMouseEnter = function () {
134
- if (isShiftDown)
135
- return;
136
- setHoveringNode(node);
137
- };
138
- var onMouseLeave = function () {
139
- if (isShiftDown)
140
- return;
141
- setHoveringNode(undefined);
142
- };
143
- var path = [];
144
- return (_jsxs("g", __assign({ transform: 'translate(0, 0)' }, { children: [_jsx(IcicleRect, { x: 0, y: 0, width: totalWidth, height: RowHeight, name: 'root', color: color, onClick: onClick, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, curPath: curPath }), _jsx(MemoizedIcicleGraphNodes, { data: node.children, strings: strings, mappings: mappings, locations: locations, functions: functions, x: 0, y: RowHeight, xScale: xScale, total: total, totalWidth: totalWidth, level: 0, setHoveringNode: setHoveringNode, path: path, curPath: curPath, setCurPath: setCurPath })] })));
145
- }
146
- var MemoizedIcicleGraphRootNode = memo(IcicleGraphRootNode);
147
- export default function IcicleGraph(_a) {
148
- var graph = _a.graph, width = _a.width, setCurPath = _a.setCurPath, curPath = _a.curPath, sampleUnit = _a.sampleUnit;
149
- var _b = useState(), hoveringNode = _b[0], setHoveringNode = _b[1];
150
- var _c = useState([0, 0]), pos = _c[0], setPos = _c[1];
151
- var _d = useState(0), height = _d[0], setHeight = _d[1];
152
- var svg = useRef(null);
153
- var ref = useRef(null);
154
- var rawDashboardItems = useURLState({
155
- param: 'dashboard_items',
156
- })[0];
157
- var dashboardItems = rawDashboardItems;
158
- useEffect(function () {
159
- if (ref.current != null) {
160
- setHeight(ref === null || ref === void 0 ? void 0 : ref.current.getBoundingClientRect().height);
161
- }
162
- }, [width, graph]);
163
- var total = useMemo(function () { return parseFloat(graph.total); }, [graph.total]);
164
- var xScale = useMemo(function () {
165
- if (width === undefined) {
166
- return function () { return 0; };
167
- }
168
- return scaleLinear().domain([0, total]).range([0, width]);
169
- }, [total, width]);
170
- if (graph.root === undefined || width === undefined) {
171
- return _jsx(_Fragment, {});
172
- }
173
- var throttledSetPos = throttle(setPos, 20);
174
- var onMouseMove = function (e) {
175
- // X/Y coordinate array relative to svg
176
- var rel = pointer(e);
177
- throttledSetPos([rel[0], rel[1]]);
178
- };
179
- return (_jsxs("div", __assign({ onMouseLeave: function () { return setHoveringNode(undefined); }, className: "relative" }, { children: [_jsx(GraphTooltip, { unit: sampleUnit, total: total, x: pos[0], y: pos[1], hoveringNode: hoveringNode, contextElement: svg.current, strings: graph.stringTable, mappings: graph.mapping, locations: graph.locations, functions: graph.function }), _jsx("div", __assign({ className: cx(dashboardItems.length > 1 ? 'top-[-46px] left-[25px]' : 'top-[-45px]', 'flex justify-start absolute ') }, { children: _jsx(Button, __assign({ color: "neutral", onClick: function () { return setCurPath([]); }, disabled: curPath.length === 0, className: "w-auto", variant: "neutral" }, { children: "Reset View" })) })), _jsx("svg", __assign({ className: "font-robotoMono", width: width, height: height, onMouseMove: onMouseMove, preserveAspectRatio: "xMinYMid", ref: svg }, { children: _jsx("g", __assign({ ref: ref }, { children: _jsx(MemoizedIcicleGraphRootNode, { node: graph.root, strings: graph.stringTable, mappings: graph.mapping, locations: graph.locations, functions: graph.function, setHoveringNode: setHoveringNode, curPath: curPath, setCurPath: setCurPath, xScale: xScale, total: total, totalWidth: width }) })) }))] })));
180
- }