@parca/profile 0.16.452 → 0.16.453
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 +4 -0
- package/dist/MetricsGraphStrips/MetricsGraphStrips.stories.d.ts +8 -3
- package/dist/MetricsGraphStrips/MetricsGraphStrips.stories.d.ts.map +1 -1
- package/dist/MetricsGraphStrips/MetricsGraphStrips.stories.js +8 -8
- package/dist/MetricsGraphStrips/index.d.ts +6 -5
- package/dist/MetricsGraphStrips/index.d.ts.map +1 -1
- package/dist/MetricsGraphStrips/index.js +21 -4
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts +1 -0
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +1 -0
- package/dist/ProfileIcicleGraph/index.d.ts +1 -2
- package/dist/ProfileIcicleGraph/index.d.ts.map +1 -1
- package/dist/ProfileIcicleGraph/index.js +4 -4
- package/dist/ProfileView/components/DashboardItems/index.d.ts +1 -2
- package/dist/ProfileView/components/DashboardItems/index.d.ts.map +1 -1
- package/dist/ProfileView/components/DashboardItems/index.js +2 -2
- package/dist/ProfileView/context/ProfileViewContext.d.ts +10 -0
- package/dist/ProfileView/context/ProfileViewContext.d.ts.map +1 -1
- package/dist/ProfileView/context/ProfileViewContext.js +1 -0
- package/dist/ProfileView/index.d.ts +1 -1
- package/dist/ProfileView/index.d.ts.map +1 -1
- package/dist/ProfileView/index.js +2 -3
- package/dist/ProfileView/types/visualization.d.ts +2 -0
- package/dist/ProfileView/types/visualization.d.ts.map +1 -1
- package/dist/ProfileViewWithData.d.ts +4 -2
- package/dist/ProfileViewWithData.d.ts.map +1 -1
- package/dist/ProfileViewWithData.js +7 -4
- package/dist/TimelineGuide/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/package.json +2 -2
- package/src/MetricsGraphStrips/MetricsGraphStrips.stories.tsx +8 -8
- package/src/MetricsGraphStrips/index.tsx +36 -12
- package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +1 -0
- package/src/ProfileIcicleGraph/index.tsx +4 -6
- package/src/ProfileView/components/DashboardItems/index.tsx +0 -3
- package/src/ProfileView/context/ProfileViewContext.tsx +12 -0
- package/src/ProfileView/index.tsx +2 -3
- package/src/ProfileView/types/visualization.ts +2 -0
- package/src/ProfileViewWithData.tsx +11 -5
- package/src/TimelineGuide/index.tsx +0 -5
- package/src/index.tsx +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
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.453 (2024-12-05)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
6
10
|
## 0.16.452 (2024-12-02)
|
|
7
11
|
|
|
8
12
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -5,13 +5,18 @@ declare const meta: Meta;
|
|
|
5
5
|
export default meta;
|
|
6
6
|
export declare const ThreeCPUStrips: {
|
|
7
7
|
args: {
|
|
8
|
-
cpus:
|
|
8
|
+
cpus: {
|
|
9
|
+
labels: {
|
|
10
|
+
name: string;
|
|
11
|
+
value: number;
|
|
12
|
+
}[];
|
|
13
|
+
}[];
|
|
9
14
|
data: DataPoint[][];
|
|
10
|
-
|
|
15
|
+
selectedTimeframe: {
|
|
11
16
|
index: number;
|
|
12
17
|
bounds: number[];
|
|
13
18
|
};
|
|
14
|
-
|
|
19
|
+
onSelectedTimeframe: (index: number, bounds: NumberDuo) => void;
|
|
15
20
|
};
|
|
16
21
|
render: (args: any) => JSX.Element;
|
|
17
22
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MetricsGraphStrips.stories.d.ts","sourceRoot":"","sources":["../../src/MetricsGraphStrips/MetricsGraphStrips.stories.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAC;AAEtC,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AACnC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAqBtC,QAAA,MAAM,IAAI,EAAE,IAGX,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"MetricsGraphStrips.stories.d.ts","sourceRoot":"","sources":["../../src/MetricsGraphStrips/MetricsGraphStrips.stories.tsx"],"names":[],"mappings":"AAgBA,OAAO,EAAC,IAAI,EAAC,MAAM,kBAAkB,CAAC;AAEtC,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AACnC,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAqBtC,QAAA,MAAM,IAAI,EAAE,IAGX,CAAC;AACF,eAAe,IAAI,CAAC;AAEpB,eAAO,MAAM,cAAc;;;;;;;;;;;;;qCAKM,MAAM,UAAU,SAAS,KAAG,IAAI;;mBAI9B,GAAG,KAAG,GAAG,CAAC,OAAO;CAUnD,CAAC"}
|
|
@@ -37,19 +37,19 @@ const meta = {
|
|
|
37
37
|
export default meta;
|
|
38
38
|
export const ThreeCPUStrips = {
|
|
39
39
|
args: {
|
|
40
|
-
cpus: Array.from(mockData, (_, i) =>
|
|
40
|
+
cpus: Array.from(mockData, (_, i) => ({ labels: [{ name: 'cpuid', value: i + 1 }] })),
|
|
41
41
|
data: mockData,
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
console.log('
|
|
42
|
+
selectedTimeframe: { index: 1, bounds: [mockData[0][25].timestamp, mockData[0][100].timestamp] },
|
|
43
|
+
onSelectedTimeframe: (index, bounds) => {
|
|
44
|
+
console.log('onSelectedTimeframe', index, bounds);
|
|
45
45
|
},
|
|
46
46
|
},
|
|
47
47
|
render: function Component(args) {
|
|
48
48
|
const [, setArgs] = useArgs();
|
|
49
|
-
const
|
|
50
|
-
args.
|
|
51
|
-
setArgs({ ...args,
|
|
49
|
+
const onSelectedTimeframe = (index, bounds) => {
|
|
50
|
+
args.onSelectedTimeframe(index, bounds);
|
|
51
|
+
setArgs({ ...args, selectedTimeframe: { index, bounds } });
|
|
52
52
|
};
|
|
53
|
-
return _jsx(MetricsGraphStrips, { ...args,
|
|
53
|
+
return _jsx(MetricsGraphStrips, { ...args, onSelectedTimeframe: onSelectedTimeframe });
|
|
54
54
|
},
|
|
55
55
|
};
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
import { LabelSet } from '@parca/client';
|
|
1
2
|
import { NumberDuo } from '../utils';
|
|
2
3
|
import { DataPoint } from './AreaGraph';
|
|
3
4
|
interface Props {
|
|
4
|
-
cpus:
|
|
5
|
+
cpus: LabelSet[];
|
|
5
6
|
data: DataPoint[][];
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
selectedTimeframe?: {
|
|
8
|
+
labels: LabelSet;
|
|
8
9
|
bounds: NumberDuo;
|
|
9
10
|
};
|
|
10
|
-
|
|
11
|
+
onSelectedTimeframe: (labels: LabelSet, bounds: NumberDuo | undefined) => void;
|
|
11
12
|
width?: number;
|
|
12
13
|
}
|
|
13
|
-
export declare const MetricsGraphStrips: ({ cpus, data,
|
|
14
|
+
export declare const MetricsGraphStrips: ({ cpus, data, selectedTimeframe, onSelectedTimeframe, width, }: Props) => JSX.Element;
|
|
14
15
|
export {};
|
|
15
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MetricsGraphStrips/index.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/MetricsGraphStrips/index.tsx"],"names":[],"mappings":"AAkBA,OAAO,EAAC,QAAQ,EAAC,MAAM,eAAe,CAAC;AAGvC,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AACnC,OAAO,EAAY,SAAS,EAAC,MAAM,aAAa,CAAC;AAEjD,UAAU,KAAK;IACb,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;IACpB,iBAAiB,CAAC,EAAE;QAClB,MAAM,EAAE,QAAQ,CAAC;QACjB,MAAM,EAAE,SAAS,CAAC;KACnB,CAAC;IACF,mBAAmB,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,GAAG,SAAS,KAAK,IAAI,CAAC;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AA2BD,eAAO,MAAM,kBAAkB,mEAM5B,KAAK,KAAG,GAAG,CAAC,OAgEd,CAAC"}
|
|
@@ -16,10 +16,26 @@ import { Icon } from '@iconify/react';
|
|
|
16
16
|
import * as d3 from 'd3';
|
|
17
17
|
import { TimelineGuide } from '../TimelineGuide';
|
|
18
18
|
import { AreaGraph } from './AreaGraph';
|
|
19
|
+
const labelSetToString = (labelSet) => {
|
|
20
|
+
if (labelSet === undefined) {
|
|
21
|
+
return '{}';
|
|
22
|
+
}
|
|
23
|
+
let str = '{';
|
|
24
|
+
let isFirst = true;
|
|
25
|
+
for (const label of labelSet.labels) {
|
|
26
|
+
if (!isFirst) {
|
|
27
|
+
str += ', ';
|
|
28
|
+
isFirst = false;
|
|
29
|
+
}
|
|
30
|
+
str += `${label.name}: ${label.value}`;
|
|
31
|
+
}
|
|
32
|
+
str += '}';
|
|
33
|
+
return str;
|
|
34
|
+
};
|
|
19
35
|
const getTimelineGuideHeight = (cpus, collapsedIndices) => {
|
|
20
36
|
return 56 * (cpus.length - collapsedIndices.length) + 20 * collapsedIndices.length + 24;
|
|
21
37
|
};
|
|
22
|
-
export const MetricsGraphStrips = ({ cpus, data,
|
|
38
|
+
export const MetricsGraphStrips = ({ cpus, data, selectedTimeframe, onSelectedTimeframe, width, }) => {
|
|
23
39
|
const [collapsedIndices, setCollapsedIndices] = useState([]);
|
|
24
40
|
// @ts-expect-error
|
|
25
41
|
const color = d3.scaleOrdinal(d3.schemeObservable10);
|
|
@@ -35,6 +51,7 @@ export const MetricsGraphStrips = ({ cpus, data, selectedTimeline, onSelectedTim
|
|
|
35
51
|
}, [data]);
|
|
36
52
|
return (_jsxs("div", { className: "flex flex-col gap-1 relative my-0 ml-[70px]", style: { width: width ?? '100%' }, children: [_jsx(TimelineGuide, { bounds: bounds, width: width ?? 1468, height: getTimelineGuideHeight(cpus, collapsedIndices), margin: 1 }), cpus.map((cpu, i) => {
|
|
37
53
|
const isCollapsed = collapsedIndices.includes(i);
|
|
54
|
+
const labelStr = labelSetToString(cpu);
|
|
38
55
|
return (_jsxs("div", { className: "relative min-h-5", style: { width: width ?? 1468 }, children: [_jsxs("div", { className: "text-xs absolute top-0 left-0 flex gap-[2px] items-center bg-white/50 px-1 rounded-sm cursor-pointer z-30", onClick: () => {
|
|
39
56
|
const newCollapsedIndices = [...collapsedIndices];
|
|
40
57
|
if (collapsedIndices.includes(i)) {
|
|
@@ -44,8 +61,8 @@ export const MetricsGraphStrips = ({ cpus, data, selectedTimeline, onSelectedTim
|
|
|
44
61
|
newCollapsedIndices.push(i);
|
|
45
62
|
}
|
|
46
63
|
setCollapsedIndices(newCollapsedIndices);
|
|
47
|
-
}, children: [_jsx(Icon, { icon: isCollapsed ? 'bxs:right-arrow' : 'bxs:down-arrow' }),
|
|
48
|
-
|
|
49
|
-
} })) : null] },
|
|
64
|
+
}, children: [_jsx(Icon, { icon: isCollapsed ? 'bxs:right-arrow' : 'bxs:down-arrow' }), labelStr] }), !isCollapsed ? (_jsx(AreaGraph, { data: data[i], height: 56, width: width ?? 1468, fill: color(labelStr), selectionBounds: cpu === selectedTimeframe?.labels ? selectedTimeframe.bounds : undefined, setSelectionBounds: bounds => {
|
|
65
|
+
onSelectedTimeframe(cpu, bounds);
|
|
66
|
+
} })) : null] }, labelStr));
|
|
50
67
|
})] }));
|
|
51
68
|
};
|
|
@@ -9,6 +9,7 @@ export declare const FIELD_MAPPING_BUILD_ID = "mapping_build_id";
|
|
|
9
9
|
export declare const FIELD_LOCATION_ADDRESS = "location_address";
|
|
10
10
|
export declare const FIELD_LOCATION_LINE = "location_line";
|
|
11
11
|
export declare const FIELD_INLINED = "inlined";
|
|
12
|
+
export declare const FIELD_TIMESTAMP = "timestamp";
|
|
12
13
|
export declare const FIELD_FUNCTION_NAME = "function_name";
|
|
13
14
|
export declare const FIELD_FUNCTION_SYSTEM_NAME = "function_system_name";
|
|
14
15
|
export declare const FIELD_FUNCTION_FILE_NAME = "function_file_name";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgE,MAAM,OAAO,CAAC;AAKrF,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAQ1C,OAAO,EAA2B,KAAK,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAO5E,OAAO,EAAwB,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAIxE,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAC/C,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AACjD,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AACjE,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAC7D,eAAO,MAAM,yBAAyB,uBAAuB,CAAC;AAC9D,eAAO,MAAM,cAAc,aAAa,CAAC;AACzC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAC7C,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,UAAU,SAAS,CAAC;AAEjC,UAAU,qBAAqB;IAC7B,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,gBAAgB,iBACb,MAAM,EAAE,cACV,OAAO,uBACE,WAAW,KAC/B,aAQF,CAAC;AAEF,eAAO,MAAM,iBAAiB,kBACb,MAAM,EAAE,cACX,OAAO,uBACE,WAAW,KAC/B,aAQF,CAAC;AAIF,eAAO,MAAM,gBAAgB,mDAiR3B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAgE,MAAM,OAAO,CAAC;AAKrF,OAAO,EAAC,eAAe,EAAC,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAQ1C,OAAO,EAA2B,KAAK,WAAW,EAAC,MAAM,kBAAkB,CAAC;AAO5E,OAAO,EAAwB,aAAa,EAAC,MAAM,oBAAoB,CAAC;AAIxE,eAAO,MAAM,iBAAiB,gBAAgB,CAAC;AAC/C,eAAO,MAAM,kBAAkB,iBAAiB,CAAC;AACjD,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,sBAAsB,qBAAqB,CAAC;AACzD,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,aAAa,YAAY,CAAC;AACvC,eAAO,MAAM,eAAe,cAAc,CAAC;AAC3C,eAAO,MAAM,mBAAmB,kBAAkB,CAAC;AACnD,eAAO,MAAM,0BAA0B,yBAAyB,CAAC;AACjE,eAAO,MAAM,wBAAwB,uBAAuB,CAAC;AAC7D,eAAO,MAAM,yBAAyB,uBAAuB,CAAC;AAC9D,eAAO,MAAM,cAAc,aAAa,CAAC;AACzC,eAAO,MAAM,YAAY,WAAW,CAAC;AACrC,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAC7C,eAAO,MAAM,UAAU,SAAS,CAAC;AACjC,eAAO,MAAM,UAAU,SAAS,CAAC;AAEjC,UAAU,qBAAqB;IAC7B,KAAK,EAAE,eAAe,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,wBAAwB,EAAE,MAAM,EAAE,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED,eAAO,MAAM,gBAAgB,iBACb,MAAM,EAAE,cACV,OAAO,uBACE,WAAW,KAC/B,aAQF,CAAC;AAEF,eAAO,MAAM,iBAAiB,kBACb,MAAM,EAAE,cACX,OAAO,uBACE,WAAW,KAC/B,aAQF,CAAC;AAIF,eAAO,MAAM,gBAAgB,mDAiR3B,CAAC;AAEH,eAAe,gBAAgB,CAAC"}
|
|
@@ -32,6 +32,7 @@ export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
|
|
|
32
32
|
export const FIELD_LOCATION_ADDRESS = 'location_address';
|
|
33
33
|
export const FIELD_LOCATION_LINE = 'location_line';
|
|
34
34
|
export const FIELD_INLINED = 'inlined';
|
|
35
|
+
export const FIELD_TIMESTAMP = 'timestamp';
|
|
35
36
|
export const FIELD_FUNCTION_NAME = 'function_name';
|
|
36
37
|
export const FIELD_FUNCTION_SYSTEM_NAME = 'function_system_name';
|
|
37
38
|
export const FIELD_FUNCTION_FILE_NAME = 'function_file_name';
|
|
@@ -17,8 +17,7 @@ interface ProfileIcicleGraphProps {
|
|
|
17
17
|
isHalfScreen: boolean;
|
|
18
18
|
metadataMappingFiles?: string[];
|
|
19
19
|
metadataLoading?: boolean;
|
|
20
|
-
showTimelineGuide?: boolean;
|
|
21
20
|
}
|
|
22
|
-
declare const ProfileIcicleGraph: ({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, loading, error, width, isHalfScreen, metadataMappingFiles,
|
|
21
|
+
declare const ProfileIcicleGraph: ({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, }: ProfileIcicleGraphProps) => JSX.Element;
|
|
23
22
|
export default ProfileIcicleGraph;
|
|
24
23
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAI1D,OAAO,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAY1C,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACvB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileIcicleGraph/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAqC,MAAM,OAAO,CAAC;AAI1D,OAAO,EAAC,UAAU,EAAE,eAAe,EAAC,MAAM,eAAe,CAAC;AAE1D,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAY1C,MAAM,MAAM,aAAa,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,UAAU,uBAAuB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IACvB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAAK,IAAI,CAAC;IACxD,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,YAAY,EAAE,OAAO,CAAC;IACtB,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAMD,QAAA,MAAM,kBAAkB,uIAarB,uBAAuB,KAAG,GAAG,CAAC,OA2LhC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -25,9 +25,9 @@ const numberFormatter = new Intl.NumberFormat('en-US');
|
|
|
25
25
|
const ErrorContent = ({ errorMessage }) => {
|
|
26
26
|
return _jsx("div", { className: "flex justify-center p-10", children: errorMessage });
|
|
27
27
|
};
|
|
28
|
-
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, loading, error, width, isHalfScreen, metadataMappingFiles,
|
|
28
|
+
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, total, filtered, curPath, setNewCurPath, profileType, loading, error, width, isHalfScreen, metadataMappingFiles, }) {
|
|
29
29
|
const { onError, authenticationErrorMessage, isDarkMode } = useParcaContext();
|
|
30
|
-
const { compareMode } = useProfileViewContext();
|
|
30
|
+
const { compareMode, timelineGuide } = useProfileViewContext();
|
|
31
31
|
const [isLoading, setIsLoading] = useState(true);
|
|
32
32
|
const mappingsList = useMappingList(metadataMappingFiles);
|
|
33
33
|
const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState('sort_by');
|
|
@@ -83,7 +83,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
83
83
|
if (graph !== undefined)
|
|
84
84
|
return (_jsx(IcicleGraph, { width: width, graph: graph, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, profileType: profileType }));
|
|
85
85
|
if (arrow !== undefined)
|
|
86
|
-
return (_jsxs("div", { className: "relative", children: [
|
|
86
|
+
return (_jsxs("div", { className: "relative", children: [timelineGuide?.show === true && (_jsx(TimelineGuide, { bounds: timelineGuide.props.bounds, width: width, height: 1000, margin: 0, ticks: 60000 / 10000 })), _jsx(IcicleGraphArrow, { width: width, arrow: arrow, total: total, filtered: filtered, curPath: curPath, setCurPath: setNewCurPath, profileType: profileType, sortBy: storeSortBy, flamegraphLoading: isLoading, isHalfScreen: isHalfScreen, mappingsListFromMetadata: mappingsList, compareAbsolute: isCompareAbsolute })] }));
|
|
87
87
|
}, [
|
|
88
88
|
isLoading,
|
|
89
89
|
graph,
|
|
@@ -100,7 +100,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
100
100
|
isDarkMode,
|
|
101
101
|
mappingsList,
|
|
102
102
|
isCompareAbsolute,
|
|
103
|
-
|
|
103
|
+
timelineGuide,
|
|
104
104
|
]);
|
|
105
105
|
if (error != null) {
|
|
106
106
|
onError?.(error);
|
|
@@ -20,8 +20,7 @@ interface GetDashboardItemProps {
|
|
|
20
20
|
perf?: {
|
|
21
21
|
onRender?: ProfilerOnRenderCallback;
|
|
22
22
|
};
|
|
23
|
-
showTimelineGuide?: boolean;
|
|
24
23
|
}
|
|
25
|
-
export declare const getDashboardItem: ({ type, isHalfScreen, dimensions, flamegraphData, topTableData, callgraphData, sourceData, profileSource, total, filtered, curPath, setNewCurPath, currentSearchString, setSearchString, callgraphSVG, perf,
|
|
24
|
+
export declare const getDashboardItem: ({ type, isHalfScreen, dimensions, flamegraphData, topTableData, callgraphData, sourceData, profileSource, total, filtered, curPath, setNewCurPath, currentSearchString, setSearchString, callgraphSVG, perf, }: GetDashboardItemProps) => JSX.Element;
|
|
26
25
|
export {};
|
|
27
26
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAMzD,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/ProfileView/components/DashboardItems/index.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAW,wBAAwB,EAAC,MAAM,OAAO,CAAC;AAMzD,OAAO,EAAC,aAAa,EAAC,MAAM,wBAAwB,CAAC;AAGrD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,YAAY,EACZ,iBAAiB,EAClB,MAAM,2BAA2B,CAAC;AAEnC,UAAU,qBAAqB;IAC7B,IAAI,EAAE,iBAAiB,CAAC;IACxB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACxC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,CAAC,EAAE;QACL,QAAQ,CAAC,EAAE,wBAAwB,CAAC;KACrC,CAAC;CACH;AAED,eAAO,MAAM,gBAAgB,mNAiB1B,qBAAqB,KAAG,GAAG,CAAC,OA+E9B,CAAC"}
|
|
@@ -17,7 +17,7 @@ import Callgraph from '../../../Callgraph';
|
|
|
17
17
|
import ProfileIcicleGraph from '../../../ProfileIcicleGraph';
|
|
18
18
|
import { SourceView } from '../../../SourceView';
|
|
19
19
|
import { Table } from '../../../Table';
|
|
20
|
-
export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphData, topTableData, callgraphData, sourceData, profileSource, total, filtered, curPath, setNewCurPath, currentSearchString, setSearchString, callgraphSVG, perf,
|
|
20
|
+
export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphData, topTableData, callgraphData, sourceData, profileSource, total, filtered, curPath, setNewCurPath, currentSearchString, setSearchString, callgraphSVG, perf, }) => {
|
|
21
21
|
switch (type) {
|
|
22
22
|
case 'icicle':
|
|
23
23
|
return (_jsx(ConditionalWrapper, { condition: perf?.onRender != null, WrapperComponent: Profiler, wrapperProps: {
|
|
@@ -27,7 +27,7 @@ export const getDashboardItem = ({ type, isHalfScreen, dimensions, flamegraphDat
|
|
|
27
27
|
? isHalfScreen
|
|
28
28
|
? (dimensions.width - 54) / 2
|
|
29
29
|
: dimensions.width - 16
|
|
30
|
-
: 0, metadataMappingFiles: flamegraphData.metadataMappingFiles, metadataLoading: flamegraphData.metadataLoading
|
|
30
|
+
: 0, metadataMappingFiles: flamegraphData.metadataMappingFiles, metadataLoading: flamegraphData.metadataLoading }) }));
|
|
31
31
|
case 'callgraph':
|
|
32
32
|
return callgraphData?.data !== undefined &&
|
|
33
33
|
callgraphSVG !== undefined &&
|
|
@@ -1,8 +1,18 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
import { ProfileSource } from '../../ProfileSource';
|
|
3
|
+
import { NumberDuo } from '../../utils';
|
|
4
|
+
export type TimelineGuideData = {
|
|
5
|
+
show: false;
|
|
6
|
+
} | {
|
|
7
|
+
show: true;
|
|
8
|
+
props: {
|
|
9
|
+
bounds: NumberDuo;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
3
12
|
interface Props {
|
|
4
13
|
profileSource?: ProfileSource;
|
|
5
14
|
compareMode: boolean;
|
|
15
|
+
timelineGuide?: TimelineGuideData;
|
|
6
16
|
}
|
|
7
17
|
export declare const defaultValue: Props;
|
|
8
18
|
declare const ProfileViewContext: import("react").Context<Props>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileViewContext.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/context/ProfileViewContext.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,SAAS,EAA4B,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ProfileViewContext.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/context/ProfileViewContext.tsx"],"names":[],"mappings":"AAaA,OAAO,EAAC,SAAS,EAA4B,MAAM,OAAO,CAAC;AAE3D,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AAEtC,MAAM,MAAM,iBAAiB,GACzB;IAAC,IAAI,EAAE,KAAK,CAAA;CAAC,GACb;IACE,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE;QACL,MAAM,EAAE,SAAS,CAAC;KACnB,CAAC;CACH,CAAC;AAEN,UAAU,KAAK;IACb,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED,eAAO,MAAM,YAAY,EAAE,KAI1B,CAAC;AAEF,QAAA,MAAM,kBAAkB,gCAAqC,CAAC;AAE9D,eAAO,MAAM,0BAA0B,yBAGpC;IACD,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;CACf,KAAG,GAAG,CAAC,OAMP,CAAC;AAEF,eAAO,MAAM,qBAAqB,QAAO,KAMxC,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
|
|
@@ -15,6 +15,7 @@ import { createContext, useContext } from 'react';
|
|
|
15
15
|
export const defaultValue = {
|
|
16
16
|
profileSource: undefined,
|
|
17
17
|
compareMode: false,
|
|
18
|
+
timelineGuide: { show: false },
|
|
18
19
|
};
|
|
19
20
|
const ProfileViewContext = createContext(defaultValue);
|
|
20
21
|
export const ProfileViewContextProvider = ({ children, value, }) => {
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { ProfileViewProps } from './types/visualization';
|
|
2
|
-
export declare const ProfileView: ({ total, filtered, flamegraphData, topTableData, callgraphData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector,
|
|
2
|
+
export declare const ProfileView: ({ total, filtered, flamegraphData, topTableData, callgraphData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, timelineGuide, }: ProfileViewProps) => JSX.Element;
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAG/E,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ProfileView/index.tsx"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAC,gBAAgB,EAAoB,MAAM,uBAAuB,CAAC;AAG/E,eAAO,MAAM,WAAW,oMAcrB,gBAAgB,KAAG,GAAG,CAAC,OAwIzB,CAAC"}
|
|
@@ -26,7 +26,7 @@ import { useGraphviz } from './hooks/useGraphviz';
|
|
|
26
26
|
import { useProfileMetadata } from './hooks/useProfileMetadata';
|
|
27
27
|
import { useVisualizationState } from './hooks/useVisualizationState';
|
|
28
28
|
import { getColorRange } from './utils/colorUtils';
|
|
29
|
-
export const ProfileView = ({ total, filtered, flamegraphData, topTableData, callgraphData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector,
|
|
29
|
+
export const ProfileView = ({ total, filtered, flamegraphData, topTableData, callgraphData, sourceData, profileSource, queryClient, onDownloadPProf, pprofDownloading, compare, showVisualizationSelector, timelineGuide, }) => {
|
|
30
30
|
const { timezone, perf, profileViewExternalMainActions, preferencesModal, profileViewExternalSubActions, } = useParcaContext();
|
|
31
31
|
const { ref, dimensions } = useContainerDimensions();
|
|
32
32
|
const isDarkMode = useAppSelector(selectDarkMode);
|
|
@@ -64,7 +64,6 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
|
|
|
64
64
|
setSearchString,
|
|
65
65
|
callgraphSVG,
|
|
66
66
|
perf,
|
|
67
|
-
showTimelineGuide,
|
|
68
67
|
});
|
|
69
68
|
};
|
|
70
69
|
const actionButtons = {
|
|
@@ -72,5 +71,5 @@ export const ProfileView = ({ total, filtered, flamegraphData, topTableData, cal
|
|
|
72
71
|
table: (_jsx(TableToolbar, { profileType: profileSource?.ProfileType(), total: total, filtered: filtered, clearSelection: clearSelection, currentSearchString: currentSearchString })),
|
|
73
72
|
};
|
|
74
73
|
const hasProfileSource = profileSource !== undefined && profileSource.toString(timezone) !== '';
|
|
75
|
-
return (_jsx(KeyDownProvider, { children: _jsx(ProfileViewContextProvider, { value: { profileSource, compareMode }, children: _jsxs(DashboardProvider, { children: [_jsx(ProfileHeader, { profileSourceString: profileSource?.toString(timezone), hasProfileSource: hasProfileSource, externalMainActions: profileViewExternalMainActions }), _jsx(VisualisationToolbar, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, hasProfileSource: hasProfileSource, pprofdownloading: pprofDownloading, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: onDownloadPProf, curPath: curPath, setNewCurPath: setCurPath, profileType: profileSource?.ProfileType(), total: total, filtered: filtered, currentSearchString: currentSearchString, setSearchString: setSearchString, groupByLabels: flamegraphData.metadataLabels ?? [], preferencesModal: preferencesModal, profileViewExternalSubActions: profileViewExternalSubActions, clearSelection: clearSelection, setGroupByLabels: setGroupByLabels, showVisualizationSelector: showVisualizationSelector }), isColorStackLegendEnabled && (_jsx(ColorStackLegend, { compareMode: compareMode, mappings: colorMappings, loading: flamegraphData.metadataLoading })), _jsx("div", { className: "w-full", ref: ref, children: _jsx(DashboardLayout, { getDashboardItemByType: getDashboardItemByType, actionButtons: actionButtons }) })] }) }) }));
|
|
74
|
+
return (_jsx(KeyDownProvider, { children: _jsx(ProfileViewContextProvider, { value: { profileSource, compareMode, timelineGuide }, children: _jsxs(DashboardProvider, { children: [_jsx(ProfileHeader, { profileSourceString: profileSource?.toString(timezone), hasProfileSource: hasProfileSource, externalMainActions: profileViewExternalMainActions }), _jsx(VisualisationToolbar, { groupBy: groupBy, toggleGroupBy: toggleGroupBy, hasProfileSource: hasProfileSource, pprofdownloading: pprofDownloading, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: onDownloadPProf, curPath: curPath, setNewCurPath: setCurPath, profileType: profileSource?.ProfileType(), total: total, filtered: filtered, currentSearchString: currentSearchString, setSearchString: setSearchString, groupByLabels: flamegraphData.metadataLabels ?? [], preferencesModal: preferencesModal, profileViewExternalSubActions: profileViewExternalSubActions, clearSelection: clearSelection, setGroupByLabels: setGroupByLabels, showVisualizationSelector: showVisualizationSelector }), isColorStackLegendEnabled && (_jsx(ColorStackLegend, { compareMode: compareMode, mappings: colorMappings, loading: flamegraphData.metadataLoading })), _jsx("div", { className: "w-full", ref: ref, children: _jsx(DashboardLayout, { getDashboardItemByType: getDashboardItemByType, actionButtons: actionButtons }) })] }) }) }));
|
|
76
75
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Callgraph as CallgraphType, Flamegraph, FlamegraphArrow, QueryServiceClient, Source, TableArrow } from '@parca/client';
|
|
2
2
|
import { ProfileSource } from '../../ProfileSource';
|
|
3
|
+
import { TimelineGuideData } from '../context/ProfileViewContext';
|
|
3
4
|
export interface FlamegraphData {
|
|
4
5
|
loading: boolean;
|
|
5
6
|
data?: Flamegraph;
|
|
@@ -46,5 +47,6 @@ export interface ProfileViewProps {
|
|
|
46
47
|
pprofDownloading?: boolean;
|
|
47
48
|
showVisualizationSelector?: boolean;
|
|
48
49
|
showTimelineGuide?: boolean;
|
|
50
|
+
timelineGuide?: TimelineGuideData;
|
|
49
51
|
}
|
|
50
52
|
//# sourceMappingURL=visualization.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/types/visualization.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,SAAS,IAAI,aAAa,EAC1B,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,UAAU,EACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"visualization.d.ts","sourceRoot":"","sources":["../../../src/ProfileView/types/visualization.ts"],"names":[],"mappings":"AAaA,OAAO,EACL,SAAS,IAAI,aAAa,EAC1B,UAAU,EACV,eAAe,EACf,kBAAkB,EAClB,MAAM,EACN,UAAU,EACX,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAC,aAAa,EAAC,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAC,iBAAiB,EAAC,MAAM,+BAA+B,CAAC;AAEhE,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC,eAAe,EAAE,OAAO,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,GAAG,CAAC;CACb;AAED,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE5E,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,cAAc,CAAC;IAC/B,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,MAAM,IAAI,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { QueryServiceClient } from '@parca/client';
|
|
2
2
|
import { ProfileSource } from './ProfileSource';
|
|
3
|
+
import { TimelineGuideData } from './ProfileView/context/ProfileViewContext';
|
|
3
4
|
interface ProfileViewWithDataProps {
|
|
4
5
|
queryClient: QueryServiceClient;
|
|
5
6
|
profileSource: ProfileSource;
|
|
6
7
|
compare?: boolean;
|
|
7
8
|
showVisualizationSelector?: boolean;
|
|
8
|
-
|
|
9
|
+
isGroupByTimestamp?: boolean;
|
|
10
|
+
timelineGuide?: TimelineGuideData;
|
|
9
11
|
}
|
|
10
|
-
export declare const ProfileViewWithData: ({ queryClient, profileSource, showVisualizationSelector,
|
|
12
|
+
export declare const ProfileViewWithData: ({ queryClient, profileSource, showVisualizationSelector, isGroupByTimestamp, timelineGuide, }: ProfileViewWithDataProps) => JSX.Element;
|
|
11
13
|
export default ProfileViewWithData;
|
|
12
14
|
//# sourceMappingURL=ProfileViewWithData.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProfileViewWithData.d.ts","sourceRoot":"","sources":["../src/ProfileViewWithData.tsx"],"names":[],"mappings":"AAeA,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAK1E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"ProfileViewWithData.d.ts","sourceRoot":"","sources":["../src/ProfileViewWithData.tsx"],"names":[],"mappings":"AAeA,OAAO,EAA0B,kBAAkB,EAAC,MAAM,eAAe,CAAC;AAK1E,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAE9C,OAAO,EAAC,iBAAiB,EAAC,MAAM,0CAA0C,CAAC;AAI3E,UAAU,wBAAwB;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,aAAa,EAAE,aAAa,CAAC;IAC7B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,aAAa,CAAC,EAAE,iBAAiB,CAAC;CACnC;AAED,eAAO,MAAM,mBAAmB,kGAM7B,wBAAwB,KAAG,GAAG,CAAC,OAsNjC,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
|
|
@@ -15,11 +15,11 @@ import { useEffect, useMemo, useState } from 'react';
|
|
|
15
15
|
import { QueryRequest_ReportType } from '@parca/client';
|
|
16
16
|
import { useGrpcMetadata, useParcaContext, useURLState } from '@parca/components';
|
|
17
17
|
import { saveAsBlob } from '@parca/utilities';
|
|
18
|
-
import { FIELD_FUNCTION_NAME } from './ProfileIcicleGraph/IcicleGraphArrow';
|
|
18
|
+
import { FIELD_FUNCTION_NAME, FIELD_TIMESTAMP } from './ProfileIcicleGraph/IcicleGraphArrow';
|
|
19
19
|
import { ProfileView } from './ProfileView';
|
|
20
20
|
import { useQuery } from './useQuery';
|
|
21
21
|
import { downloadPprof } from './utils';
|
|
22
|
-
export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizationSelector,
|
|
22
|
+
export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizationSelector, isGroupByTimestamp, timelineGuide, }) => {
|
|
23
23
|
const metadata = useGrpcMetadata();
|
|
24
24
|
const [dashboardItems] = useURLState('dashboard_items', {
|
|
25
25
|
alwaysReturnArray: true,
|
|
@@ -27,7 +27,10 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
|
|
|
27
27
|
const [sourceBuildID] = useURLState('source_buildid');
|
|
28
28
|
const [sourceFilename] = useURLState('source_filename');
|
|
29
29
|
const [groupBy] = useURLState('group_by', {
|
|
30
|
-
defaultValue: [
|
|
30
|
+
defaultValue: [
|
|
31
|
+
isGroupByTimestamp === true ? FIELD_TIMESTAMP : null,
|
|
32
|
+
FIELD_FUNCTION_NAME,
|
|
33
|
+
].filter(Boolean),
|
|
31
34
|
alwaysReturnArray: true,
|
|
32
35
|
});
|
|
33
36
|
const [invertStack] = useURLState('invert_call_stack');
|
|
@@ -168,6 +171,6 @@ export const ProfileViewWithData = ({ queryClient, profileSource, showVisualizat
|
|
|
168
171
|
? sourceResponse?.report?.source
|
|
169
172
|
: undefined,
|
|
170
173
|
error: sourceError,
|
|
171
|
-
}, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: () => void downloadPProfClick(), pprofDownloading: pprofDownloading, showVisualizationSelector: showVisualizationSelector,
|
|
174
|
+
}, profileSource: profileSource, queryClient: queryClient, onDownloadPProf: () => void downloadPProfClick(), pprofDownloading: pprofDownloading, showVisualizationSelector: showVisualizationSelector, timelineGuide: timelineGuide }));
|
|
172
175
|
};
|
|
173
176
|
export default ProfileViewWithData;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/TimelineGuide/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AAEnC,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD,eAAO,MAAM,aAAa,6CAA4C,KAAK,KAAG,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/TimelineGuide/index.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAC,SAAS,EAAC,MAAM,UAAU,CAAC;AAEnC,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAaD,eAAO,MAAM,aAAa,6CAA4C,KAAK,KAAG,GAAG,CAAC,OAyDjF,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export * from './ProfileViewWithData';
|
|
|
11
11
|
export * from './utils';
|
|
12
12
|
export * from './ProfileTypeSelector';
|
|
13
13
|
export * from './SourceView';
|
|
14
|
+
export * from './ProfileMetricsGraph';
|
|
14
15
|
export { default as Callgraph } from './Callgraph';
|
|
15
16
|
export declare const DEFAULT_PROFILE_EXPLORER_PARAM_VALUES: {
|
|
16
17
|
dashboard_items: string;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,KAAK,IAAI,cAAc,EAAC,MAAM,aAAa,CAAC;AACzD,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAC9C,OAAO,eAAe,EAAE,EAAC,sBAAsB,EAAC,MAAM,mBAAmB,CAAC;AAC1E,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,YAAY,MAAM,yBAAyB,CAAC;AAEnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,qCAAqC;;CAEjD,CAAC;AAEF,YAAY,EAAC,cAAc,EAAC,CAAC;AAE7B,OAAO,EAAC,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,YAAY,EAAE,aAAa,EAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAC,KAAK,IAAI,cAAc,EAAC,MAAM,aAAa,CAAC;AACzD,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAC9C,OAAO,eAAe,EAAE,EAAC,sBAAsB,EAAC,MAAM,mBAAmB,CAAC;AAC1E,OAAO,mBAAmB,MAAM,uBAAuB,CAAC;AACxD,OAAO,YAAY,MAAM,yBAAyB,CAAC;AAEnD,cAAc,kCAAkC,CAAC;AACjD,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,cAAc,eAAe,CAAC;AAC9B,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,uBAAuB,CAAC;AACtC,cAAc,cAAc,CAAC;AAC7B,cAAc,uBAAuB,CAAC;AACtC,OAAO,EAAC,OAAO,IAAI,SAAS,EAAC,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,qCAAqC;;CAEjD,CAAC;AAEF,YAAY,EAAC,cAAc,EAAC,CAAC;AAE7B,OAAO,EAAC,eAAe,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,YAAY,EAAE,aAAa,EAAC,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,7 @@ export * from './ProfileViewWithData';
|
|
|
22
22
|
export * from './utils';
|
|
23
23
|
export * from './ProfileTypeSelector';
|
|
24
24
|
export * from './SourceView';
|
|
25
|
+
export * from './ProfileMetricsGraph';
|
|
25
26
|
export { default as Callgraph } from './Callgraph';
|
|
26
27
|
export const DEFAULT_PROFILE_EXPLORER_PARAM_VALUES = {
|
|
27
28
|
dashboard_items: 'icicle',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.453",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@headlessui/react": "^1.7.19",
|
|
@@ -74,5 +74,5 @@
|
|
|
74
74
|
"access": "public",
|
|
75
75
|
"registry": "https://registry.npmjs.org/"
|
|
76
76
|
},
|
|
77
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "2e1089b0b34e67c26a29567db2c1e30e9516d10e"
|
|
78
78
|
}
|
|
@@ -46,21 +46,21 @@ export default meta;
|
|
|
46
46
|
|
|
47
47
|
export const ThreeCPUStrips = {
|
|
48
48
|
args: {
|
|
49
|
-
cpus: Array.from(mockData, (_, i) =>
|
|
49
|
+
cpus: Array.from(mockData, (_, i) => ({labels: [{name: 'cpuid', value: i + 1}]})),
|
|
50
50
|
data: mockData,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
console.log('
|
|
51
|
+
selectedTimeframe: {index: 1, bounds: [mockData[0][25].timestamp, mockData[0][100].timestamp]},
|
|
52
|
+
onSelectedTimeframe: (index: number, bounds: NumberDuo): void => {
|
|
53
|
+
console.log('onSelectedTimeframe', index, bounds);
|
|
54
54
|
},
|
|
55
55
|
},
|
|
56
56
|
render: function Component(args: any): JSX.Element {
|
|
57
57
|
const [, setArgs] = useArgs();
|
|
58
58
|
|
|
59
|
-
const
|
|
60
|
-
args.
|
|
61
|
-
setArgs({...args,
|
|
59
|
+
const onSelectedTimeframe = (index: number, bounds: NumberDuo): void => {
|
|
60
|
+
args.onSelectedTimeframe(index, bounds);
|
|
61
|
+
setArgs({...args, selectedTimeframe: {index, bounds}});
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
return <MetricsGraphStrips {...args}
|
|
64
|
+
return <MetricsGraphStrips {...args} onSelectedTimeframe={onSelectedTimeframe} />;
|
|
65
65
|
},
|
|
66
66
|
};
|
|
@@ -16,30 +16,53 @@ import {useMemo, useState} from 'react';
|
|
|
16
16
|
import {Icon} from '@iconify/react';
|
|
17
17
|
import * as d3 from 'd3';
|
|
18
18
|
|
|
19
|
+
import {LabelSet} from '@parca/client';
|
|
20
|
+
|
|
19
21
|
import {TimelineGuide} from '../TimelineGuide';
|
|
20
22
|
import {NumberDuo} from '../utils';
|
|
21
23
|
import {AreaGraph, DataPoint} from './AreaGraph';
|
|
22
24
|
|
|
23
25
|
interface Props {
|
|
24
|
-
cpus:
|
|
26
|
+
cpus: LabelSet[];
|
|
25
27
|
data: DataPoint[][];
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
selectedTimeframe?: {
|
|
29
|
+
labels: LabelSet;
|
|
28
30
|
bounds: NumberDuo;
|
|
29
31
|
};
|
|
30
|
-
|
|
32
|
+
onSelectedTimeframe: (labels: LabelSet, bounds: NumberDuo | undefined) => void;
|
|
31
33
|
width?: number;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
|
-
const
|
|
36
|
+
const labelSetToString = (labelSet?: LabelSet): string => {
|
|
37
|
+
if (labelSet === undefined) {
|
|
38
|
+
return '{}';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let str = '{';
|
|
42
|
+
|
|
43
|
+
let isFirst = true;
|
|
44
|
+
for (const label of labelSet.labels) {
|
|
45
|
+
if (!isFirst) {
|
|
46
|
+
str += ', ';
|
|
47
|
+
isFirst = false;
|
|
48
|
+
}
|
|
49
|
+
str += `${label.name}: ${label.value}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
str += '}';
|
|
53
|
+
|
|
54
|
+
return str;
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const getTimelineGuideHeight = (cpus: LabelSet[], collapsedIndices: number[]): number => {
|
|
35
58
|
return 56 * (cpus.length - collapsedIndices.length) + 20 * collapsedIndices.length + 24;
|
|
36
59
|
};
|
|
37
60
|
|
|
38
61
|
export const MetricsGraphStrips = ({
|
|
39
62
|
cpus,
|
|
40
63
|
data,
|
|
41
|
-
|
|
42
|
-
|
|
64
|
+
selectedTimeframe,
|
|
65
|
+
onSelectedTimeframe,
|
|
43
66
|
width,
|
|
44
67
|
}: Props): JSX.Element => {
|
|
45
68
|
const [collapsedIndices, setCollapsedIndices] = useState<number[]>([]);
|
|
@@ -68,8 +91,9 @@ export const MetricsGraphStrips = ({
|
|
|
68
91
|
/>
|
|
69
92
|
{cpus.map((cpu, i) => {
|
|
70
93
|
const isCollapsed = collapsedIndices.includes(i);
|
|
94
|
+
const labelStr = labelSetToString(cpu);
|
|
71
95
|
return (
|
|
72
|
-
<div className="relative min-h-5" style={{width: width ?? 1468}} key={
|
|
96
|
+
<div className="relative min-h-5" style={{width: width ?? 1468}} key={labelStr}>
|
|
73
97
|
<div
|
|
74
98
|
className="text-xs absolute top-0 left-0 flex gap-[2px] items-center bg-white/50 px-1 rounded-sm cursor-pointer z-30"
|
|
75
99
|
onClick={() => {
|
|
@@ -83,19 +107,19 @@ export const MetricsGraphStrips = ({
|
|
|
83
107
|
}}
|
|
84
108
|
>
|
|
85
109
|
<Icon icon={isCollapsed ? 'bxs:right-arrow' : 'bxs:down-arrow'} />
|
|
86
|
-
{
|
|
110
|
+
{labelStr}
|
|
87
111
|
</div>
|
|
88
112
|
{!isCollapsed ? (
|
|
89
113
|
<AreaGraph
|
|
90
114
|
data={data[i]}
|
|
91
115
|
height={56}
|
|
92
116
|
width={width ?? 1468}
|
|
93
|
-
fill={color(
|
|
117
|
+
fill={color(labelStr) as string}
|
|
94
118
|
selectionBounds={
|
|
95
|
-
|
|
119
|
+
cpu === selectedTimeframe?.labels ? selectedTimeframe.bounds : undefined
|
|
96
120
|
}
|
|
97
121
|
setSelectionBounds={bounds => {
|
|
98
|
-
|
|
122
|
+
onSelectedTimeframe(cpu, bounds);
|
|
99
123
|
}}
|
|
100
124
|
/>
|
|
101
125
|
) : null}
|
|
@@ -44,6 +44,7 @@ export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
|
|
|
44
44
|
export const FIELD_LOCATION_ADDRESS = 'location_address';
|
|
45
45
|
export const FIELD_LOCATION_LINE = 'location_line';
|
|
46
46
|
export const FIELD_INLINED = 'inlined';
|
|
47
|
+
export const FIELD_TIMESTAMP = 'timestamp';
|
|
47
48
|
export const FIELD_FUNCTION_NAME = 'function_name';
|
|
48
49
|
export const FIELD_FUNCTION_SYSTEM_NAME = 'function_system_name';
|
|
49
50
|
export const FIELD_FUNCTION_FILE_NAME = 'function_file_name';
|
|
@@ -46,7 +46,6 @@ interface ProfileIcicleGraphProps {
|
|
|
46
46
|
isHalfScreen: boolean;
|
|
47
47
|
metadataMappingFiles?: string[];
|
|
48
48
|
metadataLoading?: boolean;
|
|
49
|
-
showTimelineGuide?: boolean;
|
|
50
49
|
}
|
|
51
50
|
|
|
52
51
|
const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
|
|
@@ -66,10 +65,9 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
66
65
|
width,
|
|
67
66
|
isHalfScreen,
|
|
68
67
|
metadataMappingFiles,
|
|
69
|
-
showTimelineGuide = false,
|
|
70
68
|
}: ProfileIcicleGraphProps): JSX.Element {
|
|
71
69
|
const {onError, authenticationErrorMessage, isDarkMode} = useParcaContext();
|
|
72
|
-
const {compareMode} = useProfileViewContext();
|
|
70
|
+
const {compareMode, timelineGuide} = useProfileViewContext();
|
|
73
71
|
const [isLoading, setIsLoading] = useState<boolean>(true);
|
|
74
72
|
|
|
75
73
|
const mappingsList = useMappingList(metadataMappingFiles);
|
|
@@ -169,9 +167,9 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
169
167
|
if (arrow !== undefined)
|
|
170
168
|
return (
|
|
171
169
|
<div className="relative">
|
|
172
|
-
{
|
|
170
|
+
{timelineGuide?.show === true && (
|
|
173
171
|
<TimelineGuide
|
|
174
|
-
bounds={
|
|
172
|
+
bounds={timelineGuide.props.bounds}
|
|
175
173
|
width={width}
|
|
176
174
|
height={1000}
|
|
177
175
|
margin={0}
|
|
@@ -210,7 +208,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
210
208
|
isDarkMode,
|
|
211
209
|
mappingsList,
|
|
212
210
|
isCompareAbsolute,
|
|
213
|
-
|
|
211
|
+
timelineGuide,
|
|
214
212
|
]);
|
|
215
213
|
|
|
216
214
|
if (error != null) {
|
|
@@ -47,7 +47,6 @@ interface GetDashboardItemProps {
|
|
|
47
47
|
perf?: {
|
|
48
48
|
onRender?: ProfilerOnRenderCallback;
|
|
49
49
|
};
|
|
50
|
-
showTimelineGuide?: boolean;
|
|
51
50
|
}
|
|
52
51
|
|
|
53
52
|
export const getDashboardItem = ({
|
|
@@ -67,7 +66,6 @@ export const getDashboardItem = ({
|
|
|
67
66
|
setSearchString,
|
|
68
67
|
callgraphSVG,
|
|
69
68
|
perf,
|
|
70
|
-
showTimelineGuide,
|
|
71
69
|
}: GetDashboardItemProps): JSX.Element => {
|
|
72
70
|
switch (type) {
|
|
73
71
|
case 'icicle':
|
|
@@ -100,7 +98,6 @@ export const getDashboardItem = ({
|
|
|
100
98
|
}
|
|
101
99
|
metadataMappingFiles={flamegraphData.metadataMappingFiles}
|
|
102
100
|
metadataLoading={flamegraphData.metadataLoading}
|
|
103
|
-
showTimelineGuide={showTimelineGuide}
|
|
104
101
|
/>
|
|
105
102
|
</ConditionalWrapper>
|
|
106
103
|
);
|
|
@@ -14,15 +14,27 @@
|
|
|
14
14
|
import {ReactNode, createContext, useContext} from 'react';
|
|
15
15
|
|
|
16
16
|
import {ProfileSource} from '../../ProfileSource';
|
|
17
|
+
import {NumberDuo} from '../../utils';
|
|
18
|
+
|
|
19
|
+
export type TimelineGuideData =
|
|
20
|
+
| {show: false}
|
|
21
|
+
| {
|
|
22
|
+
show: true;
|
|
23
|
+
props: {
|
|
24
|
+
bounds: NumberDuo;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
17
27
|
|
|
18
28
|
interface Props {
|
|
19
29
|
profileSource?: ProfileSource;
|
|
20
30
|
compareMode: boolean;
|
|
31
|
+
timelineGuide?: TimelineGuideData;
|
|
21
32
|
}
|
|
22
33
|
|
|
23
34
|
export const defaultValue: Props = {
|
|
24
35
|
profileSource: undefined,
|
|
25
36
|
compareMode: false,
|
|
37
|
+
timelineGuide: {show: false},
|
|
26
38
|
};
|
|
27
39
|
|
|
28
40
|
const ProfileViewContext = createContext<Props>(defaultValue);
|
|
@@ -42,7 +42,7 @@ export const ProfileView = ({
|
|
|
42
42
|
pprofDownloading,
|
|
43
43
|
compare,
|
|
44
44
|
showVisualizationSelector,
|
|
45
|
-
|
|
45
|
+
timelineGuide,
|
|
46
46
|
}: ProfileViewProps): JSX.Element => {
|
|
47
47
|
const {
|
|
48
48
|
timezone,
|
|
@@ -110,7 +110,6 @@ export const ProfileView = ({
|
|
|
110
110
|
setSearchString,
|
|
111
111
|
callgraphSVG,
|
|
112
112
|
perf,
|
|
113
|
-
showTimelineGuide,
|
|
114
113
|
});
|
|
115
114
|
};
|
|
116
115
|
|
|
@@ -131,7 +130,7 @@ export const ProfileView = ({
|
|
|
131
130
|
|
|
132
131
|
return (
|
|
133
132
|
<KeyDownProvider>
|
|
134
|
-
<ProfileViewContextProvider value={{profileSource, compareMode}}>
|
|
133
|
+
<ProfileViewContextProvider value={{profileSource, compareMode, timelineGuide}}>
|
|
135
134
|
<DashboardProvider>
|
|
136
135
|
<ProfileHeader
|
|
137
136
|
profileSourceString={profileSource?.toString(timezone)}
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
} from '@parca/client';
|
|
22
22
|
|
|
23
23
|
import {ProfileSource} from '../../ProfileSource';
|
|
24
|
+
import {TimelineGuideData} from '../context/ProfileViewContext';
|
|
24
25
|
|
|
25
26
|
export interface FlamegraphData {
|
|
26
27
|
loading: boolean;
|
|
@@ -73,4 +74,5 @@ export interface ProfileViewProps {
|
|
|
73
74
|
pprofDownloading?: boolean;
|
|
74
75
|
showVisualizationSelector?: boolean;
|
|
75
76
|
showTimelineGuide?: boolean;
|
|
77
|
+
timelineGuide?: TimelineGuideData;
|
|
76
78
|
}
|
|
@@ -17,9 +17,10 @@ import {QueryRequest_ReportType, QueryServiceClient} from '@parca/client';
|
|
|
17
17
|
import {useGrpcMetadata, useParcaContext, useURLState} from '@parca/components';
|
|
18
18
|
import {saveAsBlob} from '@parca/utilities';
|
|
19
19
|
|
|
20
|
-
import {FIELD_FUNCTION_NAME} from './ProfileIcicleGraph/IcicleGraphArrow';
|
|
20
|
+
import {FIELD_FUNCTION_NAME, FIELD_TIMESTAMP} from './ProfileIcicleGraph/IcicleGraphArrow';
|
|
21
21
|
import {ProfileSource} from './ProfileSource';
|
|
22
22
|
import {ProfileView} from './ProfileView';
|
|
23
|
+
import {TimelineGuideData} from './ProfileView/context/ProfileViewContext';
|
|
23
24
|
import {useQuery} from './useQuery';
|
|
24
25
|
import {downloadPprof} from './utils';
|
|
25
26
|
|
|
@@ -28,14 +29,16 @@ interface ProfileViewWithDataProps {
|
|
|
28
29
|
profileSource: ProfileSource;
|
|
29
30
|
compare?: boolean;
|
|
30
31
|
showVisualizationSelector?: boolean;
|
|
31
|
-
|
|
32
|
+
isGroupByTimestamp?: boolean;
|
|
33
|
+
timelineGuide?: TimelineGuideData;
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
export const ProfileViewWithData = ({
|
|
35
37
|
queryClient,
|
|
36
38
|
profileSource,
|
|
37
39
|
showVisualizationSelector,
|
|
38
|
-
|
|
40
|
+
isGroupByTimestamp,
|
|
41
|
+
timelineGuide,
|
|
39
42
|
}: ProfileViewWithDataProps): JSX.Element => {
|
|
40
43
|
const metadata = useGrpcMetadata();
|
|
41
44
|
const [dashboardItems] = useURLState<string[]>('dashboard_items', {
|
|
@@ -44,7 +47,10 @@ export const ProfileViewWithData = ({
|
|
|
44
47
|
const [sourceBuildID] = useURLState<string>('source_buildid');
|
|
45
48
|
const [sourceFilename] = useURLState<string>('source_filename');
|
|
46
49
|
const [groupBy] = useURLState<string[]>('group_by', {
|
|
47
|
-
defaultValue: [
|
|
50
|
+
defaultValue: [
|
|
51
|
+
isGroupByTimestamp === true ? FIELD_TIMESTAMP : (null as unknown as string),
|
|
52
|
+
FIELD_FUNCTION_NAME,
|
|
53
|
+
].filter(Boolean),
|
|
48
54
|
alwaysReturnArray: true,
|
|
49
55
|
});
|
|
50
56
|
|
|
@@ -244,7 +250,7 @@ export const ProfileViewWithData = ({
|
|
|
244
250
|
onDownloadPProf={() => void downloadPProfClick()}
|
|
245
251
|
pprofDownloading={pprofDownloading}
|
|
246
252
|
showVisualizationSelector={showVisualizationSelector}
|
|
247
|
-
|
|
253
|
+
timelineGuide={timelineGuide}
|
|
248
254
|
/>
|
|
249
255
|
);
|
|
250
256
|
};
|
|
@@ -88,11 +88,6 @@ export const TimelineGuide = ({bounds, width, height, margin, ticks}: Props): JS
|
|
|
88
88
|
y1={-height + 20}
|
|
89
89
|
y2={-height + 20}
|
|
90
90
|
/>
|
|
91
|
-
{/* <g transform={`translate(${(width - 2.5 * margin) / 2}, ${margin / 2})`}>
|
|
92
|
-
<text fill="currentColor" dy=".71em" y={5} className="text-sm">
|
|
93
|
-
Time
|
|
94
|
-
</text>
|
|
95
|
-
</g> */}
|
|
96
91
|
</g>
|
|
97
92
|
</svg>
|
|
98
93
|
</div>
|
package/src/index.tsx
CHANGED
|
@@ -25,6 +25,7 @@ export * from './ProfileViewWithData';
|
|
|
25
25
|
export * from './utils';
|
|
26
26
|
export * from './ProfileTypeSelector';
|
|
27
27
|
export * from './SourceView';
|
|
28
|
+
export * from './ProfileMetricsGraph';
|
|
28
29
|
export {default as Callgraph} from './Callgraph';
|
|
29
30
|
|
|
30
31
|
export const DEFAULT_PROFILE_EXPLORER_PARAM_VALUES = {
|