@parca/profile 0.16.0 → 0.16.22
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 +40 -0
- package/dist/Callgraph/Edge/index.d.ts +22 -0
- package/dist/Callgraph/Edge/index.js +30 -0
- package/dist/Callgraph/Node/index.d.ts +19 -0
- package/dist/Callgraph/Node/index.js +37 -0
- package/dist/Callgraph/index.d.ts +8 -0
- package/dist/Callgraph/index.js +137 -0
- package/dist/Callgraph/mockData/index.d.ts +148 -0
- package/dist/Callgraph/mockData/index.js +577 -0
- package/dist/Callgraph/utils.d.ts +19 -0
- package/dist/Callgraph/utils.js +82 -0
- package/dist/GraphTooltip/index.d.ts +19 -0
- package/dist/GraphTooltip/index.js +119 -0
- package/dist/IcicleGraph.d.ts +35 -0
- package/dist/IcicleGraph.js +139 -0
- package/dist/MatchersInput/index.d.ts +23 -0
- package/dist/MatchersInput/index.js +479 -0
- package/dist/MetricsCircle/index.d.ts +7 -0
- package/dist/MetricsCircle/index.js +18 -0
- package/dist/MetricsGraph/index.d.ts +35 -0
- package/dist/MetricsGraph/index.js +349 -0
- package/dist/MetricsSeries/index.d.ts +11 -0
- package/dist/MetricsSeries/index.js +21 -0
- package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts +19 -0
- package/dist/ProfileExplorer/ProfileExplorerCompare.js +38 -0
- package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts +15 -0
- package/dist/ProfileExplorer/ProfileExplorerSingle.js +19 -0
- package/dist/ProfileExplorer/index.d.ts +9 -0
- package/dist/ProfileExplorer/index.js +203 -0
- package/dist/ProfileIcicleGraph.d.ts +10 -0
- package/dist/ProfileIcicleGraph.js +28 -0
- package/dist/ProfileMetricsGraph/index.d.ts +22 -0
- package/dist/ProfileMetricsGraph/index.js +127 -0
- package/dist/ProfileSVG.module.css +3 -0
- package/dist/ProfileSelector/CompareButton.d.ts +5 -0
- package/dist/ProfileSelector/CompareButton.js +41 -0
- package/dist/ProfileSelector/MergeButton.d.ts +5 -0
- package/dist/ProfileSelector/MergeButton.js +41 -0
- package/dist/ProfileSelector/index.d.ts +29 -0
- package/dist/ProfileSelector/index.js +133 -0
- package/dist/ProfileSource.d.ts +88 -0
- package/dist/ProfileSource.js +239 -0
- package/dist/ProfileTypeSelector/index.d.ts +20 -0
- package/dist/ProfileTypeSelector/index.js +138 -0
- package/dist/ProfileView.d.ts +39 -0
- package/dist/ProfileView.js +111 -0
- package/dist/ProfileView.styles.css +3 -0
- package/dist/ProfileViewWithData.d.ts +11 -0
- package/dist/ProfileViewWithData.js +116 -0
- package/dist/TopTable.d.ts +9 -0
- package/dist/TopTable.js +140 -0
- package/dist/TopTable.styles.css +7 -0
- package/dist/components/DiffLegend.d.ts +2 -0
- package/dist/components/DiffLegend.js +62 -0
- package/dist/components/ProfileShareButton/ResultBox.d.ts +6 -0
- package/dist/components/ProfileShareButton/ResultBox.js +46 -0
- package/dist/components/ProfileShareButton/index.d.ts +7 -0
- package/dist/components/ProfileShareButton/index.js +119 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +64 -0
- package/dist/styles.css +1 -0
- package/dist/useDelayedLoader.d.ts +5 -0
- package/dist/useDelayedLoader.js +33 -0
- package/dist/useQuery.d.ts +13 -0
- package/dist/useQuery.js +41 -0
- package/dist/utils.d.ts +4 -0
- package/dist/utils.js +83 -0
- package/package.json +12 -8
- package/src/Callgraph/Edge/index.tsx +59 -0
- package/src/Callgraph/Node/index.tsx +66 -0
- package/src/Callgraph/index.tsx +169 -0
- package/src/Callgraph/mockData/index.ts +605 -0
- package/src/Callgraph/utils.ts +116 -0
- package/src/GraphTooltip/index.tsx +245 -0
- package/src/IcicleGraph.tsx +3 -3
- package/src/MatchersInput/index.tsx +698 -0
- package/src/MetricsCircle/index.tsx +28 -0
- package/src/MetricsGraph/index.tsx +614 -0
- package/src/MetricsSeries/index.tsx +38 -0
- package/src/ProfileExplorer/ProfileExplorerCompare.tsx +109 -0
- package/src/ProfileExplorer/ProfileExplorerSingle.tsx +72 -0
- package/src/ProfileExplorer/index.tsx +377 -0
- package/src/ProfileMetricsGraph/index.tsx +143 -0
- package/src/ProfileSelector/CompareButton.tsx +72 -0
- package/src/ProfileSelector/MergeButton.tsx +72 -0
- package/src/ProfileSelector/index.tsx +270 -0
- package/src/ProfileTypeSelector/index.tsx +180 -0
- package/src/ProfileView.tsx +2 -7
- package/src/index.tsx +11 -0
- package/src/useQuery.tsx +1 -0
- package/tailwind.config.js +8 -0
- package/tsconfig.json +7 -3
- package/typings.d.ts +14 -0
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
13
|
+
var t = {};
|
|
14
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
15
|
+
t[p] = s[p];
|
|
16
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
17
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
18
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
19
|
+
t[p[i]] = s[p[i]];
|
|
20
|
+
}
|
|
21
|
+
return t;
|
|
22
|
+
};
|
|
23
|
+
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
24
|
+
import { getLastItem, valueFormatter } from '@parca/functions';
|
|
25
|
+
import { hexifyAddress } from '../';
|
|
26
|
+
import { useState, useEffect } from 'react';
|
|
27
|
+
import { usePopper } from 'react-popper';
|
|
28
|
+
var virtualElement = {
|
|
29
|
+
getBoundingClientRect: function () {
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
31
|
+
return ({
|
|
32
|
+
width: 0,
|
|
33
|
+
height: 0,
|
|
34
|
+
top: 0,
|
|
35
|
+
left: 0,
|
|
36
|
+
right: 0,
|
|
37
|
+
bottom: 0,
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
function generateGetBoundingClientRect(contextElement, x, y) {
|
|
42
|
+
if (x === void 0) { x = 0; }
|
|
43
|
+
if (y === void 0) { y = 0; }
|
|
44
|
+
var domRect = contextElement.getBoundingClientRect();
|
|
45
|
+
return function () {
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
47
|
+
return ({
|
|
48
|
+
width: 0,
|
|
49
|
+
height: 0,
|
|
50
|
+
top: domRect.y + y,
|
|
51
|
+
left: domRect.x + x,
|
|
52
|
+
right: domRect.x + x,
|
|
53
|
+
bottom: domRect.y + y,
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
var TooltipMetaInfo = function (_a) {
|
|
58
|
+
var _b, _c, _d, _e, _f, _g, _h, _j;
|
|
59
|
+
var hoveringNode = _a.hoveringNode;
|
|
60
|
+
if (hoveringNode.meta === undefined)
|
|
61
|
+
return _jsx(_Fragment, {});
|
|
62
|
+
return (_jsxs(_Fragment, { children: [((_b = hoveringNode.meta.function) === null || _b === void 0 ? void 0 : _b.filename) !== undefined &&
|
|
63
|
+
((_c = hoveringNode.meta.function) === null || _c === void 0 ? void 0 : _c.filename) !== '' && (_jsxs("tr", { children: [_jsx("td", __assign({ className: "w-1/5" }, { children: "File" })), _jsxs("td", __assign({ className: "w-4/5 break-all" }, { children: [hoveringNode.meta.function.filename, ((_d = hoveringNode.meta.line) === null || _d === void 0 ? void 0 : _d.line) !== undefined && ((_e = hoveringNode.meta.line) === null || _e === void 0 ? void 0 : _e.line) !== '0'
|
|
64
|
+
? " +".concat(hoveringNode.meta.line.line.toString())
|
|
65
|
+
: "".concat(((_f = hoveringNode.meta.function) === null || _f === void 0 ? void 0 : _f.startLine) !== undefined &&
|
|
66
|
+
((_g = hoveringNode.meta.function) === null || _g === void 0 ? void 0 : _g.startLine) !== '0'
|
|
67
|
+
? " +".concat(hoveringNode.meta.function.startLine)
|
|
68
|
+
: '')] }))] })), ((_h = hoveringNode.meta.location) === null || _h === void 0 ? void 0 : _h.address) !== undefined &&
|
|
69
|
+
((_j = hoveringNode.meta.location) === null || _j === void 0 ? void 0 : _j.address) !== '0' && (_jsxs("tr", { children: [_jsx("td", __assign({ className: "w-1/5" }, { children: "Address" })), _jsx("td", __assign({ className: "w-4/5 break-all" }, { children: ' 0x' + hoveringNode.meta.location.address.toString() }))] })), hoveringNode.meta.mapping !== undefined && hoveringNode.meta.mapping.file !== '' && (_jsxs("tr", { children: [_jsx("td", __assign({ className: "w-1/5" }, { children: "Binary" })), _jsx("td", __assign({ className: "w-4/5 break-all" }, { children: getLastItem(hoveringNode.meta.mapping.file) }))] }))] }));
|
|
70
|
+
};
|
|
71
|
+
var GraphTooltipContent = function (_a) {
|
|
72
|
+
var hoveringNode = _a.hoveringNode, unit = _a.unit, total = _a.total, isFixed = _a.isFixed;
|
|
73
|
+
var hoveringNodeCumulative = parseFloat(hoveringNode.cumulative);
|
|
74
|
+
var diff = hoveringNode.diff === undefined ? 0 : parseFloat(hoveringNode.diff);
|
|
75
|
+
var prevValue = hoveringNodeCumulative - diff;
|
|
76
|
+
var diffRatio = Math.abs(diff) > 0 ? diff / prevValue : 0;
|
|
77
|
+
var diffSign = diff > 0 ? '+' : '';
|
|
78
|
+
var diffValueText = diffSign + valueFormatter(diff, unit, 1);
|
|
79
|
+
var diffPercentageText = diffSign + (diffRatio * 100).toFixed(2) + '%';
|
|
80
|
+
var diffText = "".concat(diffValueText, " (").concat(diffPercentageText, ")");
|
|
81
|
+
var metaRows = hoveringNode.meta === undefined ? _jsx(_Fragment, {}) : _jsx(TooltipMetaInfo, { hoveringNode: hoveringNode });
|
|
82
|
+
return (_jsx("div", __assign({ className: "flex ".concat(isFixed ? 'w-full h-36' : '') }, { children: _jsx("div", __assign({ className: "m-auto w-full ".concat(isFixed ? 'w-full h-36' : '') }, { children: _jsx("div", __assign({ className: "border-gray-300 dark:border-gray-500 bg-gray-50 dark:bg-gray-900 rounded-lg p-3 shadow-lg opacity-90", style: { borderWidth: 1 } }, { children: _jsx("div", __assign({ className: "flex flex-row" }, { children: _jsxs("div", __assign({ className: "ml-2 mr-6" }, { children: [_jsx("span", __assign({ className: "font-semibold break-all" }, { children: hoveringNode.meta === undefined ? (_jsx("p", { children: "root" })) : (_jsx(_Fragment, { children: hoveringNode.meta.function !== undefined &&
|
|
83
|
+
hoveringNode.meta.function.name !== '' ? (_jsx("p", { children: hoveringNode.meta.function.name })) : (_jsx(_Fragment, { children: hoveringNode.meta.location !== undefined &&
|
|
84
|
+
parseInt(hoveringNode.meta.location.address, 10) !== 0 ? (_jsx("p", { children: hexifyAddress(hoveringNode.meta.location.address) })) : (_jsx("p", { children: "unknown" })) })) })) })), _jsx("span", __assign({ className: "text-gray-700 dark:text-gray-300 my-2" }, { children: _jsx("table", __assign({ className: "table-fixed" }, { children: _jsxs("tbody", { children: [_jsxs("tr", { children: [_jsx("td", __assign({ className: "w-1/5" }, { children: "Cumulative" })), _jsxs("td", __assign({ className: "w-4/5" }, { children: [valueFormatter(hoveringNodeCumulative, unit, 2), " (", ((hoveringNodeCumulative * 100) / total).toFixed(2), "%)"] }))] }), hoveringNode.diff !== undefined && diff !== 0 && (_jsxs("tr", { children: [_jsx("td", __assign({ className: "w-1/5" }, { children: "Diff" })), _jsx("td", __assign({ className: "w-4/5" }, { children: diffText }))] })), metaRows] }) })) }))] })) })) })) })) })));
|
|
85
|
+
};
|
|
86
|
+
var GraphTooltip = function (_a) {
|
|
87
|
+
var x = _a.x, y = _a.y, unit = _a.unit, total = _a.total, hoveringNode = _a.hoveringNode, contextElement = _a.contextElement, _b = _a.isFixed, isFixed = _b === void 0 ? false : _b, _c = _a.virtualContextElement, virtualContextElement = _c === void 0 ? true : _c;
|
|
88
|
+
var _d = useState(null), popperElement = _d[0], setPopperElement = _d[1];
|
|
89
|
+
var _e = usePopper(virtualContextElement ? virtualElement : contextElement, popperElement, {
|
|
90
|
+
placement: 'auto-start',
|
|
91
|
+
strategy: 'absolute',
|
|
92
|
+
modifiers: [
|
|
93
|
+
{
|
|
94
|
+
name: 'preventOverflow',
|
|
95
|
+
options: {
|
|
96
|
+
tether: false,
|
|
97
|
+
altAxis: true,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
name: 'offset',
|
|
102
|
+
options: {
|
|
103
|
+
offset: [30, 30],
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
}), styles = _e.styles, attributes = _e.attributes, popperProps = __rest(_e, ["styles", "attributes"]);
|
|
108
|
+
var update = popperProps.update;
|
|
109
|
+
useEffect(function () {
|
|
110
|
+
if (contextElement != null) {
|
|
111
|
+
virtualElement.getBoundingClientRect = generateGetBoundingClientRect(contextElement, x, y);
|
|
112
|
+
void (update === null || update === void 0 ? void 0 : update());
|
|
113
|
+
}
|
|
114
|
+
}, [x, y, contextElement, update]);
|
|
115
|
+
if (hoveringNode === undefined || hoveringNode == null)
|
|
116
|
+
return _jsx(_Fragment, {});
|
|
117
|
+
return isFixed ? (_jsx(GraphTooltipContent, { hoveringNode: hoveringNode, unit: unit, total: total, isFixed: isFixed })) : (_jsx("div", __assign({ ref: setPopperElement, style: styles.popper }, attributes.popper, { children: _jsx(GraphTooltipContent, { hoveringNode: hoveringNode, unit: unit, total: total, isFixed: isFixed }) })));
|
|
118
|
+
};
|
|
119
|
+
export default GraphTooltip;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Flamegraph, FlamegraphNode, FlamegraphRootNode } from '@parca/client';
|
|
2
|
+
interface IcicleGraphProps {
|
|
3
|
+
graph: Flamegraph;
|
|
4
|
+
sampleUnit: string;
|
|
5
|
+
width?: number;
|
|
6
|
+
curPath: string[];
|
|
7
|
+
setCurPath: (path: string[]) => void;
|
|
8
|
+
}
|
|
9
|
+
interface IcicleGraphNodesProps {
|
|
10
|
+
data: FlamegraphNode[];
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
total: number;
|
|
14
|
+
totalWidth: number;
|
|
15
|
+
level: number;
|
|
16
|
+
curPath: string[];
|
|
17
|
+
setCurPath: (path: string[]) => void;
|
|
18
|
+
setHoveringNode: (node: FlamegraphNode | FlamegraphRootNode | undefined) => void;
|
|
19
|
+
path: string[];
|
|
20
|
+
xScale: (value: number) => number;
|
|
21
|
+
}
|
|
22
|
+
interface IcicleGraphRootNodeProps {
|
|
23
|
+
node: FlamegraphRootNode;
|
|
24
|
+
xScale: (value: number) => number;
|
|
25
|
+
total: number;
|
|
26
|
+
totalWidth: number;
|
|
27
|
+
curPath: string[];
|
|
28
|
+
setCurPath: (path: string[]) => void;
|
|
29
|
+
setHoveringNode: (node: FlamegraphNode | FlamegraphRootNode | undefined) => void;
|
|
30
|
+
}
|
|
31
|
+
export declare function nodeLabel(node: FlamegraphNode): string;
|
|
32
|
+
export declare function IcicleGraphNodes({ data, x, y, xScale, total, totalWidth, level, setHoveringNode, path, setCurPath, curPath, }: IcicleGraphNodesProps): JSX.Element;
|
|
33
|
+
export declare function IcicleGraphRootNode({ node, xScale, total, totalWidth, setHoveringNode, setCurPath, curPath, }: IcicleGraphRootNodeProps): JSX.Element;
|
|
34
|
+
export default function IcicleGraph({ graph, width, setCurPath, curPath, sampleUnit, }: IcicleGraphProps): JSX.Element;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,139 @@
|
|
|
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 React, { useEffect, useRef, useState } from 'react';
|
|
26
|
+
import { throttle } from 'lodash';
|
|
27
|
+
import { pointer } from 'd3-selection';
|
|
28
|
+
import { scaleLinear } from 'd3-scale';
|
|
29
|
+
import GraphTooltip from './GraphTooltip';
|
|
30
|
+
import { getLastItem, diffColor, isSearchMatch } from '@parca/functions';
|
|
31
|
+
import { useAppSelector, selectDarkMode, selectSearchNodeString } from '@parca/store';
|
|
32
|
+
import { hexifyAddress } from './utils';
|
|
33
|
+
var RowHeight = 26;
|
|
34
|
+
var icicleRectStyles = {
|
|
35
|
+
cursor: 'pointer',
|
|
36
|
+
transition: 'opacity .15s linear',
|
|
37
|
+
};
|
|
38
|
+
var fadedIcicleRectStyles = {
|
|
39
|
+
cursor: 'pointer',
|
|
40
|
+
transition: 'opacity .15s linear',
|
|
41
|
+
opacity: '0.5',
|
|
42
|
+
};
|
|
43
|
+
function IcicleRect(_a) {
|
|
44
|
+
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;
|
|
45
|
+
var currentSearchString = useAppSelector(selectSearchNodeString);
|
|
46
|
+
var isFaded = curPath.length > 0 && name !== curPath[curPath.length - 1];
|
|
47
|
+
var styles = isFaded ? fadedIcicleRectStyles : icicleRectStyles;
|
|
48
|
+
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: {
|
|
49
|
+
opacity: currentSearchString !== undefined &&
|
|
50
|
+
currentSearchString !== '' &&
|
|
51
|
+
!isSearchMatch(currentSearchString, name)
|
|
52
|
+
? 0.5
|
|
53
|
+
: 1,
|
|
54
|
+
fill: color,
|
|
55
|
+
} }), width > 5 && (_jsx("svg", __assign({ width: width - 5, height: height }, { children: _jsx("text", __assign({ x: 5, y: 15, style: { fontSize: '12px' } }, { children: name })) })))] })));
|
|
56
|
+
}
|
|
57
|
+
export function nodeLabel(node) {
|
|
58
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
59
|
+
if (node.meta === undefined)
|
|
60
|
+
return '<unknown>';
|
|
61
|
+
var mapping = "".concat(((_b = (_a = node.meta) === null || _a === void 0 ? void 0 : _a.mapping) === null || _b === void 0 ? void 0 : _b.file) !== undefined && ((_d = (_c = node.meta) === null || _c === void 0 ? void 0 : _c.mapping) === null || _d === void 0 ? void 0 : _d.file) !== ''
|
|
62
|
+
? '[' + ((_e = getLastItem(node.meta.mapping.file)) !== null && _e !== void 0 ? _e : '') + '] '
|
|
63
|
+
: '');
|
|
64
|
+
if (((_f = node.meta.function) === null || _f === void 0 ? void 0 : _f.name) !== undefined && ((_g = node.meta.function) === null || _g === void 0 ? void 0 : _g.name) !== '')
|
|
65
|
+
return mapping + node.meta.function.name;
|
|
66
|
+
var address = hexifyAddress((_h = node.meta.location) === null || _h === void 0 ? void 0 : _h.address);
|
|
67
|
+
var fallback = "".concat(mapping).concat(address);
|
|
68
|
+
return fallback === '' ? '<unknown>' : fallback;
|
|
69
|
+
}
|
|
70
|
+
export function IcicleGraphNodes(_a) {
|
|
71
|
+
var data = _a.data, 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;
|
|
72
|
+
var isDarkMode = useAppSelector(selectDarkMode);
|
|
73
|
+
var nodes = curPath.length === 0 ? data : data.filter(function (d) { return d != null && curPath[0] === nodeLabel(d); });
|
|
74
|
+
var nextLevel = level + 1;
|
|
75
|
+
return (_jsx("g", __assign({ transform: "translate(".concat(x, ", ").concat(y, ")") }, { children: nodes.map(function (d, i) {
|
|
76
|
+
var cumulative = parseFloat(d.cumulative);
|
|
77
|
+
var diff = parseFloat(d.diff);
|
|
78
|
+
var start = nodes.slice(0, i).reduce(function (sum, d) { return sum + parseFloat(d.cumulative); }, 0);
|
|
79
|
+
var nextCurPath = curPath.length === 0 ? [] : curPath.slice(1);
|
|
80
|
+
var width = nextCurPath.length > 0 || (nextCurPath.length === 0 && curPath.length === 1)
|
|
81
|
+
? totalWidth
|
|
82
|
+
: xScale(cumulative);
|
|
83
|
+
if (width <= 1) {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
var name = nodeLabel(d);
|
|
87
|
+
var key = "".concat(level, "-").concat(i);
|
|
88
|
+
var nextPath = path.concat([name]);
|
|
89
|
+
var color = diffColor(diff, cumulative, isDarkMode);
|
|
90
|
+
var onClick = function () {
|
|
91
|
+
setCurPath(nextPath);
|
|
92
|
+
};
|
|
93
|
+
var xStart = xScale(start);
|
|
94
|
+
var newXScale = nextCurPath.length === 0 && curPath.length === 1
|
|
95
|
+
? scaleLinear().domain([0, cumulative]).range([0, totalWidth])
|
|
96
|
+
: xScale;
|
|
97
|
+
var onMouseEnter = function () { return setHoveringNode(d); };
|
|
98
|
+
var onMouseLeave = function () { return setHoveringNode(undefined); };
|
|
99
|
+
return (_jsxs(React.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, 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)));
|
|
100
|
+
}) })));
|
|
101
|
+
}
|
|
102
|
+
var MemoizedIcicleGraphNodes = React.memo(IcicleGraphNodes);
|
|
103
|
+
export function IcicleGraphRootNode(_a) {
|
|
104
|
+
var node = _a.node, xScale = _a.xScale, total = _a.total, totalWidth = _a.totalWidth, setHoveringNode = _a.setHoveringNode, setCurPath = _a.setCurPath, curPath = _a.curPath;
|
|
105
|
+
var isDarkMode = useAppSelector(selectDarkMode);
|
|
106
|
+
var cumulative = parseFloat(node.cumulative);
|
|
107
|
+
var diff = parseFloat(node.diff);
|
|
108
|
+
var color = diffColor(diff, cumulative, isDarkMode);
|
|
109
|
+
var onClick = function () { return setCurPath([]); };
|
|
110
|
+
var onMouseEnter = function () { return setHoveringNode(node); };
|
|
111
|
+
var onMouseLeave = function () { return setHoveringNode(undefined); };
|
|
112
|
+
var path = [];
|
|
113
|
+
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, x: 0, y: RowHeight, xScale: xScale, total: total, totalWidth: totalWidth, level: 0, setHoveringNode: setHoveringNode, path: path, curPath: curPath, setCurPath: setCurPath })] })));
|
|
114
|
+
}
|
|
115
|
+
var MemoizedIcicleGraphRootNode = React.memo(IcicleGraphRootNode);
|
|
116
|
+
export default function IcicleGraph(_a) {
|
|
117
|
+
var graph = _a.graph, width = _a.width, setCurPath = _a.setCurPath, curPath = _a.curPath, sampleUnit = _a.sampleUnit;
|
|
118
|
+
var _b = useState(), hoveringNode = _b[0], setHoveringNode = _b[1];
|
|
119
|
+
var _c = useState([0, 0]), pos = _c[0], setPos = _c[1];
|
|
120
|
+
var _d = useState(0), height = _d[0], setHeight = _d[1];
|
|
121
|
+
var svg = useRef(null);
|
|
122
|
+
var ref = useRef(null);
|
|
123
|
+
useEffect(function () {
|
|
124
|
+
if (ref.current != null) {
|
|
125
|
+
setHeight(ref === null || ref === void 0 ? void 0 : ref.current.getBoundingClientRect().height);
|
|
126
|
+
}
|
|
127
|
+
}, [width]);
|
|
128
|
+
if (graph.root === undefined || width === undefined)
|
|
129
|
+
return _jsx(_Fragment, {});
|
|
130
|
+
var throttledSetPos = throttle(setPos, 20);
|
|
131
|
+
var onMouseMove = function (e) {
|
|
132
|
+
// X/Y coordinate array relative to svg
|
|
133
|
+
var rel = pointer(e);
|
|
134
|
+
throttledSetPos([rel[0], rel[1]]);
|
|
135
|
+
};
|
|
136
|
+
var total = parseFloat(graph.total);
|
|
137
|
+
var xScale = scaleLinear().domain([0, total]).range([0, width]);
|
|
138
|
+
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 }), _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, setHoveringNode: setHoveringNode, curPath: curPath, setCurPath: setCurPath, xScale: xScale, total: total, totalWidth: width }) })) }))] })));
|
|
139
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Query } from '@parca/parser';
|
|
2
|
+
import { LabelsResponse, QueryServiceClient, ValuesResponse } from '@parca/client';
|
|
3
|
+
interface MatchersInputProps {
|
|
4
|
+
queryClient: QueryServiceClient;
|
|
5
|
+
setMatchersString: (arg: string) => void;
|
|
6
|
+
runQuery: () => void;
|
|
7
|
+
currentQuery: Query;
|
|
8
|
+
}
|
|
9
|
+
export interface ILabelNamesResult {
|
|
10
|
+
response?: LabelsResponse;
|
|
11
|
+
error?: Error;
|
|
12
|
+
}
|
|
13
|
+
export interface ILabelValuesResult {
|
|
14
|
+
response?: ValuesResponse;
|
|
15
|
+
error?: Error;
|
|
16
|
+
}
|
|
17
|
+
interface UseLabelNames {
|
|
18
|
+
result: ILabelNamesResult;
|
|
19
|
+
loading: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare const useLabelNames: (client: QueryServiceClient) => UseLabelNames;
|
|
22
|
+
declare const MatchersInput: ({ queryClient, setMatchersString, runQuery, currentQuery, }: MatchersInputProps) => JSX.Element;
|
|
23
|
+
export default MatchersInput;
|