Skip to content
This repository has been archived by the owner on Feb 18, 2023. It is now read-only.

Add time info in tooltips #99

Merged
merged 1 commit into from
Jul 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/pf4/src/components/Container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const newBrushVoronoiContainer = (onClick?: (event: MouseEvent) => void,
}
return formatValue(obj.datum.name, obj.datum, obj.datum.y);
},
labelComponent: <CustomTooltip onClick={onClick} />,
labelComponent: <CustomTooltip showTime={true} onClick={onClick} />,
// We blacklist "parent" as a workaround to avoid the VictoryVoronoiContainer crashing.
// See https://github.com/FormidableLabs/victory/issues/1355
voronoiBlacklist: ['parent']
Expand Down
40 changes: 32 additions & 8 deletions web/pf4/src/components/CustomTooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import * as React from 'react';
import { ChartTooltip, ChartTooltipProps } from '@patternfly/react-charts';
import { Flyout, Point, VictoryLabel } from 'victory';
import { VCDataPoint } from '..';

const dy = 15;
const headSize = 2 * dy;
const yMargin = 8;

// eslint-disable-next-line @typescript-eslint/no-explicit-any
const canvasContext: any = document.createElement('canvas').getContext('2d');
// TODO: safe way to get this programmatically?
canvasContext.font = '14px overpass';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const CustomLabel = (props: any & { textWidth: number }) => {
const nbTexts = Array.isArray(props.text) ? props.text.length : 1;
export const CustomLabel = (props: any & { head?: string, text: string[], textWidth: number }) => {
const x = props.x - 11 - props.textWidth / 2;
const startY = 8 + props.y - (nbTexts * dy) / 2;
const textsWithHead = props.head ? [props.head, ' '].concat(props.text) : props.text;
const headSize = props.head ? 2 * dy : 0;
const startY = yMargin + props.y - (textsWithHead.length * dy) / 2 + headSize;
return (
<>
{props.activePoints && props.activePoints.filter(pt => pt.color)
Expand All @@ -30,20 +35,39 @@ export const CustomLabel = (props: any & { textWidth: number }) => {
);
})
}
<VictoryLabel {...props} />
<VictoryLabel {...props} text={textsWithHead} />
</>
);
};

export const CustomTooltip = (props: ChartTooltipProps & { onClick?: (event: MouseEvent) => void }) => {
const texts: Array<string> = Array.isArray(props.text) ? props.text : [props.text];
const getHeader = (activePoints?: VCDataPoint[]): string | undefined => {
if (activePoints && activePoints.length > 0) {
const x = activePoints[0].x;
if (typeof x === 'object') {
// Assume date
return x.toLocaleTimeString();
}
}
return undefined;
}

export const CustomTooltip = (props: ChartTooltipProps & { showTime?: boolean, activePoints?: VCDataPoint[], onClick?: (event: MouseEvent) => void }) => {
const head = props.showTime ? getHeader(props.activePoints) : undefined;
let height = props.text.length * dy + 2 * yMargin;
if (head) {
height += headSize;
}
const texts = Array.isArray(props.text) ? props.text : [props.text]
const textWidth = Math.max(...texts.map(t => canvasContext.measureText(t).width));
const width = 50 + (head ? Math.max(textWidth, canvasContext.measureText(head).width) : textWidth);
return (
<ChartTooltip
{...props}
flyoutWidth={textWidth + 50}
text={texts}
flyoutWidth={width}
flyoutHeight={height}
flyoutComponent={<Flyout style={{ stroke: 'none', fillOpacity: 0.6 }} />}
labelComponent={<CustomLabel textWidth={textWidth}/>} constrainToVisibleArea={true}
labelComponent={<CustomLabel head={head} textWidth={textWidth}/>} constrainToVisibleArea={true}
events={props.onClick ? { onClick: props.onClick } : undefined}
/>
);
Expand Down