Tooltip follows marker on charts with marker (#997)

* Renaming of some tooltip stuff

* Tooltip follows marker on single value history charts
This commit is contained in:
Marshall Polaris 2022-10-04 14:02:44 -07:00 committed by GitHub
parent 26f5e506b7
commit bbce3e873e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 42 additions and 44 deletions

View File

@ -31,9 +31,9 @@ const getBetPoints = (bets: Bet[]) => {
}
const BinaryChartTooltip = (props: TooltipProps<Date, HistoryPoint<Bet>>) => {
const { data, mouseX, xScale } = props
const { data, x, xScale } = props
const [start, end] = xScale.domain()
const d = xScale.invert(mouseX)
const d = xScale.invert(x)
return (
<Row className="items-center gap-2">
{data.obj && <Avatar size="xs" avatarUrl={data.obj.userAvatarUrl} />}

View File

@ -180,9 +180,9 @@ export const ChoiceContractChart = (props: {
const ChoiceTooltip = useMemo(
() => (props: TooltipProps<Date, MultiPoint<Bet>>) => {
const { data, mouseX, xScale } = props
const { data, x, xScale } = props
const [start, end] = xScale.domain()
const d = xScale.invert(mouseX)
const d = xScale.invert(x)
const legendItems = sortBy(
data.y.map((p, i) => ({
color: CATEGORY_COLORS[i],

View File

@ -26,11 +26,11 @@ const getNumericChartData = (contract: NumericContract) => {
const NumericChartTooltip = (
props: TooltipProps<number, DistributionPoint>
) => {
const { data, mouseX, xScale } = props
const x = xScale.invert(mouseX)
const { data, x, xScale } = props
const amount = xScale.invert(x)
return (
<>
<span className="text-semibold">{formatLargeNumber(x)}</span>
<span className="text-semibold">{formatLargeNumber(amount)}</span>
<span className="text-greyscale-6">{formatPct(data.y, 2)}</span>
</>
)

View File

@ -45,9 +45,9 @@ const getBetPoints = (bets: Bet[], scaleP: (p: number) => number) => {
const PseudoNumericChartTooltip = (
props: TooltipProps<Date, HistoryPoint<Bet>>
) => {
const { data, mouseX, xScale } = props
const { data, x, xScale } = props
const [start, end] = xScale.domain()
const d = xScale.invert(mouseX)
const d = xScale.invert(x)
return (
<Row className="items-center gap-2">
{data.obj && <Avatar size="xs" avatarUrl={data.obj.userAvatarUrl} />}

View File

@ -21,8 +21,8 @@ import {
AreaPath,
AreaWithTopStroke,
Point,
MouseProps,
SliceMarker,
TooltipParams,
TooltipComponent,
computeColorStops,
formatPct,
@ -89,7 +89,7 @@ export const DistributionChart = <P extends DistributionPoint>(props: {
}) => {
const { data, w, h, color, margin, yScale, curve, Tooltip } = props
const [mouse, setMouse] = useState<MouseProps<P>>()
const [ttParams, setTTParams] = useState<TooltipParams<P>>()
const [viewXScale, setViewXScale] =
useState<ScaleContinuousNumeric<number, number>>()
const xScale = viewXScale ?? props.xScale
@ -109,13 +109,13 @@ export const DistributionChart = <P extends DistributionPoint>(props: {
const p = selector(mouseX)
props.onMouseOver?.(p.prev)
if (p.prev) {
setMouse({ x: mouseX, y: mouseY, data: p.prev })
setTTParams({ x: mouseX, y: mouseY, data: p.prev })
} else {
setMouse(undefined)
setTTParams(undefined)
}
})
const onMouseLeave = useEvent(() => setMouse(undefined))
const onMouseLeave = useEvent(() => setTTParams(undefined))
const onSelect = useEvent((ev: D3BrushEvent<P>) => {
if (ev.selection) {
@ -135,7 +135,7 @@ export const DistributionChart = <P extends DistributionPoint>(props: {
margin={margin}
xAxis={xAxis}
yAxis={yAxis}
mouse={mouse}
ttParams={ttParams}
onSelect={onSelect}
onMouseOver={onMouseOver}
onMouseLeave={onMouseLeave}
@ -168,7 +168,7 @@ export const MultiValueHistoryChart = <P extends MultiPoint>(props: {
}) => {
const { data, w, h, colors, margin, yScale, yKind, curve, Tooltip } = props
const [mouse, setMouse] = useState<MouseProps<P>>()
const [ttParams, setTTParams] = useState<TooltipParams<P>>()
const [viewXScale, setViewXScale] = useState<ScaleTime<number, number>>()
const xScale = viewXScale ?? props.xScale
@ -208,13 +208,13 @@ export const MultiValueHistoryChart = <P extends MultiPoint>(props: {
const p = selector(mouseX)
props.onMouseOver?.(p.prev)
if (p.prev) {
setMouse({ x: mouseX, y: mouseY, data: p.prev })
setTTParams({ x: mouseX, y: mouseY, data: p.prev })
} else {
setMouse(undefined)
setTTParams(undefined)
}
})
const onMouseLeave = useEvent(() => setMouse(undefined))
const onMouseLeave = useEvent(() => setTTParams(undefined))
const onSelect = useEvent((ev: D3BrushEvent<P>) => {
if (ev.selection) {
@ -234,7 +234,7 @@ export const MultiValueHistoryChart = <P extends MultiPoint>(props: {
margin={margin}
xAxis={xAxis}
yAxis={yAxis}
mouse={mouse}
ttParams={ttParams}
onSelect={onSelect}
onMouseOver={onMouseOver}
onMouseLeave={onMouseLeave}
@ -272,7 +272,7 @@ export const SingleValueHistoryChart = <P extends HistoryPoint>(props: {
const { data, w, h, color, margin, yScale, yKind, Tooltip } = props
const curve = props.curve ?? curveLinear
const [mouse, setMouse] = useState<MouseProps<P> & SliceExtent>()
const [mouse, setMouse] = useState<TooltipParams<P> & SliceExtent>()
const [viewXScale, setViewXScale] = useState<ScaleTime<number, number>>()
const xScale = viewXScale ?? props.xScale
@ -299,7 +299,7 @@ export const SingleValueHistoryChart = <P extends HistoryPoint>(props: {
}, [w, h, yKind, xScale, yScale])
const selector = dataAtPointSelector(data, xScale)
const onMouseOver = useEvent((mouseX: number, mouseY: number) => {
const onMouseOver = useEvent((mouseX: number) => {
const p = selector(mouseX)
props.onMouseOver?.(p.prev)
const x0 = p.prev ? xScale(p.prev.x) : xScale.range()[0]
@ -310,7 +310,7 @@ export const SingleValueHistoryChart = <P extends HistoryPoint>(props: {
if (p.prev && markerY) {
setMouse({
x: mouseX,
y: mouseY,
y: markerY,
y0: py0,
y1: markerY,
data: p.prev,
@ -347,7 +347,9 @@ export const SingleValueHistoryChart = <P extends HistoryPoint>(props: {
margin={margin}
xAxis={xAxis}
yAxis={yAxis}
mouse={mouse}
ttParams={
mouse ? { x: mouse.x, y: mouse.y, data: mouse.data } : undefined
}
onSelect={onSelect}
onMouseOver={onMouseOver}
onMouseLeave={onMouseLeave}

View File

@ -144,7 +144,7 @@ export const SVGChart = <X, TT>(props: {
margin: Margin
xAxis: Axis<X>
yAxis: Axis<number>
mouse: MouseProps<TT> | undefined
ttParams: TooltipParams<TT> | undefined
onSelect?: (ev: D3BrushEvent<any>) => void
onMouseOver?: (mouseX: number, mouseY: number) => void
onMouseLeave?: () => void
@ -157,7 +157,7 @@ export const SVGChart = <X, TT>(props: {
margin,
xAxis,
yAxis,
mouse,
ttParams,
onSelect,
onMouseOver,
onMouseLeave,
@ -213,13 +213,13 @@ export const SVGChart = <X, TT>(props: {
return (
<div className="relative overflow-hidden">
{mouse && Tooltip && (
{ttParams && Tooltip && (
<TooltipContainer
setElem={tooltipMeasure.setElem}
margin={margin}
pos={getTooltipPosition(
mouse.x,
mouse.y,
ttParams.x,
ttParams.y,
innerW,
innerH,
tooltipMeasure.width,
@ -228,9 +228,9 @@ export const SVGChart = <X, TT>(props: {
>
<Tooltip
xScale={xAxis.scale()}
mouseX={mouse.x}
mouseY={mouse.y}
data={mouse.data}
x={ttParams.x}
y={ttParams.y}
data={ttParams.data}
/>
</TooltipContainer>
)}
@ -287,11 +287,9 @@ export const getTooltipPosition = (
return { left, bottom }
}
export type TooltipProps<X, T> = {
mouseX: number
mouseY: number
export type TooltipParams<T> = { x: number; y: number; data: T }
export type TooltipProps<X, T> = TooltipParams<T> & {
xScale: ContinuousScale<X>
data: T
}
export type TooltipComponent<X, T> = React.ComponentType<TooltipProps<X, T>>
@ -320,8 +318,6 @@ export const TooltipContainer = (props: {
)
}
export type MouseProps<T> = { x: number; y: number; data: T }
export const computeColorStops = <P,>(
data: P[],
pc: (p: P) => string,

View File

@ -22,8 +22,8 @@ const getPoints = (startDate: number, dailyValues: number[]) => {
}
const DailyCountTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
const { data, mouseX, xScale } = props
const d = xScale.invert(mouseX)
const { data, x, xScale } = props
const d = xScale.invert(x)
return (
<Row className="items-center gap-2">
<span className="font-semibold">{dayjs(d).format('MMM DD')}</span>
@ -33,8 +33,8 @@ const DailyCountTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
}
const DailyPercentTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
const { data, mouseX, xScale } = props
const d = xScale.invert(mouseX)
const { data, x, xScale } = props
const d = xScale.invert(x)
return (
<Row className="items-center gap-2">
<span className="font-semibold">{dayjs(d).format('MMM DD')}</span>

View File

@ -18,8 +18,8 @@ const MARGIN_Y = MARGIN.top + MARGIN.bottom
export type GraphMode = 'profit' | 'value'
export const PortfolioTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
const { mouseX, xScale } = props
const d = dayjs(xScale.invert(mouseX))
const { x, xScale } = props
const d = dayjs(xScale.invert(x))
return (
<Col className="text-xs font-semibold sm:text-sm">
<div>{d.format('MMM/D/YY')}</div>