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:
parent
26f5e506b7
commit
bbce3e873e
|
@ -31,9 +31,9 @@ const getBetPoints = (bets: Bet[]) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const BinaryChartTooltip = (props: TooltipProps<Date, HistoryPoint<Bet>>) => {
|
const BinaryChartTooltip = (props: TooltipProps<Date, HistoryPoint<Bet>>) => {
|
||||||
const { data, mouseX, xScale } = props
|
const { data, x, xScale } = props
|
||||||
const [start, end] = xScale.domain()
|
const [start, end] = xScale.domain()
|
||||||
const d = xScale.invert(mouseX)
|
const d = xScale.invert(x)
|
||||||
return (
|
return (
|
||||||
<Row className="items-center gap-2">
|
<Row className="items-center gap-2">
|
||||||
{data.obj && <Avatar size="xs" avatarUrl={data.obj.userAvatarUrl} />}
|
{data.obj && <Avatar size="xs" avatarUrl={data.obj.userAvatarUrl} />}
|
||||||
|
|
|
@ -180,9 +180,9 @@ export const ChoiceContractChart = (props: {
|
||||||
|
|
||||||
const ChoiceTooltip = useMemo(
|
const ChoiceTooltip = useMemo(
|
||||||
() => (props: TooltipProps<Date, MultiPoint<Bet>>) => {
|
() => (props: TooltipProps<Date, MultiPoint<Bet>>) => {
|
||||||
const { data, mouseX, xScale } = props
|
const { data, x, xScale } = props
|
||||||
const [start, end] = xScale.domain()
|
const [start, end] = xScale.domain()
|
||||||
const d = xScale.invert(mouseX)
|
const d = xScale.invert(x)
|
||||||
const legendItems = sortBy(
|
const legendItems = sortBy(
|
||||||
data.y.map((p, i) => ({
|
data.y.map((p, i) => ({
|
||||||
color: CATEGORY_COLORS[i],
|
color: CATEGORY_COLORS[i],
|
||||||
|
|
|
@ -26,11 +26,11 @@ const getNumericChartData = (contract: NumericContract) => {
|
||||||
const NumericChartTooltip = (
|
const NumericChartTooltip = (
|
||||||
props: TooltipProps<number, DistributionPoint>
|
props: TooltipProps<number, DistributionPoint>
|
||||||
) => {
|
) => {
|
||||||
const { data, mouseX, xScale } = props
|
const { data, x, xScale } = props
|
||||||
const x = xScale.invert(mouseX)
|
const amount = xScale.invert(x)
|
||||||
return (
|
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>
|
<span className="text-greyscale-6">{formatPct(data.y, 2)}</span>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
|
|
@ -45,9 +45,9 @@ const getBetPoints = (bets: Bet[], scaleP: (p: number) => number) => {
|
||||||
const PseudoNumericChartTooltip = (
|
const PseudoNumericChartTooltip = (
|
||||||
props: TooltipProps<Date, HistoryPoint<Bet>>
|
props: TooltipProps<Date, HistoryPoint<Bet>>
|
||||||
) => {
|
) => {
|
||||||
const { data, mouseX, xScale } = props
|
const { data, x, xScale } = props
|
||||||
const [start, end] = xScale.domain()
|
const [start, end] = xScale.domain()
|
||||||
const d = xScale.invert(mouseX)
|
const d = xScale.invert(x)
|
||||||
return (
|
return (
|
||||||
<Row className="items-center gap-2">
|
<Row className="items-center gap-2">
|
||||||
{data.obj && <Avatar size="xs" avatarUrl={data.obj.userAvatarUrl} />}
|
{data.obj && <Avatar size="xs" avatarUrl={data.obj.userAvatarUrl} />}
|
||||||
|
|
|
@ -21,8 +21,8 @@ import {
|
||||||
AreaPath,
|
AreaPath,
|
||||||
AreaWithTopStroke,
|
AreaWithTopStroke,
|
||||||
Point,
|
Point,
|
||||||
MouseProps,
|
|
||||||
SliceMarker,
|
SliceMarker,
|
||||||
|
TooltipParams,
|
||||||
TooltipComponent,
|
TooltipComponent,
|
||||||
computeColorStops,
|
computeColorStops,
|
||||||
formatPct,
|
formatPct,
|
||||||
|
@ -89,7 +89,7 @@ export const DistributionChart = <P extends DistributionPoint>(props: {
|
||||||
}) => {
|
}) => {
|
||||||
const { data, w, h, color, margin, yScale, curve, Tooltip } = 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] =
|
const [viewXScale, setViewXScale] =
|
||||||
useState<ScaleContinuousNumeric<number, number>>()
|
useState<ScaleContinuousNumeric<number, number>>()
|
||||||
const xScale = viewXScale ?? props.xScale
|
const xScale = viewXScale ?? props.xScale
|
||||||
|
@ -109,13 +109,13 @@ export const DistributionChart = <P extends DistributionPoint>(props: {
|
||||||
const p = selector(mouseX)
|
const p = selector(mouseX)
|
||||||
props.onMouseOver?.(p.prev)
|
props.onMouseOver?.(p.prev)
|
||||||
if (p.prev) {
|
if (p.prev) {
|
||||||
setMouse({ x: mouseX, y: mouseY, data: p.prev })
|
setTTParams({ x: mouseX, y: mouseY, data: p.prev })
|
||||||
} else {
|
} else {
|
||||||
setMouse(undefined)
|
setTTParams(undefined)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const onMouseLeave = useEvent(() => setMouse(undefined))
|
const onMouseLeave = useEvent(() => setTTParams(undefined))
|
||||||
|
|
||||||
const onSelect = useEvent((ev: D3BrushEvent<P>) => {
|
const onSelect = useEvent((ev: D3BrushEvent<P>) => {
|
||||||
if (ev.selection) {
|
if (ev.selection) {
|
||||||
|
@ -135,7 +135,7 @@ export const DistributionChart = <P extends DistributionPoint>(props: {
|
||||||
margin={margin}
|
margin={margin}
|
||||||
xAxis={xAxis}
|
xAxis={xAxis}
|
||||||
yAxis={yAxis}
|
yAxis={yAxis}
|
||||||
mouse={mouse}
|
ttParams={ttParams}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
onMouseOver={onMouseOver}
|
onMouseOver={onMouseOver}
|
||||||
onMouseLeave={onMouseLeave}
|
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 { 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 [viewXScale, setViewXScale] = useState<ScaleTime<number, number>>()
|
||||||
const xScale = viewXScale ?? props.xScale
|
const xScale = viewXScale ?? props.xScale
|
||||||
|
|
||||||
|
@ -208,13 +208,13 @@ export const MultiValueHistoryChart = <P extends MultiPoint>(props: {
|
||||||
const p = selector(mouseX)
|
const p = selector(mouseX)
|
||||||
props.onMouseOver?.(p.prev)
|
props.onMouseOver?.(p.prev)
|
||||||
if (p.prev) {
|
if (p.prev) {
|
||||||
setMouse({ x: mouseX, y: mouseY, data: p.prev })
|
setTTParams({ x: mouseX, y: mouseY, data: p.prev })
|
||||||
} else {
|
} else {
|
||||||
setMouse(undefined)
|
setTTParams(undefined)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const onMouseLeave = useEvent(() => setMouse(undefined))
|
const onMouseLeave = useEvent(() => setTTParams(undefined))
|
||||||
|
|
||||||
const onSelect = useEvent((ev: D3BrushEvent<P>) => {
|
const onSelect = useEvent((ev: D3BrushEvent<P>) => {
|
||||||
if (ev.selection) {
|
if (ev.selection) {
|
||||||
|
@ -234,7 +234,7 @@ export const MultiValueHistoryChart = <P extends MultiPoint>(props: {
|
||||||
margin={margin}
|
margin={margin}
|
||||||
xAxis={xAxis}
|
xAxis={xAxis}
|
||||||
yAxis={yAxis}
|
yAxis={yAxis}
|
||||||
mouse={mouse}
|
ttParams={ttParams}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
onMouseOver={onMouseOver}
|
onMouseOver={onMouseOver}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
|
@ -272,7 +272,7 @@ export const SingleValueHistoryChart = <P extends HistoryPoint>(props: {
|
||||||
const { data, w, h, color, margin, yScale, yKind, Tooltip } = props
|
const { data, w, h, color, margin, yScale, yKind, Tooltip } = props
|
||||||
const curve = props.curve ?? curveLinear
|
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 [viewXScale, setViewXScale] = useState<ScaleTime<number, number>>()
|
||||||
const xScale = viewXScale ?? props.xScale
|
const xScale = viewXScale ?? props.xScale
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ export const SingleValueHistoryChart = <P extends HistoryPoint>(props: {
|
||||||
}, [w, h, yKind, xScale, yScale])
|
}, [w, h, yKind, xScale, yScale])
|
||||||
|
|
||||||
const selector = dataAtPointSelector(data, xScale)
|
const selector = dataAtPointSelector(data, xScale)
|
||||||
const onMouseOver = useEvent((mouseX: number, mouseY: number) => {
|
const onMouseOver = useEvent((mouseX: number) => {
|
||||||
const p = selector(mouseX)
|
const p = selector(mouseX)
|
||||||
props.onMouseOver?.(p.prev)
|
props.onMouseOver?.(p.prev)
|
||||||
const x0 = p.prev ? xScale(p.prev.x) : xScale.range()[0]
|
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) {
|
if (p.prev && markerY) {
|
||||||
setMouse({
|
setMouse({
|
||||||
x: mouseX,
|
x: mouseX,
|
||||||
y: mouseY,
|
y: markerY,
|
||||||
y0: py0,
|
y0: py0,
|
||||||
y1: markerY,
|
y1: markerY,
|
||||||
data: p.prev,
|
data: p.prev,
|
||||||
|
@ -347,7 +347,9 @@ export const SingleValueHistoryChart = <P extends HistoryPoint>(props: {
|
||||||
margin={margin}
|
margin={margin}
|
||||||
xAxis={xAxis}
|
xAxis={xAxis}
|
||||||
yAxis={yAxis}
|
yAxis={yAxis}
|
||||||
mouse={mouse}
|
ttParams={
|
||||||
|
mouse ? { x: mouse.x, y: mouse.y, data: mouse.data } : undefined
|
||||||
|
}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
onMouseOver={onMouseOver}
|
onMouseOver={onMouseOver}
|
||||||
onMouseLeave={onMouseLeave}
|
onMouseLeave={onMouseLeave}
|
||||||
|
|
|
@ -144,7 +144,7 @@ export const SVGChart = <X, TT>(props: {
|
||||||
margin: Margin
|
margin: Margin
|
||||||
xAxis: Axis<X>
|
xAxis: Axis<X>
|
||||||
yAxis: Axis<number>
|
yAxis: Axis<number>
|
||||||
mouse: MouseProps<TT> | undefined
|
ttParams: TooltipParams<TT> | undefined
|
||||||
onSelect?: (ev: D3BrushEvent<any>) => void
|
onSelect?: (ev: D3BrushEvent<any>) => void
|
||||||
onMouseOver?: (mouseX: number, mouseY: number) => void
|
onMouseOver?: (mouseX: number, mouseY: number) => void
|
||||||
onMouseLeave?: () => void
|
onMouseLeave?: () => void
|
||||||
|
@ -157,7 +157,7 @@ export const SVGChart = <X, TT>(props: {
|
||||||
margin,
|
margin,
|
||||||
xAxis,
|
xAxis,
|
||||||
yAxis,
|
yAxis,
|
||||||
mouse,
|
ttParams,
|
||||||
onSelect,
|
onSelect,
|
||||||
onMouseOver,
|
onMouseOver,
|
||||||
onMouseLeave,
|
onMouseLeave,
|
||||||
|
@ -213,13 +213,13 @@ export const SVGChart = <X, TT>(props: {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative overflow-hidden">
|
<div className="relative overflow-hidden">
|
||||||
{mouse && Tooltip && (
|
{ttParams && Tooltip && (
|
||||||
<TooltipContainer
|
<TooltipContainer
|
||||||
setElem={tooltipMeasure.setElem}
|
setElem={tooltipMeasure.setElem}
|
||||||
margin={margin}
|
margin={margin}
|
||||||
pos={getTooltipPosition(
|
pos={getTooltipPosition(
|
||||||
mouse.x,
|
ttParams.x,
|
||||||
mouse.y,
|
ttParams.y,
|
||||||
innerW,
|
innerW,
|
||||||
innerH,
|
innerH,
|
||||||
tooltipMeasure.width,
|
tooltipMeasure.width,
|
||||||
|
@ -228,9 +228,9 @@ export const SVGChart = <X, TT>(props: {
|
||||||
>
|
>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
xScale={xAxis.scale()}
|
xScale={xAxis.scale()}
|
||||||
mouseX={mouse.x}
|
x={ttParams.x}
|
||||||
mouseY={mouse.y}
|
y={ttParams.y}
|
||||||
data={mouse.data}
|
data={ttParams.data}
|
||||||
/>
|
/>
|
||||||
</TooltipContainer>
|
</TooltipContainer>
|
||||||
)}
|
)}
|
||||||
|
@ -287,11 +287,9 @@ export const getTooltipPosition = (
|
||||||
return { left, bottom }
|
return { left, bottom }
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TooltipProps<X, T> = {
|
export type TooltipParams<T> = { x: number; y: number; data: T }
|
||||||
mouseX: number
|
export type TooltipProps<X, T> = TooltipParams<T> & {
|
||||||
mouseY: number
|
|
||||||
xScale: ContinuousScale<X>
|
xScale: ContinuousScale<X>
|
||||||
data: T
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TooltipComponent<X, T> = React.ComponentType<TooltipProps<X, 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,>(
|
export const computeColorStops = <P,>(
|
||||||
data: P[],
|
data: P[],
|
||||||
pc: (p: P) => string,
|
pc: (p: P) => string,
|
||||||
|
|
|
@ -22,8 +22,8 @@ const getPoints = (startDate: number, dailyValues: number[]) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const DailyCountTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
|
const DailyCountTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
|
||||||
const { data, mouseX, xScale } = props
|
const { data, x, xScale } = props
|
||||||
const d = xScale.invert(mouseX)
|
const d = xScale.invert(x)
|
||||||
return (
|
return (
|
||||||
<Row className="items-center gap-2">
|
<Row className="items-center gap-2">
|
||||||
<span className="font-semibold">{dayjs(d).format('MMM DD')}</span>
|
<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 DailyPercentTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
|
||||||
const { data, mouseX, xScale } = props
|
const { data, x, xScale } = props
|
||||||
const d = xScale.invert(mouseX)
|
const d = xScale.invert(x)
|
||||||
return (
|
return (
|
||||||
<Row className="items-center gap-2">
|
<Row className="items-center gap-2">
|
||||||
<span className="font-semibold">{dayjs(d).format('MMM DD')}</span>
|
<span className="font-semibold">{dayjs(d).format('MMM DD')}</span>
|
||||||
|
|
|
@ -18,8 +18,8 @@ const MARGIN_Y = MARGIN.top + MARGIN.bottom
|
||||||
export type GraphMode = 'profit' | 'value'
|
export type GraphMode = 'profit' | 'value'
|
||||||
|
|
||||||
export const PortfolioTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
|
export const PortfolioTooltip = (props: TooltipProps<Date, HistoryPoint>) => {
|
||||||
const { mouseX, xScale } = props
|
const { x, xScale } = props
|
||||||
const d = dayjs(xScale.invert(mouseX))
|
const d = dayjs(xScale.invert(x))
|
||||||
return (
|
return (
|
||||||
<Col className="text-xs font-semibold sm:text-sm">
|
<Col className="text-xs font-semibold sm:text-sm">
|
||||||
<div>{d.format('MMM/D/YY')}</div>
|
<div>{d.format('MMM/D/YY')}</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user