Skip to content

Commit

Permalink
area/ui: Customisable TimelineGuide component (#5333)
Browse files Browse the repository at this point in the history
* Extracting TimelineGuide from MetricGraphStrips and making it reusable

* Fix visual regression tests for MetricsGraphStrips story

* Added ticks count to the props

* Removed the unwanted styles

* Fix z-index issues with TimelineGuide

* Configurable timeline guide via prop

* Add a `width` prop to the MetricsGraphStrip

---------

Co-authored-by: Manoj Vivek <[email protected]>
  • Loading branch information
yomete and manojVivek authored Dec 2, 2024
1 parent 62c525d commit d99401a
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 19 deletions.
10 changes: 6 additions & 4 deletions ui/packages/shared/profile/src/MetricsGraphStrips/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ interface Props {
bounds: NumberDuo;
};
onSelectedTimeline: (index: number, bounds: NumberDuo | undefined) => void;
width?: number;
}

const getTimelineGuideHeight = (cpus: string[], collapsedIndices: number[]): number => {
Expand All @@ -39,6 +40,7 @@ export const MetricsGraphStrips = ({
data,
selectedTimeline,
onSelectedTimeline,
width,
}: Props): JSX.Element => {
const [collapsedIndices, setCollapsedIndices] = useState<number[]>([]);

Expand All @@ -57,17 +59,17 @@ export const MetricsGraphStrips = ({
}, [data]);

return (
<div className="flex flex-col gap-1 relative">
<div className="flex flex-col gap-1 relative my-0 ml-[70px]" style={{width: width ?? '100%'}}>
<TimelineGuide
bounds={bounds}
width={1468}
width={width ?? 1468}
height={getTimelineGuideHeight(cpus, collapsedIndices)}
margin={1}
/>
{cpus.map((cpu, i) => {
const isCollapsed = collapsedIndices.includes(i);
return (
<div className="relative min-h-5" key={cpu}>
<div className="relative min-h-5" style={{width: width ?? 1468}} key={cpu}>
<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={() => {
Expand All @@ -87,7 +89,7 @@ export const MetricsGraphStrips = ({
<AreaGraph
data={data[i]}
height={56}
width={1468}
width={width ?? 1468}
fill={color(i.toString()) as string}
selectionBounds={
selectedTimeline?.index === i ? selectedTimeline.bounds : undefined
Expand Down
43 changes: 29 additions & 14 deletions ui/packages/shared/profile/src/ProfileIcicleGraph/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {capitalizeOnlyFirstLetter, divide} from '@parca/utilities';

import DiffLegend from '../ProfileView/components/DiffLegend';
import {useProfileViewContext} from '../ProfileView/context/ProfileViewContext';
import {TimelineGuide} from '../TimelineGuide';
import {IcicleGraph} from './IcicleGraph';
import {FIELD_FUNCTION_NAME, IcicleGraphArrow} from './IcicleGraphArrow';
import useMappingList from './IcicleGraphArrow/useMappingList';
Expand All @@ -45,6 +46,7 @@ interface ProfileIcicleGraphProps {
isHalfScreen: boolean;
metadataMappingFiles?: string[];
metadataLoading?: boolean;
showTimelineGuide?: boolean;
}

const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
Expand All @@ -64,6 +66,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
width,
isHalfScreen,
metadataMappingFiles,
showTimelineGuide = false,
}: ProfileIcicleGraphProps): JSX.Element {
const {onError, authenticationErrorMessage, isDarkMode} = useParcaContext();
const {compareMode} = useProfileViewContext();
Expand Down Expand Up @@ -165,20 +168,31 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({

if (arrow !== undefined)
return (
<IcicleGraphArrow
width={width}
arrow={arrow}
total={total}
filtered={filtered}
curPath={curPath}
setCurPath={setNewCurPath}
profileType={profileType}
sortBy={storeSortBy as string}
flamegraphLoading={isLoading}
isHalfScreen={isHalfScreen}
mappingsListFromMetadata={mappingsList}
compareAbsolute={isCompareAbsolute}
/>
<div className="relative">
{showTimelineGuide && (
<TimelineGuide
bounds={[0, 60000]}
width={width}
height={1000}
margin={0}
ticks={60000 / 10000}
/>
)}
<IcicleGraphArrow
width={width}
arrow={arrow}
total={total}
filtered={filtered}
curPath={curPath}
setCurPath={setNewCurPath}
profileType={profileType}
sortBy={storeSortBy as string}
flamegraphLoading={isLoading}
isHalfScreen={isHalfScreen}
mappingsListFromMetadata={mappingsList}
compareAbsolute={isCompareAbsolute}
/>
</div>
);
}, [
isLoading,
Expand All @@ -196,6 +210,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
isDarkMode,
mappingsList,
isCompareAbsolute,
showTimelineGuide,
]);

if (error != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ interface GetDashboardItemProps {
perf?: {
onRender?: ProfilerOnRenderCallback;
};
showTimelineGuide?: boolean;
}

export const getDashboardItem = ({
Expand All @@ -66,6 +67,7 @@ export const getDashboardItem = ({
setSearchString,
callgraphSVG,
perf,
showTimelineGuide,
}: GetDashboardItemProps): JSX.Element => {
switch (type) {
case 'icicle':
Expand Down Expand Up @@ -98,6 +100,7 @@ export const getDashboardItem = ({
}
metadataMappingFiles={flamegraphData.metadataMappingFiles}
metadataLoading={flamegraphData.metadataLoading}
showTimelineGuide={showTimelineGuide}
/>
</ConditionalWrapper>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const VisualizationContainer: FC<VisualizationContainerProps> = ({
{...provided.draggableProps}
className={cx(
'w-full min-h-96',
snapshot.isDragging ? 'bg-gray-200 dark:bg-gray-500' : 'bg-white dark:bg-gray-900',
snapshot.isDragging ? 'bg-gray-200 dark:bg-gray-500' : 'bg-inherit dark:bg-gray-900',
isMultiPanelView ? 'border-2 border-gray-100 dark:border-gray-700 rounded-md p-3' : ''
)}
>
Expand Down
2 changes: 2 additions & 0 deletions ui/packages/shared/profile/src/ProfileView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const ProfileView = ({
pprofDownloading,
compare,
showVisualizationSelector,
showTimelineGuide,
}: ProfileViewProps): JSX.Element => {
const {
timezone,
Expand Down Expand Up @@ -109,6 +110,7 @@ export const ProfileView = ({
setSearchString,
callgraphSVG,
perf,
showTimelineGuide,
});
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,5 @@ export interface ProfileViewProps {
onDownloadPProf: () => void;
pprofDownloading?: boolean;
showVisualizationSelector?: boolean;
showTimelineGuide?: boolean;
}
3 changes: 3 additions & 0 deletions ui/packages/shared/profile/src/ProfileViewWithData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@ interface ProfileViewWithDataProps {
profileSource: ProfileSource;
compare?: boolean;
showVisualizationSelector?: boolean;
showTimelineGuide?: boolean;
}

export const ProfileViewWithData = ({
queryClient,
profileSource,
showVisualizationSelector,
showTimelineGuide,
}: ProfileViewWithDataProps): JSX.Element => {
const metadata = useGrpcMetadata();
const [dashboardItems] = useURLState<string[]>('dashboard_items', {
Expand Down Expand Up @@ -242,6 +244,7 @@ export const ProfileViewWithData = ({
onDownloadPProf={() => void downloadPProfClick()}
pprofDownloading={pprofDownloading}
showVisualizationSelector={showVisualizationSelector}
showTimelineGuide={showTimelineGuide}
/>
);
};
Expand Down

0 comments on commit d99401a

Please sign in to comment.