@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.
Files changed (93) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/dist/Callgraph/Edge/index.d.ts +22 -0
  3. package/dist/Callgraph/Edge/index.js +30 -0
  4. package/dist/Callgraph/Node/index.d.ts +19 -0
  5. package/dist/Callgraph/Node/index.js +37 -0
  6. package/dist/Callgraph/index.d.ts +8 -0
  7. package/dist/Callgraph/index.js +137 -0
  8. package/dist/Callgraph/mockData/index.d.ts +148 -0
  9. package/dist/Callgraph/mockData/index.js +577 -0
  10. package/dist/Callgraph/utils.d.ts +19 -0
  11. package/dist/Callgraph/utils.js +82 -0
  12. package/dist/GraphTooltip/index.d.ts +19 -0
  13. package/dist/GraphTooltip/index.js +119 -0
  14. package/dist/IcicleGraph.d.ts +35 -0
  15. package/dist/IcicleGraph.js +139 -0
  16. package/dist/MatchersInput/index.d.ts +23 -0
  17. package/dist/MatchersInput/index.js +479 -0
  18. package/dist/MetricsCircle/index.d.ts +7 -0
  19. package/dist/MetricsCircle/index.js +18 -0
  20. package/dist/MetricsGraph/index.d.ts +35 -0
  21. package/dist/MetricsGraph/index.js +349 -0
  22. package/dist/MetricsSeries/index.d.ts +11 -0
  23. package/dist/MetricsSeries/index.js +21 -0
  24. package/dist/ProfileExplorer/ProfileExplorerCompare.d.ts +19 -0
  25. package/dist/ProfileExplorer/ProfileExplorerCompare.js +38 -0
  26. package/dist/ProfileExplorer/ProfileExplorerSingle.d.ts +15 -0
  27. package/dist/ProfileExplorer/ProfileExplorerSingle.js +19 -0
  28. package/dist/ProfileExplorer/index.d.ts +9 -0
  29. package/dist/ProfileExplorer/index.js +203 -0
  30. package/dist/ProfileIcicleGraph.d.ts +10 -0
  31. package/dist/ProfileIcicleGraph.js +28 -0
  32. package/dist/ProfileMetricsGraph/index.d.ts +22 -0
  33. package/dist/ProfileMetricsGraph/index.js +127 -0
  34. package/dist/ProfileSVG.module.css +3 -0
  35. package/dist/ProfileSelector/CompareButton.d.ts +5 -0
  36. package/dist/ProfileSelector/CompareButton.js +41 -0
  37. package/dist/ProfileSelector/MergeButton.d.ts +5 -0
  38. package/dist/ProfileSelector/MergeButton.js +41 -0
  39. package/dist/ProfileSelector/index.d.ts +29 -0
  40. package/dist/ProfileSelector/index.js +133 -0
  41. package/dist/ProfileSource.d.ts +88 -0
  42. package/dist/ProfileSource.js +239 -0
  43. package/dist/ProfileTypeSelector/index.d.ts +20 -0
  44. package/dist/ProfileTypeSelector/index.js +138 -0
  45. package/dist/ProfileView.d.ts +39 -0
  46. package/dist/ProfileView.js +111 -0
  47. package/dist/ProfileView.styles.css +3 -0
  48. package/dist/ProfileViewWithData.d.ts +11 -0
  49. package/dist/ProfileViewWithData.js +116 -0
  50. package/dist/TopTable.d.ts +9 -0
  51. package/dist/TopTable.js +140 -0
  52. package/dist/TopTable.styles.css +7 -0
  53. package/dist/components/DiffLegend.d.ts +2 -0
  54. package/dist/components/DiffLegend.js +62 -0
  55. package/dist/components/ProfileShareButton/ResultBox.d.ts +6 -0
  56. package/dist/components/ProfileShareButton/ResultBox.js +46 -0
  57. package/dist/components/ProfileShareButton/index.d.ts +7 -0
  58. package/dist/components/ProfileShareButton/index.js +119 -0
  59. package/dist/index.d.ts +13 -0
  60. package/dist/index.js +64 -0
  61. package/dist/styles.css +1 -0
  62. package/dist/useDelayedLoader.d.ts +5 -0
  63. package/dist/useDelayedLoader.js +33 -0
  64. package/dist/useQuery.d.ts +13 -0
  65. package/dist/useQuery.js +41 -0
  66. package/dist/utils.d.ts +4 -0
  67. package/dist/utils.js +83 -0
  68. package/package.json +12 -8
  69. package/src/Callgraph/Edge/index.tsx +59 -0
  70. package/src/Callgraph/Node/index.tsx +66 -0
  71. package/src/Callgraph/index.tsx +169 -0
  72. package/src/Callgraph/mockData/index.ts +605 -0
  73. package/src/Callgraph/utils.ts +116 -0
  74. package/src/GraphTooltip/index.tsx +245 -0
  75. package/src/IcicleGraph.tsx +3 -3
  76. package/src/MatchersInput/index.tsx +698 -0
  77. package/src/MetricsCircle/index.tsx +28 -0
  78. package/src/MetricsGraph/index.tsx +614 -0
  79. package/src/MetricsSeries/index.tsx +38 -0
  80. package/src/ProfileExplorer/ProfileExplorerCompare.tsx +109 -0
  81. package/src/ProfileExplorer/ProfileExplorerSingle.tsx +72 -0
  82. package/src/ProfileExplorer/index.tsx +377 -0
  83. package/src/ProfileMetricsGraph/index.tsx +143 -0
  84. package/src/ProfileSelector/CompareButton.tsx +72 -0
  85. package/src/ProfileSelector/MergeButton.tsx +72 -0
  86. package/src/ProfileSelector/index.tsx +270 -0
  87. package/src/ProfileTypeSelector/index.tsx +180 -0
  88. package/src/ProfileView.tsx +2 -7
  89. package/src/index.tsx +11 -0
  90. package/src/useQuery.tsx +1 -0
  91. package/tailwind.config.js +8 -0
  92. package/tsconfig.json +7 -3
  93. package/typings.d.ts +14 -0
