@parca/profile 0.16.92 → 0.16.94
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/Callgraph/index.js +11 -10
- package/dist/IcicleGraph.js +6 -4
- package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts +2 -1
- package/dist/ProfileExplorer/ProfileExplorerCompare.js +1 -13
- package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts +2 -1
- package/dist/ProfileExplorer/index.d.ts +1 -1
- package/dist/ProfileExplorer/index.js +15 -33
- package/dist/ProfileIcicleGraph/index.js +2 -2
- package/dist/ProfileView/FilterByFunctionButton.d.ts +4 -1
- package/dist/ProfileView/FilterByFunctionButton.js +14 -11
- package/dist/ProfileView/ViewSelector.d.ts +13 -0
- package/dist/ProfileView/ViewSelector.js +80 -0
- package/dist/ProfileView/index.d.ts +4 -9
- package/dist/ProfileView/index.js +45 -68
- package/dist/ProfileViewWithData.d.ts +1 -1
- package/dist/ProfileViewWithData.js +8 -9
- package/dist/TopTable/index.d.ts +3 -1
- package/dist/TopTable/index.js +9 -8
- package/dist/styles.css +1 -1
- package/package.json +5 -5
- package/src/Callgraph/index.tsx +5 -4
- package/src/IcicleGraph.tsx +15 -3
- package/src/ProfileExplorer/ProfileExplorerCompare.tsx +2 -1
- package/src/ProfileExplorer/ProfileExplorerSingle.tsx +2 -1
- package/src/ProfileExplorer/index.tsx +21 -44
- package/src/ProfileIcicleGraph/index.tsx +3 -2
- package/src/ProfileView/FilterByFunctionButton.tsx +18 -18
- package/src/ProfileView/ViewSelector.tsx +117 -0
- package/src/ProfileView/index.tsx +107 -184
- package/src/ProfileViewWithData.tsx +7 -12
- package/src/TopTable/index.tsx +24 -13
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.94](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.93...@parca/profile@0.16.94) (2023-01-12)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.16.93](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.92...@parca/profile@0.16.93) (2023-01-11)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## [0.16.92](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.89...@parca/profile@0.16.92) (2023-01-11)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
package/dist/Callgraph/index.js
CHANGED
|
@@ -64,8 +64,7 @@ import * as d3 from 'd3';
|
|
|
64
64
|
import { Stage, Layer, Rect, Arrow, Text, Label } from 'react-konva';
|
|
65
65
|
import { Button } from '@parca/components';
|
|
66
66
|
import { jsonToDot, getCurvePoints } from './utils';
|
|
67
|
-
import {
|
|
68
|
-
import { isSearchMatch } from '@parca/functions';
|
|
67
|
+
import { isSearchMatch, selectQueryParam } from '@parca/functions';
|
|
69
68
|
import Tooltip from '../GraphTooltip';
|
|
70
69
|
import { DEFAULT_NODE_HEIGHT, GRAPH_MARGIN } from './constants';
|
|
71
70
|
var Node = function (_a) {
|
|
@@ -97,18 +96,18 @@ var Edge = function (_a) {
|
|
|
97
96
|
return (_jsx(Arrow, { points: points, bezier: true, stroke: color, strokeWidth: 3, pointerLength: 10, pointerWidth: 10, fill: color, opacity: isCurrentSearchMatch ? Number(opacity) : 0 }));
|
|
98
97
|
};
|
|
99
98
|
var Callgraph = function (_a) {
|
|
100
|
-
var _b, _c;
|
|
99
|
+
var _b, _c, _d;
|
|
101
100
|
var graph = _a.graph, sampleUnit = _a.sampleUnit, width = _a.width, colorRange = _a.colorRange;
|
|
102
101
|
var containerRef = useRef(null);
|
|
103
|
-
var
|
|
104
|
-
var
|
|
105
|
-
var
|
|
102
|
+
var _e = useState(null), graphData = _e[0], setGraphData = _e[1];
|
|
103
|
+
var _f = useState(null), hoveredNode = _f[0], setHoveredNode = _f[1];
|
|
104
|
+
var _g = useState({
|
|
106
105
|
scale: { x: 1, y: 1 },
|
|
107
106
|
x: 0,
|
|
108
107
|
y: 0,
|
|
109
|
-
}), stage =
|
|
108
|
+
}), stage = _g[0], setStage = _g[1];
|
|
110
109
|
var rawNodes = graph.nodes, total = graph.cumulative;
|
|
111
|
-
var currentSearchString =
|
|
110
|
+
var currentSearchString = (_b = selectQueryParam('search_string')) !== null && _b !== void 0 ? _b : '';
|
|
112
111
|
var isSearchEmpty = currentSearchString === undefined || currentSearchString === '';
|
|
113
112
|
useEffect(function () {
|
|
114
113
|
var getDataWithPositions = function () { return __awaiter(void 0, void 0, void 0, function () {
|
|
@@ -139,7 +138,9 @@ var Callgraph = function (_a) {
|
|
|
139
138
|
// 3. Render the graph with calculated layout in Canvas container
|
|
140
139
|
if (width == null || graphData == null)
|
|
141
140
|
return _jsx(_Fragment, {});
|
|
142
|
-
var
|
|
141
|
+
var _h = JSON.parse(graphData), gvizNodes = _h.objects, edges = _h.edges, boundingBox = _h.bb;
|
|
142
|
+
if (gvizNodes.length < 1)
|
|
143
|
+
return _jsx(_Fragment, { children: "Profile has no samples" });
|
|
143
144
|
var graphBB = boundingBox.split(',');
|
|
144
145
|
var bbWidth = Number(graphBB[2]);
|
|
145
146
|
var bbHeight = Number(graphBB[3]);
|
|
@@ -217,6 +218,6 @@ var Callgraph = function (_a) {
|
|
|
217
218
|
? true
|
|
218
219
|
: isSearchMatch(currentSearchString, node.functionName);
|
|
219
220
|
return (_jsx(Node, { node: node, hoveredNode: hoveredNode, setHoveredNode: setHoveredNode, isCurrentSearchMatch: isCurrentSearchMatch }, "node-".concat(node._gvid)));
|
|
220
|
-
})] })) })), _jsx(Tooltip, { hoveringNode: rawNodes.find(function (n) { return n.id === (hoveredNode === null || hoveredNode === void 0 ? void 0 : hoveredNode.data.id); }), unit: sampleUnit, total: +total, isFixed: false, x: (
|
|
221
|
+
})] })) })), _jsx(Tooltip, { hoveringNode: rawNodes.find(function (n) { return n.id === (hoveredNode === null || hoveredNode === void 0 ? void 0 : hoveredNode.data.id); }), unit: sampleUnit, total: +total, isFixed: false, x: (_c = hoveredNode === null || hoveredNode === void 0 ? void 0 : hoveredNode.mouseX) !== null && _c !== void 0 ? _c : 0, y: (_d = hoveredNode === null || hoveredNode === void 0 ? void 0 : hoveredNode.mouseY) !== null && _d !== void 0 ? _d : 0, contextElement: containerRef.current }), stage.scale.x !== 1 && (_jsx(Button, __assign({ className: "w-auto !absolute top-0 left-0", variant: "neutral", onClick: resetZoom }, { children: "Reset Zoom" })))] })) })));
|
|
221
222
|
};
|
|
222
223
|
export default Callgraph;
|
package/dist/IcicleGraph.js
CHANGED
|
@@ -27,9 +27,10 @@ import { throttle } from 'lodash';
|
|
|
27
27
|
import { pointer } from 'd3-selection';
|
|
28
28
|
import { scaleLinear } from 'd3-scale';
|
|
29
29
|
import GraphTooltip from './GraphTooltip';
|
|
30
|
-
import { diffColor, getLastItem, isSearchMatch } from '@parca/functions';
|
|
31
|
-
import { selectDarkMode,
|
|
30
|
+
import { diffColor, getLastItem, isSearchMatch, selectQueryParam } from '@parca/functions';
|
|
31
|
+
import { selectDarkMode, useAppSelector } from '@parca/store';
|
|
32
32
|
import useIsShiftDown from '@parca/components/src/hooks/useIsShiftDown';
|
|
33
|
+
import { Button } from '@parca/components';
|
|
33
34
|
import { hexifyAddress } from './utils';
|
|
34
35
|
var RowHeight = 26;
|
|
35
36
|
var icicleRectStyles = {
|
|
@@ -42,8 +43,9 @@ var fadedIcicleRectStyles = {
|
|
|
42
43
|
opacity: '0.5',
|
|
43
44
|
};
|
|
44
45
|
function IcicleRect(_a) {
|
|
46
|
+
var _b;
|
|
45
47
|
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;
|
|
46
|
-
var currentSearchString =
|
|
48
|
+
var currentSearchString = (_b = selectQueryParam('search_string')) !== null && _b !== void 0 ? _b : '';
|
|
47
49
|
var isFaded = curPath.length > 0 && name !== curPath[curPath.length - 1];
|
|
48
50
|
var styles = isFaded ? fadedIcicleRectStyles : icicleRectStyles;
|
|
49
51
|
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: {
|
|
@@ -169,5 +171,5 @@ export default function IcicleGraph(_a) {
|
|
|
169
171
|
var rel = pointer(e);
|
|
170
172
|
throttledSetPos([rel[0], rel[1]]);
|
|
171
173
|
};
|
|
172
|
-
return (_jsxs("div", __assign({ onMouseLeave: function () { return setHoveringNode(undefined); } }, { 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("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 }) })) }))] })));
|
|
174
|
+
return (_jsxs("div", __assign({ onMouseLeave: function () { return setHoveringNode(undefined); } }, { 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: "w-full flex justify-start" }, { children: _jsx(Button, __assign({ color: "neutral", onClick: function () { return setCurPath([]); }, disabled: curPath.length === 0, className: "w-auto", variant: "neutral" }, { children: "Reset zoom" })) })), _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 }) })) }))] })));
|
|
173
175
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import {
|
|
2
|
+
import { NavigateFunction } from '@parca/functions';
|
|
3
3
|
import { QueryServiceClient } from '@parca/client';
|
|
4
|
+
import { ProfileSelection } from '..';
|
|
4
5
|
import { QuerySelection } from '../ProfileSelector';
|
|
5
6
|
interface ProfileExplorerCompareProps {
|
|
6
7
|
queryClient: QueryServiceClient;
|
|
@@ -10,20 +10,8 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
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 { ProfileDiffSource, ProfileViewWithData } from '..';
|
|
26
13
|
import { Query } from '@parca/parser';
|
|
14
|
+
import { ProfileDiffSource, ProfileViewWithData } from '..';
|
|
27
15
|
import ProfileSelector from '../ProfileSelector';
|
|
28
16
|
var ProfileExplorerCompare = function (_a) {
|
|
29
17
|
var queryClient = _a.queryClient, queryA = _a.queryA, queryB = _a.queryB, profileA = _a.profileA, profileB = _a.profileB, selectQueryA = _a.selectQueryA, selectQueryB = _a.selectQueryB, selectProfileA = _a.selectProfileA, selectProfileB = _a.selectProfileB, closeProfile = _a.closeProfile, navigateTo = _a.navigateTo;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
+
import { NavigateFunction } from '@parca/functions';
|
|
2
3
|
import { QueryServiceClient } from '@parca/client';
|
|
3
|
-
import { ProfileSelection
|
|
4
|
+
import { ProfileSelection } from '..';
|
|
4
5
|
import { QuerySelection } from '../ProfileSelector';
|
|
5
6
|
interface ProfileExplorerSingleProps {
|
|
6
7
|
queryClient: QueryServiceClient;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
import { NavigateFunction } from '..';
|
|
3
2
|
import { QueryServiceClient } from '@parca/client';
|
|
3
|
+
import { NavigateFunction } from '@parca/functions';
|
|
4
4
|
interface ProfileExplorerProps {
|
|
5
5
|
queryClient: QueryServiceClient;
|
|
6
6
|
queryParams: any;
|
|
@@ -13,14 +13,14 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
13
13
|
import { ProfileSelectionFromParams, SuffixParams } from '..';
|
|
14
14
|
import ProfileExplorerSingle from './ProfileExplorerSingle';
|
|
15
15
|
import ProfileExplorerCompare from './ProfileExplorerCompare';
|
|
16
|
-
import {
|
|
17
|
-
import { Provider
|
|
16
|
+
import { store } from '@parca/store';
|
|
17
|
+
import { Provider } from 'react-redux';
|
|
18
18
|
import { DateTimeRange } from '@parca/components';
|
|
19
|
-
import { useEffect } from 'react';
|
|
20
19
|
var getExpressionAsAString = function (expression) {
|
|
21
20
|
var x = Array.isArray(expression) ? expression.join() : expression;
|
|
22
21
|
return x;
|
|
23
22
|
};
|
|
23
|
+
var DEFAULT_DASHBOARD_ITEMS = ['icicle'];
|
|
24
24
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
25
25
|
var sanitizeDateRange = function (time_selection_a, from_a, to_a) {
|
|
26
26
|
var range = DateTimeRange.fromRangeKey(time_selection_a);
|
|
@@ -49,12 +49,9 @@ var swapQueryParameters = function (o) {
|
|
|
49
49
|
var ProfileExplorerApp = function (_a) {
|
|
50
50
|
var _b, _c;
|
|
51
51
|
var queryClient = _a.queryClient, queryParams = _a.queryParams, navigateTo = _a.navigateTo;
|
|
52
|
-
var dispatch = useAppDispatch();
|
|
53
|
-
var compareMode = useAppSelector(selectCompareMode);
|
|
54
52
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
55
|
-
var from_a = queryParams.from_a, to_a = queryParams.to_a, merge_a = queryParams.merge_a, profile_name_a = queryParams.profile_name_a, labels_a = queryParams.labels_a, time_a = queryParams.time_a, time_selection_a = queryParams.time_selection_a, compare_a = queryParams.compare_a, from_b = queryParams.from_b, to_b = queryParams.to_b, merge_b = queryParams.merge_b, profile_name_b = queryParams.profile_name_b, labels_b = queryParams.labels_b, time_b = queryParams.time_b, time_selection_b = queryParams.time_selection_b, compare_b = queryParams.compare_b;
|
|
53
|
+
var from_a = queryParams.from_a, to_a = queryParams.to_a, merge_a = queryParams.merge_a, profile_name_a = queryParams.profile_name_a, labels_a = queryParams.labels_a, time_a = queryParams.time_a, time_selection_a = queryParams.time_selection_a, compare_a = queryParams.compare_a, from_b = queryParams.from_b, to_b = queryParams.to_b, merge_b = queryParams.merge_b, profile_name_b = queryParams.profile_name_b, labels_b = queryParams.labels_b, time_b = queryParams.time_b, time_selection_b = queryParams.time_selection_b, compare_b = queryParams.compare_b, filter_by_function = queryParams.filter_by_function, dashboard_items = queryParams.dashboard_items;
|
|
56
54
|
/* eslint-enable @typescript-eslint/naming-convention */
|
|
57
|
-
var filterByFunction = useAppSelector(selectFilterByFunction);
|
|
58
55
|
var sanitizedRange = sanitizeDateRange(time_selection_a, from_a, to_a);
|
|
59
56
|
time_selection_a = sanitizedRange.time_selection_a;
|
|
60
57
|
from_a = sanitizedRange.from_a;
|
|
@@ -67,18 +64,10 @@ var ProfileExplorerApp = function (_a) {
|
|
|
67
64
|
queryParams.expression_a = expression_a;
|
|
68
65
|
if (((_c = queryParams === null || queryParams === void 0 ? void 0 : queryParams.expression_b) !== null && _c !== void 0 ? _c : '') !== '')
|
|
69
66
|
queryParams.expression_b = expression_b;
|
|
70
|
-
useEffect(function () {
|
|
71
|
-
if (compare_a === 'true' && compare_b === 'true') {
|
|
72
|
-
dispatch(setCompare(true));
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
dispatch(setCompare(false));
|
|
76
|
-
}
|
|
77
|
-
}, [dispatch, compare_a, compare_b]);
|
|
78
67
|
var selectProfile = function (p, suffix) {
|
|
79
68
|
queryParams.expression_a = encodeURIComponent(queryParams.expression_a);
|
|
80
69
|
queryParams.expression_b = encodeURIComponent(queryParams.expression_b);
|
|
81
|
-
return navigateTo('/', __assign(__assign({}, queryParams), SuffixParams(p.HistoryParams(), suffix)));
|
|
70
|
+
return navigateTo('/', __assign(__assign(__assign({}, queryParams), SuffixParams(p.HistoryParams(), suffix)), { dashboard_items: dashboard_items !== null && dashboard_items !== void 0 ? dashboard_items : DEFAULT_DASHBOARD_ITEMS }));
|
|
82
71
|
};
|
|
83
72
|
var selectProfileA = function (p) {
|
|
84
73
|
return selectProfile(p, '_a');
|
|
@@ -96,7 +85,7 @@ var ProfileExplorerApp = function (_a) {
|
|
|
96
85
|
profile_name: profile_name_a,
|
|
97
86
|
timeSelection: time_selection_a,
|
|
98
87
|
};
|
|
99
|
-
var profile_1 = ProfileSelectionFromParams(expression_a, from_a, to_a, merge_a, labels_a, profile_name_a, time_a,
|
|
88
|
+
var profile_1 = ProfileSelectionFromParams(expression_a, from_a, to_a, merge_a, labels_a, profile_name_a, time_a, filter_by_function);
|
|
100
89
|
var selectQuery = function (q) {
|
|
101
90
|
return navigateTo('/', __assign(__assign({}, filterSuffix(queryParams, '_a')), {
|
|
102
91
|
expression_a: encodeURIComponent(q.expression),
|
|
@@ -104,12 +93,12 @@ var ProfileExplorerApp = function (_a) {
|
|
|
104
93
|
to_a: q.to.toString(),
|
|
105
94
|
merge_a: q.merge,
|
|
106
95
|
time_selection_a: q.timeSelection,
|
|
107
|
-
|
|
96
|
+
dashboard_items: dashboard_items !== null && dashboard_items !== void 0 ? dashboard_items : DEFAULT_DASHBOARD_ITEMS,
|
|
108
97
|
}));
|
|
109
98
|
};
|
|
110
99
|
var selectProfile_1 = function (p) {
|
|
111
100
|
queryParams.expression_a = encodeURIComponent(queryParams.expression_a);
|
|
112
|
-
return navigateTo('/', __assign(__assign({}, queryParams), SuffixParams(p.HistoryParams(), '_a')));
|
|
101
|
+
return navigateTo('/', __assign(__assign(__assign({}, queryParams), SuffixParams(p.HistoryParams(), '_a')), { dashboard_items: dashboard_items !== null && dashboard_items !== void 0 ? dashboard_items : DEFAULT_DASHBOARD_ITEMS }));
|
|
113
102
|
};
|
|
114
103
|
var compareProfile = function () {
|
|
115
104
|
var compareQuery = {
|
|
@@ -131,14 +120,7 @@ var ProfileExplorerApp = function (_a) {
|
|
|
131
120
|
if (profile_1 != null) {
|
|
132
121
|
compareQuery = __assign(__assign({}, SuffixParams(profile_1.HistoryParams(), '_a')), compareQuery);
|
|
133
122
|
}
|
|
134
|
-
|
|
135
|
-
currentProfileView: 'icicle',
|
|
136
|
-
});
|
|
137
|
-
batch(function () {
|
|
138
|
-
dispatch(setCompare(!compareMode));
|
|
139
|
-
dispatch(setSearchNodeString(undefined));
|
|
140
|
-
});
|
|
141
|
-
void navigateTo('/', compareQuery);
|
|
123
|
+
void navigateTo('/', __assign(__assign({}, compareQuery), { search_string: '', dashboard_items: dashboard_items !== null && dashboard_items !== void 0 ? dashboard_items : DEFAULT_DASHBOARD_ITEMS }));
|
|
142
124
|
};
|
|
143
125
|
return (_jsx(ProfileExplorerSingle, { queryClient: queryClient, query: query_1, profile: profile_1, selectQuery: selectQuery, selectProfile: selectProfile_1, compareProfile: compareProfile, navigateTo: navigateTo }));
|
|
144
126
|
}
|
|
@@ -169,7 +151,8 @@ var ProfileExplorerApp = function (_a) {
|
|
|
169
151
|
to_a: q.to.toString(),
|
|
170
152
|
merge_a: q.merge,
|
|
171
153
|
time_selection_a: q.timeSelection,
|
|
172
|
-
|
|
154
|
+
filter_by_function: filter_by_function !== null && filter_by_function !== void 0 ? filter_by_function : '',
|
|
155
|
+
dashboard_items: dashboard_items !== null && dashboard_items !== void 0 ? dashboard_items : DEFAULT_DASHBOARD_ITEMS,
|
|
173
156
|
}));
|
|
174
157
|
};
|
|
175
158
|
var selectQueryB = function (q) {
|
|
@@ -181,7 +164,8 @@ var ProfileExplorerApp = function (_a) {
|
|
|
181
164
|
to_b: q.to.toString(),
|
|
182
165
|
merge_b: q.merge,
|
|
183
166
|
time_selection_b: q.timeSelection,
|
|
184
|
-
|
|
167
|
+
filter_by_function: filter_by_function !== null && filter_by_function !== void 0 ? filter_by_function : '',
|
|
168
|
+
dashboard_items: dashboard_items !== null && dashboard_items !== void 0 ? dashboard_items : DEFAULT_DASHBOARD_ITEMS,
|
|
185
169
|
}));
|
|
186
170
|
};
|
|
187
171
|
var closeProfile = function (card) {
|
|
@@ -189,12 +173,10 @@ var ProfileExplorerApp = function (_a) {
|
|
|
189
173
|
if (card === 'A') {
|
|
190
174
|
newQueryParameters = swapQueryParameters(queryParams);
|
|
191
175
|
}
|
|
192
|
-
batch(function () {
|
|
193
|
-
dispatch(setCompare(!compareMode));
|
|
194
|
-
dispatch(setSearchNodeString(undefined));
|
|
195
|
-
});
|
|
196
176
|
return navigateTo('/', __assign(__assign({}, filterSuffix(newQueryParameters, '_b')), {
|
|
197
177
|
compare_a: 'false',
|
|
178
|
+
compare_b: 'false',
|
|
179
|
+
search_string: '',
|
|
198
180
|
}));
|
|
199
181
|
};
|
|
200
182
|
return (_jsx(ProfileExplorerCompare, { queryClient: queryClient, queryA: queryA, queryB: queryB, profileA: profileA, profileB: profileB, selectQueryA: selectQueryA, selectQueryB: selectQueryB, selectProfileA: selectProfileA, selectProfileB: selectProfileB, closeProfile: closeProfile, navigateTo: navigateTo }));
|
|
@@ -10,15 +10,15 @@ var __assign = (this && this.__assign) || function () {
|
|
|
10
10
|
return __assign.apply(this, arguments);
|
|
11
11
|
};
|
|
12
12
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
13
|
-
import { useAppSelector, selectCompareMode } from '@parca/store';
|
|
14
13
|
import { useContainerDimensions } from '@parca/dynamicsize';
|
|
15
14
|
import DiffLegend from '../components/DiffLegend';
|
|
16
15
|
import IcicleGraph from '../IcicleGraph';
|
|
16
|
+
import { selectQueryParam } from '@parca/functions';
|
|
17
17
|
import { useEffect, useMemo } from 'react';
|
|
18
18
|
var numberFormatter = new Intl.NumberFormat('en-US');
|
|
19
19
|
var ProfileIcicleGraph = function (_a) {
|
|
20
20
|
var graph = _a.graph, curPath = _a.curPath, setNewCurPath = _a.setNewCurPath, sampleUnit = _a.sampleUnit, onContainerResize = _a.onContainerResize;
|
|
21
|
-
var compareMode =
|
|
21
|
+
var compareMode = Boolean(selectQueryParam('compare_a')) && Boolean(selectQueryParam('compare_b'));
|
|
22
22
|
var _b = useContainerDimensions(), ref = _b.ref, dimensions = _b.dimensions;
|
|
23
23
|
useEffect(function () {
|
|
24
24
|
if (dimensions === undefined)
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
|
-
|
|
2
|
+
import { NavigateFunction } from '@parca/functions';
|
|
3
|
+
declare const FilterByFunctionButton: ({ navigateTo, }: {
|
|
4
|
+
navigateTo: NavigateFunction | undefined;
|
|
5
|
+
}) => JSX.Element;
|
|
3
6
|
export default FilterByFunctionButton;
|
|
@@ -12,22 +12,25 @@ 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 { Input } from '@parca/components';
|
|
15
|
-
import {
|
|
15
|
+
import { useURLState } from '@parca/functions';
|
|
16
16
|
import { Icon } from '@iconify/react';
|
|
17
17
|
import { useCallback, useMemo, useState } from 'react';
|
|
18
|
-
var FilterByFunctionButton = function () {
|
|
19
|
-
var
|
|
20
|
-
var
|
|
21
|
-
var
|
|
18
|
+
var FilterByFunctionButton = function (_a) {
|
|
19
|
+
var navigateTo = _a.navigateTo;
|
|
20
|
+
var _b = useURLState({ param: 'filter_by_function', navigateTo: navigateTo }), storeValue = _b[0], setStoreValue = _b[1];
|
|
21
|
+
var _c = useState(storeValue), localValue = _c[0], setLocalValue = _c[1];
|
|
22
22
|
var isClearAction = useMemo(function () {
|
|
23
|
-
return
|
|
24
|
-
}, [
|
|
23
|
+
return localValue === storeValue && localValue != null && localValue !== '';
|
|
24
|
+
}, [localValue, storeValue]);
|
|
25
25
|
var onAction = useCallback(function () {
|
|
26
|
-
dispatch(setFilterByFunction(isClearAction ? undefined : value));
|
|
27
26
|
if (isClearAction) {
|
|
28
|
-
|
|
27
|
+
setLocalValue('');
|
|
28
|
+
setStoreValue('');
|
|
29
29
|
}
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
else {
|
|
31
|
+
setStoreValue(localValue);
|
|
32
|
+
}
|
|
33
|
+
}, [localValue, isClearAction, setStoreValue]);
|
|
34
|
+
return (_jsx(Input, { placeholder: "Filter by function", className: "text-sm", onAction: onAction, onChange: function (e) { return setLocalValue(e.target.value); }, value: localValue !== null && localValue !== void 0 ? localValue : '', onBlur: function () { return setLocalValue(storeValue); }, actionIcon: isClearAction ? _jsx(Icon, { icon: "ep:circle-close" }) : _jsx(Icon, { icon: "ep:arrow-right" }) }));
|
|
32
35
|
};
|
|
33
36
|
export default FilterByFunctionButton;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import { NavigateFunction } from '@parca/functions';
|
|
3
|
+
interface Props {
|
|
4
|
+
position: number;
|
|
5
|
+
defaultValue: string;
|
|
6
|
+
navigateTo?: NavigateFunction;
|
|
7
|
+
placeholderText?: string;
|
|
8
|
+
primary?: boolean;
|
|
9
|
+
addView?: boolean;
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare const ViewSelector: ({ defaultValue, navigateTo, position, placeholderText, primary, addView, disabled, }: Props) => JSX.Element;
|
|
13
|
+
export default ViewSelector;
|
|
@@ -0,0 +1,80 @@
|
|
|
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 { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } 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 { Select } from '@parca/components';
|
|
26
|
+
import { useURLState } from '@parca/functions';
|
|
27
|
+
import useUIFeatureFlag from '@parca/functions/useUIFeatureFlag';
|
|
28
|
+
var ViewSelector = function (_a) {
|
|
29
|
+
var defaultValue = _a.defaultValue, navigateTo = _a.navigateTo, position = _a.position, placeholderText = _a.placeholderText, _b = _a.primary, primary = _b === void 0 ? false : _b, _c = _a.addView, addView = _c === void 0 ? false : _c, _d = _a.disabled, disabled = _d === void 0 ? false : _d;
|
|
30
|
+
var callgraphEnabled = useUIFeatureFlag('callgraph')[0];
|
|
31
|
+
var _e = useURLState({
|
|
32
|
+
param: 'dashboard_items',
|
|
33
|
+
navigateTo: navigateTo,
|
|
34
|
+
}), dashboardItems = _e[0], setDashboardItems = _e[1];
|
|
35
|
+
var allItems = [
|
|
36
|
+
{ key: 'table', canBeSelected: !dashboardItems.includes('table') },
|
|
37
|
+
{ key: 'icicle', canBeSelected: !dashboardItems.includes('icicle') },
|
|
38
|
+
];
|
|
39
|
+
if (callgraphEnabled) {
|
|
40
|
+
allItems.push({
|
|
41
|
+
key: 'callgraph',
|
|
42
|
+
canBeSelected: !dashboardItems.includes('callgraph'),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
var getOption = function (_a) {
|
|
46
|
+
var key = _a.key, supportingText = _a.supportingText;
|
|
47
|
+
var capitalizeFirstLetter = function (string) {
|
|
48
|
+
return "".concat(string.charAt(0).toUpperCase()).concat(string.slice(1));
|
|
49
|
+
};
|
|
50
|
+
var title = capitalizeFirstLetter(key);
|
|
51
|
+
return {
|
|
52
|
+
active: _jsx(_Fragment, { children: title }),
|
|
53
|
+
expanded: (_jsxs(_Fragment, { children: [_jsx("span", { children: title }), supportingText !== null && _jsx("span", __assign({ className: "text-xs" }, { children: supportingText }))] })),
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
var items = allItems.map(function (item) { return ({
|
|
57
|
+
key: item.key,
|
|
58
|
+
disabled: !item.canBeSelected,
|
|
59
|
+
element: getOption(item),
|
|
60
|
+
}); });
|
|
61
|
+
var onSelection = function (value) {
|
|
62
|
+
if (addView) {
|
|
63
|
+
setDashboardItems([dashboardItems[0], value]);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
var isOnlyChart = dashboardItems.length === 1;
|
|
67
|
+
if (isOnlyChart) {
|
|
68
|
+
setDashboardItems([value]);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
// Note: this will need to be updated if we ever have more more than 2 panels
|
|
72
|
+
var isFirstChart = position === 0;
|
|
73
|
+
var newDashboardItems = isFirstChart
|
|
74
|
+
? [value, dashboardItems[1]]
|
|
75
|
+
: [dashboardItems[0], value];
|
|
76
|
+
setDashboardItems(newDashboardItems);
|
|
77
|
+
};
|
|
78
|
+
return (_jsx(Select, { items: items, selectedKey: defaultValue, onSelection: onSelection, placeholder: placeholderText !== null && placeholderText !== void 0 ? placeholderText : 'Select view type...', primary: primary, disabled: disabled }));
|
|
79
|
+
};
|
|
80
|
+
export default ViewSelector;
|
|
@@ -3,7 +3,9 @@ import { QueryServiceClient, Flamegraph, Top, Callgraph as CallgraphType } from
|
|
|
3
3
|
import { ResizeHandler } from '../ProfileIcicleGraph';
|
|
4
4
|
import { ProfileSource } from '../ProfileSource';
|
|
5
5
|
import '../ProfileView.styles.css';
|
|
6
|
-
type NavigateFunction = (path: string, queryParams: any
|
|
6
|
+
type NavigateFunction = (path: string, queryParams: any, options?: {
|
|
7
|
+
replace?: boolean;
|
|
8
|
+
}) => void;
|
|
7
9
|
export interface FlamegraphData {
|
|
8
10
|
loading: boolean;
|
|
9
11
|
data?: Flamegraph;
|
|
@@ -19,17 +21,11 @@ interface CallgraphData {
|
|
|
19
21
|
data?: CallgraphType;
|
|
20
22
|
error?: any;
|
|
21
23
|
}
|
|
22
|
-
export type VisualizationType = 'icicle' | 'table' | 'callgraph' | 'both';
|
|
23
|
-
export interface ProfileVisState {
|
|
24
|
-
currentView: VisualizationType;
|
|
25
|
-
setCurrentView: (view: VisualizationType) => void;
|
|
26
|
-
}
|
|
27
24
|
export interface ProfileViewProps {
|
|
28
25
|
flamegraphData?: FlamegraphData;
|
|
29
26
|
topTableData?: TopTableData;
|
|
30
27
|
callgraphData?: CallgraphData;
|
|
31
28
|
sampleUnit: string;
|
|
32
|
-
profileVisState: ProfileVisState;
|
|
33
29
|
profileSource?: ProfileSource;
|
|
34
30
|
queryClient?: QueryServiceClient;
|
|
35
31
|
navigateTo?: NavigateFunction;
|
|
@@ -37,6 +33,5 @@ export interface ProfileViewProps {
|
|
|
37
33
|
onDownloadPProf: () => void;
|
|
38
34
|
onFlamegraphContainerResize?: ResizeHandler;
|
|
39
35
|
}
|
|
40
|
-
export declare const
|
|
41
|
-
export declare const ProfileView: ({ flamegraphData, topTableData, callgraphData, sampleUnit, profileSource, queryClient, navigateTo, profileVisState, onDownloadPProf, onFlamegraphContainerResize, }: ProfileViewProps) => JSX.Element;
|
|
36
|
+
export declare const ProfileView: ({ flamegraphData, topTableData, callgraphData, sampleUnit, profileSource, queryClient, navigateTo, onDownloadPProf, onFlamegraphContainerResize, }: ProfileViewProps) => JSX.Element;
|
|
42
37
|
export {};
|