@@ -0,0 +1,349 @@
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 { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
24
+ // Copyright 2022 The Parca Authors
25
+ // Licensed under the Apache License, Version 2.0 (the "License");
26
+ // you may not use this file except in compliance with the License.
27
+ // You may obtain a copy of the License at
28
+ //
29
+ // http://www.apache.org/licenses/LICENSE-2.0
30
+ //
31
+ // Unless required by applicable law or agreed to in writing, software
32
+ // distributed under the License is distributed on an "AS IS" BASIS,
33
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34
+ // See the License for the specific language governing permissions and
35
+ // limitations under the License.
36
+ import { useEffect, useRef, useState } from 'react';
37
+ import * as d3 from 'd3';
38
+ import MetricsSeries from '../MetricsSeries';
39
+ import MetricsCircle from '../MetricsCircle';
40
+ import { pointer } from 'd3-selection';
41
+ import { formatForTimespan } from '@parca/functions/time';
42
+ import { timeFormat } from '..';
43
+ import { cutToMaxStringLength } from '@parca/functions/string';
44
+ import throttle from 'lodash.throttle';
45
+ import { usePopper } from 'react-popper';
46
+ import { valueFormatter, formatDate } from '@parca/functions';
47
+ import { DateTimeRange } from '@parca/components';
48
+ import { useContainerDimensions } from '@parca/dynamicsize';
49
+ var MetricsGraph = function (_a) {
50
+ var data = _a.data, from = _a.from, to = _a.to, profile = _a.profile, onSampleClick = _a.onSampleClick, onLabelClick = _a.onLabelClick, setTimeRange = _a.setTimeRange, sampleUnit = _a.sampleUnit;
51
+ var _b = useContainerDimensions(), ref = _b.ref, dimensions = _b.dimensions;
52
+ return (_jsx("div", __assign({ ref: ref }, { children: _jsx(RawMetricsGraph, { data: data, from: from, to: to, profile: profile, onSampleClick: onSampleClick, onLabelClick: onLabelClick, setTimeRange: setTimeRange, sampleUnit: sampleUnit, width: dimensions === null || dimensions === void 0 ? void 0 : dimensions.width }) })));
53
+ };
54
+ export default MetricsGraph;
55
+ export var parseValue = function (value) {
56
+ var val = parseFloat(value);
57
+ // "+Inf", "-Inf", "+Inf" will be parsed into NaN by parseFloat(). They
58
+ // can't be graphed, so show them as gaps (null).
59
+ return isNaN(val) ? null : val;
60
+ };
61
+ var lineStroke = '1px';
62
+ var lineStrokeHover = '2px';
63
+ function generateGetBoundingClientRect(contextElement, x, y) {
64
+ if (x === void 0) { x = 0; }
65
+ if (y === void 0) { y = 0; }
66
+ var domRect = contextElement.getBoundingClientRect();
67
+ return function () {
68
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
69
+ return ({
70
+ width: 0,
71
+ height: 0,
72
+ top: domRect.y + y,
73
+ left: domRect.x + x,
74
+ right: domRect.x + x,
75
+ bottom: domRect.y + y,
76
+ });
77
+ };
78
+ }
79
+ var virtualElement = {
80
+ getBoundingClientRect: function () {
81
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
82
+ return {
83
+ width: 0,
84
+ height: 0,
85
+ top: 0,
86
+ left: 0,
87
+ right: 0,
88
+ bottom: 0,
89
+ };
90
+ },
91
+ };
92
+ export var MetricsTooltip = function (_a) {
93
+ var x = _a.x, y = _a.y, highlighted = _a.highlighted, onLabelClick = _a.onLabelClick, contextElement = _a.contextElement, sampleUnit = _a.sampleUnit;
94
+ var _b = useState(null), popperElement = _b[0], setPopperElement = _b[1];
95
+ var _c = usePopper(virtualElement, popperElement, {
96
+ placement: 'auto-start',
97
+ strategy: 'absolute',
98
+ modifiers: [
99
+ {
100
+ name: 'preventOverflow',
101
+ options: {
102
+ tether: false,
103
+ altAxis: true,
104
+ },
105
+ },
106
+ {
107
+ name: 'offset',
108
+ options: {
109
+ offset: [30, 30],
110
+ },
111
+ },
112
+ ],
113
+ }), styles = _c.styles, attributes = _c.attributes, popperProps = __rest(_c, ["styles", "attributes"]);
114
+ var update = popperProps.update;
115
+ useEffect(function () {
116
+ if (contextElement != null) {
117
+ virtualElement.getBoundingClientRect = generateGetBoundingClientRect(contextElement, x, y);
118
+ void (update === null || update === void 0 ? void 0 : update());
119
+ }
120
+ }, [x, y, contextElement, update]);
121
+ var nameLabel = highlighted === null || highlighted === void 0 ? void 0 : highlighted.labels.find(function (e) { return e.name === '__name__'; });
122
+ var highlightedNameLabel = nameLabel !== undefined ? nameLabel : { name: '', value: '' };
123
+ return (_jsx("div", __assign({ ref: setPopperElement, style: styles.popper }, attributes.popper, { className: "z-10" }, { children: _jsx("div", __assign({ className: "flex max-w-md" }, { children: _jsx("div", __assign({ className: "m-auto" }, { 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" }, { children: highlightedNameLabel.value })), _jsx("span", __assign({ className: "block text-gray-700 dark:text-gray-300 my-2" }, { children: _jsx("table", __assign({ className: "table-auto" }, { children: _jsxs("tbody", { children: [_jsxs("tr", { children: [_jsx("td", __assign({ className: "w-1/4" }, { children: "Value" })), _jsx("td", __assign({ className: "w-3/4" }, { children: valueFormatter(highlighted.value, sampleUnit, 1) }))] }), _jsxs("tr", { children: [_jsx("td", __assign({ className: "w-1/4" }, { children: "At" })), _jsx("td", __assign({ className: "w-3/4" }, { children: formatDate(highlighted.timestamp, timeFormat) }))] })] }) })) })), _jsx("span", __assign({ className: "block text-gray-500 my-2" }, { children: highlighted.labels
124
+ .filter(function (label) { return label.name !== '__name__'; })
125
+ .map(function (label) {
126
+ return (_jsx("button", __assign({ type: "button", className: "inline-block rounded-lg text-gray-700 bg-gray-200 dark:bg-gray-700 dark:text-gray-400 px-2 py-1 text-xs font-bold mr-3", onClick: function () { return onLabelClick(label.name, label.value); } }, { children: cutToMaxStringLength("".concat(label.name, "=\"").concat(label.value, "\""), 37) }), label.name));
127
+ }) })), _jsx("span", __assign({ className: "block text-gray-500 text-xs" }, { children: "Hold shift and click label to add to query." }))] })) })) })) })) })) })));
128
+ };
129
+ export var RawMetricsGraph = function (_a) {
130
+ var data = _a.data, from = _a.from, to = _a.to, profile = _a.profile, onSampleClick = _a.onSampleClick, onLabelClick = _a.onLabelClick, setTimeRange = _a.setTimeRange, width = _a.width, sampleUnit = _a.sampleUnit;
131
+ var graph = useRef(null);
132
+ var _b = useState(false), dragging = _b[0], setDragging = _b[1];
133
+ var _c = useState(false), hovering = _c[0], setHovering = _c[1];
134
+ var _d = useState(-1), relPos = _d[0], setRelPos = _d[1];
135
+ var _e = useState([0, 0]), pos = _e[0], setPos = _e[1];
136
+ var _f = useState(false), freezeTooltip = _f[0], setFreezeTooltip = _f[1];
137
+ var metricPointRef = useRef(null);
138
+ useEffect(function () {
139
+ var handleShiftDown = function (event) {
140
+ if (event.keyCode === 16) {
141
+ setFreezeTooltip(true);
142
+ }
143
+ };
144
+ window.addEventListener('keydown', handleShiftDown);
145
+ return function () {
146
+ window.removeEventListener('keydown', handleShiftDown);
147
+ };
148
+ }, []);
149
+ useEffect(function () {
150
+ var handleShiftUp = function (event) {
151
+ if (event.keyCode === 16) {
152
+ setFreezeTooltip(false);
153
+ }
154
+ };
155
+ window.addEventListener('keyup', handleShiftUp);
156
+ return function () {
157
+ window.removeEventListener('keyup', handleShiftUp);
158
+ };
159
+ }, []);
160
+ var time = parseFloat(profile === null || profile === void 0 ? void 0 : profile.HistoryParams().time);
161
+ if (width === undefined || width == null) {
162
+ width = 0;
163
+ }
164
+ var height = Math.min(width / 2.5, 400);
165
+ var margin = 50;
166
+ var marginRight = 20;
167
+ var series = data.reduce(function (agg, s) {
168
+ if (s.labelset !== undefined) {
169
+ agg.push({
170
+ metric: s.labelset.labels,
171
+ values: s.samples.reduce(function (agg, d) {
172
+ if (d.timestamp !== undefined && d.value !== undefined) {
173
+ var t = (+d.timestamp.seconds * 1e9 + d.timestamp.nanos) / 1e6; // https://github.com/microsoft/TypeScript/issues/5710#issuecomment-157886246
174
+ agg.push([t, parseFloat(d.value)]);
175
+ }
176
+ return agg;
177
+ }, []),
178
+ });
179
+ }
180
+ return agg;
181
+ }, []);
182
+ var extentsY = series.map(function (s) {
183
+ return d3.extent(s.values, function (d) {
184
+ return d[1];
185
+ });
186
+ });
187
+ var minY = d3.min(extentsY, function (d) {
188
+ return d[0];
189
+ });
190
+ var maxY = d3.max(extentsY, function (d) {
191
+ return d[1];
192
+ });
193
+ /* Scale */
194
+ var xScale = d3
195
+ .scaleUtc()
196
+ .domain([from, to])
197
+ .range([0, width - margin - marginRight]);
198
+ var yScale = d3
199
+ .scaleLinear()
200
+ // tslint:disable-next-line
201
+ .domain([minY, maxY])
202
+ .range([height - margin, 0]);
203
+ var color = d3.scaleOrdinal(d3.schemeCategory10);
204
+ var l = d3.line(function (d) { return xScale(d[0]); }, function (d) { return yScale(d[1]); });
205
+ var getClosest = function () {
206
+ var closestPointPerSeries = series.map(function (s) {
207
+ var distances = s.values.map(function (d) {
208
+ var x = xScale(d[0]);
209
+ var y = yScale(d[1]);
210
+ return Math.sqrt(Math.pow(pos[0] - x, 2) + Math.pow(pos[1] - y, 2));
211
+ });
212
+ var pointIndex = d3.minIndex(distances);
213
+ var minDistance = distances[pointIndex];
214
+ return {
215
+ pointIndex: pointIndex,
216
+ distance: minDistance,
217
+ };
218
+ });
219
+ var closestSeriesIndex = d3.minIndex(closestPointPerSeries, function (s) { return s.distance; });
220
+ var pointIndex = closestPointPerSeries[closestSeriesIndex].pointIndex;
221
+ var point = series[closestSeriesIndex].values[pointIndex];
222
+ return {
223
+ seriesIndex: closestSeriesIndex,
224
+ labels: series[closestSeriesIndex].metric,
225
+ timestamp: point[0],
226
+ value: point[1],
227
+ x: xScale(point[0]),
228
+ y: yScale(point[1]),
229
+ };
230
+ };
231
+ var highlighted = getClosest();
232
+ var onMouseDown = function (e) {
233
+ // only left mouse button
234
+ if (e.button !== 0) {
235
+ return;
236
+ }
237
+ // X/Y coordinate array relative to svg
238
+ var rel = pointer(e);
239
+ var xCoordinate = rel[0];
240
+ var xCoordinateWithoutMargin = xCoordinate - margin;
241
+ if (xCoordinateWithoutMargin >= 0) {
242
+ setRelPos(xCoordinateWithoutMargin);
243
+ setDragging(true);
244
+ }
245
+ e.stopPropagation();
246
+ e.preventDefault();
247
+ };
248
+ var openClosestProfile = function () {
249
+ if (highlighted != null) {
250
+ onSampleClick(Math.round(highlighted.timestamp), highlighted.value, highlighted.labels);
251
+ }
252
+ };
253
+ var onMouseUp = function (e) {
254
+ setDragging(false);
255
+ if (relPos === -1) {
256
+ // MouseDown happened outside of this element.
257
+ return;
258
+ }
259
+ // This is a normal click. We tolerate tiny movements to still be a
260
+ // click as they can occur when clicking based on user feedback.
261
+ if (Math.abs(relPos - pos[0]) <= 1) {
262
+ openClosestProfile();
263
+ setRelPos(-1);
264
+ return;
265
+ }
266
+ var firstTime = xScale.invert(relPos).valueOf();
267
+ var secondTime = xScale.invert(pos[0]).valueOf();
268
+ if (firstTime > secondTime) {
269
+ setTimeRange(DateTimeRange.fromAbsoluteDates(secondTime, firstTime));
270
+ }
271
+ else {
272
+ setTimeRange(DateTimeRange.fromAbsoluteDates(firstTime, secondTime));
273
+ }
274
+ setRelPos(-1);
275
+ e.stopPropagation();
276
+ e.preventDefault();
277
+ };
278
+ var throttledSetPos = throttle(setPos, 20);
279
+ var onMouseMove = function (e) {
280
+ // X/Y coordinate array relative to svg
281
+ var rel = pointer(e);
282
+ var xCoordinate = rel[0];
283
+ var xCoordinateWithoutMargin = xCoordinate - margin;
284
+ var yCoordinate = rel[1];
285
+ var yCoordinateWithoutMargin = yCoordinate - margin;
286
+ if (!freezeTooltip) {
287
+ throttledSetPos([xCoordinateWithoutMargin, yCoordinateWithoutMargin]);
288
+ }
289
+ };
290
+ var findSelectedProfile = function () {
291
+ if (profile == null) {
292
+ return null;
293
+ }
294
+ var s = null;
295
+ var seriesIndex = -1;
296
+ outer: for (var i = 0; i < series.length; i++) {
297
+ var keys = profile.labels.map(function (e) { return e.name; });
298
+ var _loop_1 = function (j) {
299
+ var labelName = keys[j];
300
+ var label = series[i].metric.find(function (e) { return e.name === labelName; });
301
+ if (label === undefined) {
302
+ return "continue-outer";
303
+ }
304
+ if (profile.labels[j].value !== label.value) {
305
+ return "continue-outer";
306
+ }
307
+ };
308
+ for (var j = 0; j < keys.length; j++) {
309
+ var state_1 = _loop_1(j);
310
+ switch (state_1) {
311
+ case "continue-outer": continue outer;
312
+ }
313
+ }
314
+ seriesIndex = i;
315
+ s = series[i];
316
+ }
317
+ if (s == null) {
318
+ return null;
319
+ }
320
+ // Find the sample that matches the timestamp
321
+ var sample = s.values.find(function (v) {
322
+ return Math.round(v[0]) === time;
323
+ });
324
+ if (sample === undefined) {
325
+ return null;
326
+ }
327
+ return {
328
+ labels: [],
329
+ seriesIndex: seriesIndex,
330
+ timestamp: sample[0],
331
+ value: sample[1],
332
+ x: xScale(sample[0]),
333
+ y: yScale(sample[1]),
334
+ };
335
+ };
336
+ var selected = findSelectedProfile();
337
+ return (_jsxs(_Fragment, { children: [highlighted != null && hovering && !dragging && pos[0] !== 0 && pos[1] !== 0 && (_jsx("div", __assign({ onMouseMove: onMouseMove, onMouseEnter: function () { return setHovering(true); }, onMouseLeave: function () { return setHovering(false); } }, { children: _jsx(MetricsTooltip, { x: pos[0] + margin, y: pos[1] + margin, highlighted: highlighted, onLabelClick: onLabelClick, contextElement: graph.current, sampleUnit: sampleUnit }) }))), _jsx("div", __assign({ ref: graph, onMouseEnter: function () {
338
+ setHovering(true);
339
+ setFreezeTooltip(false);
340
+ }, onMouseLeave: function () { return setHovering(false); } }, { children: _jsxs("svg", __assign({ width: "".concat(width, "px"), height: "".concat(height + margin, "px"), onMouseDown: onMouseDown, onMouseUp: onMouseUp, onMouseMove: onMouseMove }, { children: [_jsx("g", __assign({ transform: "translate(".concat(margin, ", 0)") }, { children: dragging && (_jsx("g", __assign({ className: "zoom-time-rect" }, { children: _jsx("rect", { className: "bar", x: pos[0] - relPos < 0 ? pos[0] : relPos, y: 0, height: height, width: Math.abs(pos[0] - relPos), fill: 'rgba(0, 0, 0, 0.125)' }) }))) })), _jsxs("g", __assign({ transform: "translate(".concat(margin, ", ").concat(margin, ")") }, { children: [_jsx("g", __assign({ className: "lines fill-transparent" }, { children: series.map(function (s, i) { return (_jsx("g", __assign({ className: "line" }, { children: _jsx(MetricsSeries, { data: s, line: l, color: color(i.toString()), strokeWidth: hovering && highlighted != null && i === highlighted.seriesIndex
341
+ ? lineStrokeHover
342
+ : lineStroke, xScale: xScale, yScale: yScale }) }), i)); }) })), hovering && highlighted != null && (_jsx("g", __assign({ className: "circle-group", ref: metricPointRef, style: { fill: color(highlighted.seriesIndex.toString()) } }, { children: _jsx(MetricsCircle, { cx: highlighted.x, cy: highlighted.y }) }))), selected != null && (_jsx("g", __assign({ className: "circle-group", style: (selected === null || selected === void 0 ? void 0 : selected.seriesIndex) != null
343
+ ? { fill: color(selected.seriesIndex.toString()) }
344
+ : {} }, { children: _jsx(MetricsCircle, { cx: selected.x, cy: selected.y, radius: 5 }) }))), _jsx("g", __assign({ className: "x axis", fill: "none", fontSize: "10", textAnchor: "middle", transform: "translate(0,".concat(height - margin, ")") }, { children: xScale.ticks(5).map(function (d, i) { return (_jsxs("g", __assign({ className: "tick",
345
+ /* eslint-disable-next-line @typescript-eslint/restrict-template-expressions */
346
+ transform: "translate(".concat(xScale(d), ", 0)") }, { children: [_jsx("line", { y2: 6, stroke: "currentColor" }), _jsx("text", __assign({ fill: "currentColor", dy: ".71em", y: 9 }, { children: formatDate(d, formatForTimespan(from, to)) }))] }), i)); }) })), _jsx("g", __assign({ className: "y axis", textAnchor: "end", fontSize: "10", fill: "none" }, { children: yScale.ticks(3).map(function (d, i) { return (_jsxs("g", __assign({ className: "tick",
347
+ /* eslint-disable-next-line @typescript-eslint/restrict-template-expressions */
348
+ transform: "translate(0, ".concat(yScale(d), ")") }, { children: [_jsx("line", { stroke: "currentColor", x2: -6 }), _jsx("text", __assign({ fill: "currentColor", x: -9, dy: '0.32em' }, { children: valueFormatter(d, sampleUnit, 1) }))] }), i)); }) }))] }))] })) }))] }));
349
+ };
@@ -0,0 +1,11 @@
1
+ import * as d3 from 'd3';
2
+ interface MetricsSeriesProps {
3
+ data: any;
4
+ line: d3.Line<[number, number]>;
5
+ color: string;
6
+ strokeWidth: string;
7
+ xScale: (input: number) => number;
8
+ yScale: (input: number) => number;
9
+ }
10
+ declare const MetricsSeries: ({ data, line, color, strokeWidth }: MetricsSeriesProps) => JSX.Element;
11
+ export default MetricsSeries;
@@ -0,0 +1,21 @@
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 } from "react/jsx-runtime";
13
+ var MetricsSeries = function (_a) {
14
+ var _b;
15
+ var data = _a.data, line = _a.line, color = _a.color, strokeWidth = _a.strokeWidth;
16
+ return (_jsx("g", __assign({ className: "line-group" }, { children: _jsx("path", { className: "line", d: (_b = line(data.values)) !== null && _b !== void 0 ? _b : undefined, style: {
17
+ stroke: color,
18
+ strokeWidth: strokeWidth,
19
+ } }) })));
20
+ };
21
+ export default MetricsSeries;
@@ -0,0 +1,19 @@
1
+ import { ProfileSelection } from '..';
2
+ import { QueryServiceClient } from '@parca/client';
3
+ import { NavigateFunction } from '.';
4
+ import { QuerySelection } from '../ProfileSelector';
5
+ interface ProfileExplorerCompareProps {
6
+ queryClient: QueryServiceClient;
7
+ queryA: QuerySelection;
8
+ queryB: QuerySelection;
9
+ profileA: ProfileSelection | null;
10
+ profileB: ProfileSelection | null;
11
+ selectQueryA: (query: QuerySelection) => void;
12
+ selectQueryB: (query: QuerySelection) => void;
13
+ selectProfileA: (source: ProfileSelection) => void;
14
+ selectProfileB: (source: ProfileSelection) => void;
15
+ closeProfile: (card: string) => void;
16
+ navigateTo: NavigateFunction;
17
+ }
18
+ declare const ProfileExplorerCompare: ({ queryClient, queryA, queryB, profileA, profileB, selectQueryA, selectQueryB, selectProfileA, selectProfileB, closeProfile, navigateTo, }: ProfileExplorerCompareProps) => JSX.Element;
19
+ export default ProfileExplorerCompare;
@@ -0,0 +1,38 @@
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 { ProfileDiffSource, ProfileViewWithData } from '..';
26
+ import { Query } from '@parca/parser';
27
+ import ProfileSelector from '../ProfileSelector';
28
+ var ProfileExplorerCompare = function (_a) {
29
+ 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;
30
+ var closeProfileA = function () {
31
+ closeProfile('A');
32
+ };
33
+ var closeProfileB = function () {
34
+ closeProfile('B');
35
+ };
36
+ return (_jsxs(_Fragment, { children: [_jsxs("div", __assign({ className: "grid grid-cols-2" }, { children: [_jsx("div", __assign({ className: "pr-2" }, { children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryA, profileSelection: profileA, selectProfile: selectProfileA, selectQuery: selectQueryA, closeProfile: closeProfileA, enforcedProfileName: '', comparing: true, onCompareProfile: function () { } }) })), _jsx("div", __assign({ className: "pl-2" }, { children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: queryB, profileSelection: profileB, selectProfile: selectProfileB, selectQuery: selectQueryB, closeProfile: closeProfileB, enforcedProfileName: Query.parse(queryA.expression).profileName(), comparing: true, onCompareProfile: function () { } }) }))] })), _jsx("div", __assign({ className: "grid grid-cols-1" }, { children: profileA != null && profileB != null ? (_jsx(ProfileViewWithData, { navigateTo: navigateTo, queryClient: queryClient, profileSource: new ProfileDiffSource(profileA.ProfileSource(), profileB.ProfileSource()) })) : (_jsx("div", { children: _jsx("div", __assign({ className: "my-20 text-center" }, { children: _jsx("p", { children: "Select a profile on both sides." }) })) })) }))] }));
37
+ };
38
+ export default ProfileExplorerCompare;
@@ -0,0 +1,15 @@
1
+ import { QueryServiceClient } from '@parca/client';
2
+ import { ProfileSelection } from '..';
3
+ import { NavigateFunction } from '../ProfileExplorer';
4
+ import { QuerySelection } from '../ProfileSelector';
5
+ interface ProfileExplorerSingleProps {
6
+ queryClient: QueryServiceClient;
7
+ query: QuerySelection;
8
+ selectQuery: (query: QuerySelection) => void;
9
+ selectProfile: (source: ProfileSelection) => void;
10
+ profile: ProfileSelection | null;
11
+ compareProfile: () => void;
12
+ navigateTo: NavigateFunction;
13
+ }
14
+ declare const ProfileExplorerSingle: ({ queryClient, query, selectQuery, selectProfile, profile, compareProfile, navigateTo, }: ProfileExplorerSingleProps) => JSX.Element;
15
+ export default ProfileExplorerSingle;
@@ -0,0 +1,19 @@
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, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
13
+ import { ProfileViewWithData } from '..';
14
+ import ProfileSelector from '../ProfileSelector';
15
+ var ProfileExplorerSingle = function (_a) {
16
+ var queryClient = _a.queryClient, query = _a.query, selectQuery = _a.selectQuery, selectProfile = _a.selectProfile, profile = _a.profile, compareProfile = _a.compareProfile, navigateTo = _a.navigateTo;
17
+ return (_jsxs(_Fragment, { children: [_jsx("div", __assign({ className: "grid grid-cols-1" }, { children: _jsx("div", { children: _jsx(ProfileSelector, { queryClient: queryClient, querySelection: query, selectQuery: selectQuery, selectProfile: selectProfile, closeProfile: function () { }, profileSelection: profile, comparing: false, onCompareProfile: compareProfile, enforcedProfileName: '' }) }) })), _jsx("div", __assign({ className: "grid grid-cols-1" }, { children: _jsx("div", { children: profile != null ? (_jsx(ProfileViewWithData, { queryClient: queryClient, profileSource: profile.ProfileSource(), navigateTo: navigateTo })) : (_jsx(_Fragment, {})) }) }))] }));
18
+ };
19
+ export default ProfileExplorerSingle;
@@ -0,0 +1,9 @@
1
+ import { QueryServiceClient } from '@parca/client';
2
+ export declare type NavigateFunction = (path: string, queryParams: any) => void;
3
+ interface ProfileExplorerProps {
4
+ queryClient: QueryServiceClient;
5
+ queryParams: any;
6
+ navigateTo: NavigateFunction;
7
+ }
8
+ declare const ProfileExplorer: ({ queryClient, queryParams, navigateTo, }: ProfileExplorerProps) => JSX.Element;
9
+ export default ProfileExplorer;