Clean up chart tooltip handling (#959)
This commit is contained in:
parent
be010da9f5
commit
8862425120
|
@ -32,7 +32,8 @@ const getBetPoints = (bets: Bet[]) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const BinaryChartTooltip = (props: SingleValueHistoryTooltipProps<Bet>) => {
|
const BinaryChartTooltip = (props: SingleValueHistoryTooltipProps<Bet>) => {
|
||||||
const { x, y, xScale, datum } = props
|
const { p, xScale } = props
|
||||||
|
const { x, y, datum } = p
|
||||||
const [start, end] = xScale.domain()
|
const [start, end] = xScale.domain()
|
||||||
return (
|
return (
|
||||||
<Row className="items-center gap-2 text-sm">
|
<Row className="items-center gap-2 text-sm">
|
||||||
|
|
|
@ -162,7 +162,8 @@ export const ChoiceContractChart = (props: {
|
||||||
|
|
||||||
const ChoiceTooltip = useMemo(
|
const ChoiceTooltip = useMemo(
|
||||||
() => (props: MultiValueHistoryTooltipProps<Bet>) => {
|
() => (props: MultiValueHistoryTooltipProps<Bet>) => {
|
||||||
const { x, y, xScale, datum } = props
|
const { p, xScale } = props
|
||||||
|
const { x, y, datum } = p
|
||||||
const [start, end] = xScale.domain()
|
const [start, end] = xScale.domain()
|
||||||
const legendItems = sortBy(
|
const legendItems = sortBy(
|
||||||
y.map((p, i) => ({
|
y.map((p, i) => ({
|
||||||
|
|
|
@ -25,7 +25,8 @@ const getNumericChartData = (contract: NumericContract) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const NumericChartTooltip = (props: SingleValueDistributionTooltipProps) => {
|
const NumericChartTooltip = (props: SingleValueDistributionTooltipProps) => {
|
||||||
const { x, y } = props
|
const { p } = props
|
||||||
|
const { x, y } = p
|
||||||
return (
|
return (
|
||||||
<span className="text-sm">
|
<span className="text-sm">
|
||||||
<strong>{formatPct(y, 2)}</strong> {formatLargeNumber(x)}
|
<strong>{formatPct(y, 2)}</strong> {formatLargeNumber(x)}
|
||||||
|
|
|
@ -46,7 +46,8 @@ const getBetPoints = (bets: Bet[], scaleP: (p: number) => number) => {
|
||||||
const PseudoNumericChartTooltip = (
|
const PseudoNumericChartTooltip = (
|
||||||
props: SingleValueHistoryTooltipProps<Bet>
|
props: SingleValueHistoryTooltipProps<Bet>
|
||||||
) => {
|
) => {
|
||||||
const { x, y, xScale, datum } = props
|
const { p, xScale } = props
|
||||||
|
const { x, y, datum } = p
|
||||||
const [start, end] = xScale.domain()
|
const [start, end] = xScale.domain()
|
||||||
return (
|
return (
|
||||||
<Row className="items-center gap-2 text-sm">
|
<Row className="items-center gap-2 text-sm">
|
||||||
|
|
|
@ -3,7 +3,6 @@ import { bisector } from 'd3-array'
|
||||||
import { axisBottom, axisLeft } from 'd3-axis'
|
import { axisBottom, axisLeft } from 'd3-axis'
|
||||||
import { D3BrushEvent } from 'd3-brush'
|
import { D3BrushEvent } from 'd3-brush'
|
||||||
import { ScaleTime, ScaleContinuousNumeric } from 'd3-scale'
|
import { ScaleTime, ScaleContinuousNumeric } from 'd3-scale'
|
||||||
import { pointer } from 'd3-selection'
|
|
||||||
import {
|
import {
|
||||||
curveLinear,
|
curveLinear,
|
||||||
curveStepAfter,
|
curveStepAfter,
|
||||||
|
@ -18,17 +17,25 @@ import {
|
||||||
AreaPath,
|
AreaPath,
|
||||||
AreaWithTopStroke,
|
AreaWithTopStroke,
|
||||||
TooltipContent,
|
TooltipContent,
|
||||||
TooltipContainer,
|
|
||||||
TooltipPosition,
|
|
||||||
formatPct,
|
formatPct,
|
||||||
} from './helpers'
|
} from './helpers'
|
||||||
import { useEvent } from 'web/hooks/use-event'
|
import { useEvent } from 'web/hooks/use-event'
|
||||||
|
|
||||||
export type MultiPoint<T = never> = { x: Date; y: number[]; datum?: T }
|
export type MultiPoint<T = never> = {
|
||||||
export type HistoryPoint<T = never> = { x: Date; y: number; datum?: T }
|
x: Date
|
||||||
export type DistributionPoint<T = never> = { x: number; y: number; datum?: T }
|
y: number[]
|
||||||
|
datum?: T
|
||||||
type PositionValue<P> = TooltipPosition & { p: P }
|
}
|
||||||
|
export type HistoryPoint<T = never> = {
|
||||||
|
x: Date
|
||||||
|
y: number
|
||||||
|
datum?: T
|
||||||
|
}
|
||||||
|
export type DistributionPoint<T = never> = {
|
||||||
|
x: number
|
||||||
|
y: number
|
||||||
|
datum?: T
|
||||||
|
}
|
||||||
|
|
||||||
const getTickValues = (min: number, max: number, n: number) => {
|
const getTickValues = (min: number, max: number, n: number) => {
|
||||||
const step = (max - min) / (n - 1)
|
const step = (max - min) / (n - 1)
|
||||||
|
@ -48,8 +55,6 @@ export const SingleValueDistributionChart = <T,>(props: {
|
||||||
|
|
||||||
const [viewXScale, setViewXScale] =
|
const [viewXScale, setViewXScale] =
|
||||||
useState<ScaleContinuousNumeric<number, number>>()
|
useState<ScaleContinuousNumeric<number, number>>()
|
||||||
const [mouseState, setMouseState] =
|
|
||||||
useState<PositionValue<DistributionPoint<T>>>()
|
|
||||||
const xScale = viewXScale ?? props.xScale
|
const xScale = viewXScale ?? props.xScale
|
||||||
|
|
||||||
const px = useCallback((p: DistributionPoint<T>) => xScale(p.x), [xScale])
|
const px = useCallback((p: DistributionPoint<T>) => xScale(p.x), [xScale])
|
||||||
|
@ -69,16 +74,12 @@ export const SingleValueDistributionChart = <T,>(props: {
|
||||||
setViewXScale(() =>
|
setViewXScale(() =>
|
||||||
xScale.copy().domain([xScale.invert(mouseX0), xScale.invert(mouseX1)])
|
xScale.copy().domain([xScale.invert(mouseX0), xScale.invert(mouseX1)])
|
||||||
)
|
)
|
||||||
setMouseState(undefined)
|
|
||||||
} else {
|
} else {
|
||||||
setViewXScale(undefined)
|
setViewXScale(undefined)
|
||||||
setMouseState(undefined)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const onMouseOver = useEvent((ev: React.PointerEvent) => {
|
const onMouseOver = useEvent((mouseX: number) => {
|
||||||
if (ev.pointerType === 'mouse') {
|
|
||||||
const [mouseX, mouseY] = pointer(ev)
|
|
||||||
const queryX = xScale.invert(mouseX)
|
const queryX = xScale.invert(mouseX)
|
||||||
const item = data[xBisector.left(data, queryX) - 1]
|
const item = data[xBisector.left(data, queryX) - 1]
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
|
@ -86,22 +87,10 @@ export const SingleValueDistributionChart = <T,>(props: {
|
||||||
// so your queryX is out of bounds
|
// so your queryX is out of bounds
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const p = { x: queryX, y: item.y, datum: item.datum }
|
return { x: queryX, y: item.y, datum: item.datum }
|
||||||
setMouseState({ top: mouseY - 10, left: mouseX + 60, p })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const onMouseLeave = useEvent(() => {
|
|
||||||
setMouseState(undefined)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
|
||||||
{mouseState && Tooltip && (
|
|
||||||
<TooltipContainer className="text-sm" {...mouseState}>
|
|
||||||
<Tooltip xScale={xScale} {...mouseState.p} />
|
|
||||||
</TooltipContainer>
|
|
||||||
)}
|
|
||||||
<SVGChart
|
<SVGChart
|
||||||
w={w}
|
w={w}
|
||||||
h={h}
|
h={h}
|
||||||
|
@ -109,7 +98,7 @@ export const SingleValueDistributionChart = <T,>(props: {
|
||||||
yAxis={yAxis}
|
yAxis={yAxis}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
onMouseOver={onMouseOver}
|
onMouseOver={onMouseOver}
|
||||||
onMouseLeave={onMouseLeave}
|
Tooltip={Tooltip}
|
||||||
>
|
>
|
||||||
<AreaWithTopStroke
|
<AreaWithTopStroke
|
||||||
color={color}
|
color={color}
|
||||||
|
@ -120,16 +109,13 @@ export const SingleValueDistributionChart = <T,>(props: {
|
||||||
curve={curveLinear}
|
curve={curveLinear}
|
||||||
/>
|
/>
|
||||||
</SVGChart>
|
</SVGChart>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SingleValueDistributionTooltipProps<T = unknown> =
|
export type SingleValueDistributionTooltipProps<T = unknown> = {
|
||||||
DistributionPoint<T> & {
|
p: DistributionPoint<T>
|
||||||
xScale: React.ComponentProps<
|
xScale: React.ComponentProps<typeof SingleValueDistributionChart<T>>['xScale']
|
||||||
typeof SingleValueDistributionChart<T>
|
}
|
||||||
>['xScale']
|
|
||||||
}
|
|
||||||
|
|
||||||
export const MultiValueHistoryChart = <T,>(props: {
|
export const MultiValueHistoryChart = <T,>(props: {
|
||||||
data: MultiPoint<T>[]
|
data: MultiPoint<T>[]
|
||||||
|
@ -144,7 +130,6 @@ export const MultiValueHistoryChart = <T,>(props: {
|
||||||
const { colors, data, yScale, w, h, Tooltip, pct } = props
|
const { colors, data, yScale, w, h, Tooltip, pct } = props
|
||||||
|
|
||||||
const [viewXScale, setViewXScale] = useState<ScaleTime<number, number>>()
|
const [viewXScale, setViewXScale] = useState<ScaleTime<number, number>>()
|
||||||
const [mouseState, setMouseState] = useState<PositionValue<MultiPoint<T>>>()
|
|
||||||
const xScale = viewXScale ?? props.xScale
|
const xScale = viewXScale ?? props.xScale
|
||||||
|
|
||||||
type SP = SeriesPoint<MultiPoint<T>>
|
type SP = SeriesPoint<MultiPoint<T>>
|
||||||
|
@ -177,16 +162,12 @@ export const MultiValueHistoryChart = <T,>(props: {
|
||||||
setViewXScale(() =>
|
setViewXScale(() =>
|
||||||
xScale.copy().domain([xScale.invert(mouseX0), xScale.invert(mouseX1)])
|
xScale.copy().domain([xScale.invert(mouseX0), xScale.invert(mouseX1)])
|
||||||
)
|
)
|
||||||
setMouseState(undefined)
|
|
||||||
} else {
|
} else {
|
||||||
setViewXScale(undefined)
|
setViewXScale(undefined)
|
||||||
setMouseState(undefined)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const onMouseOver = useEvent((ev: React.PointerEvent) => {
|
const onMouseOver = useEvent((mouseX: number) => {
|
||||||
if (ev.pointerType === 'mouse') {
|
|
||||||
const [mouseX, mouseY] = pointer(ev)
|
|
||||||
const queryX = xScale.invert(mouseX)
|
const queryX = xScale.invert(mouseX)
|
||||||
const item = data[xBisector.left(data, queryX) - 1]
|
const item = data[xBisector.left(data, queryX) - 1]
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
|
@ -194,22 +175,10 @@ export const MultiValueHistoryChart = <T,>(props: {
|
||||||
// so your queryX is out of bounds
|
// so your queryX is out of bounds
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const p = { x: queryX, y: item.y, datum: item.datum }
|
return { x: queryX, y: item.y, datum: item.datum }
|
||||||
setMouseState({ top: mouseY - 10, left: mouseX + 60, p })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const onMouseLeave = useEvent(() => {
|
|
||||||
setMouseState(undefined)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
|
||||||
{mouseState && Tooltip && (
|
|
||||||
<TooltipContainer top={mouseState.top} left={mouseState.left}>
|
|
||||||
<Tooltip xScale={xScale} {...mouseState.p} />
|
|
||||||
</TooltipContainer>
|
|
||||||
)}
|
|
||||||
<SVGChart
|
<SVGChart
|
||||||
w={w}
|
w={w}
|
||||||
h={h}
|
h={h}
|
||||||
|
@ -217,7 +186,7 @@ export const MultiValueHistoryChart = <T,>(props: {
|
||||||
yAxis={yAxis}
|
yAxis={yAxis}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
onMouseOver={onMouseOver}
|
onMouseOver={onMouseOver}
|
||||||
onMouseLeave={onMouseLeave}
|
Tooltip={Tooltip}
|
||||||
>
|
>
|
||||||
{series.map((s, i) => (
|
{series.map((s, i) => (
|
||||||
<AreaPath
|
<AreaPath
|
||||||
|
@ -231,11 +200,11 @@ export const MultiValueHistoryChart = <T,>(props: {
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</SVGChart>
|
</SVGChart>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MultiValueHistoryTooltipProps<T = unknown> = MultiPoint<T> & {
|
export type MultiValueHistoryTooltipProps<T = unknown> = {
|
||||||
|
p: MultiPoint<T>
|
||||||
xScale: React.ComponentProps<typeof MultiValueHistoryChart<T>>['xScale']
|
xScale: React.ComponentProps<typeof MultiValueHistoryChart<T>>['xScale']
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,7 +221,6 @@ export const SingleValueHistoryChart = <T,>(props: {
|
||||||
const { color, data, pct, yScale, w, h, Tooltip } = props
|
const { color, data, pct, yScale, w, h, Tooltip } = props
|
||||||
|
|
||||||
const [viewXScale, setViewXScale] = useState<ScaleTime<number, number>>()
|
const [viewXScale, setViewXScale] = useState<ScaleTime<number, number>>()
|
||||||
const [mouseState, setMouseState] = useState<PositionValue<HistoryPoint<T>>>()
|
|
||||||
const xScale = viewXScale ?? props.xScale
|
const xScale = viewXScale ?? props.xScale
|
||||||
|
|
||||||
const px = useCallback((p: HistoryPoint<T>) => xScale(p.x), [xScale])
|
const px = useCallback((p: HistoryPoint<T>) => xScale(p.x), [xScale])
|
||||||
|
@ -276,16 +244,12 @@ export const SingleValueHistoryChart = <T,>(props: {
|
||||||
setViewXScale(() =>
|
setViewXScale(() =>
|
||||||
xScale.copy().domain([xScale.invert(mouseX0), xScale.invert(mouseX1)])
|
xScale.copy().domain([xScale.invert(mouseX0), xScale.invert(mouseX1)])
|
||||||
)
|
)
|
||||||
setMouseState(undefined)
|
|
||||||
} else {
|
} else {
|
||||||
setViewXScale(undefined)
|
setViewXScale(undefined)
|
||||||
setMouseState(undefined)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const onMouseOver = useEvent((ev: React.PointerEvent) => {
|
const onMouseOver = useEvent((mouseX: number) => {
|
||||||
if (ev.pointerType === 'mouse') {
|
|
||||||
const [mouseX, mouseY] = pointer(ev)
|
|
||||||
const queryX = xScale.invert(mouseX)
|
const queryX = xScale.invert(mouseX)
|
||||||
const item = data[xBisector.left(data, queryX) - 1]
|
const item = data[xBisector.left(data, queryX) - 1]
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
|
@ -293,22 +257,10 @@ export const SingleValueHistoryChart = <T,>(props: {
|
||||||
// so your queryX is out of bounds
|
// so your queryX is out of bounds
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const p = { x: queryX, y: item.y, datum: item.datum }
|
return { x: queryX, y: item.y, datum: item.datum }
|
||||||
setMouseState({ top: mouseY - 10, left: mouseX + 60, p })
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const onMouseLeave = useEvent(() => {
|
|
||||||
setMouseState(undefined)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative">
|
|
||||||
{mouseState && Tooltip && (
|
|
||||||
<TooltipContainer top={mouseState.top} left={mouseState.left}>
|
|
||||||
<Tooltip xScale={xScale} {...mouseState.p} />
|
|
||||||
</TooltipContainer>
|
|
||||||
)}
|
|
||||||
<SVGChart
|
<SVGChart
|
||||||
w={w}
|
w={w}
|
||||||
h={h}
|
h={h}
|
||||||
|
@ -316,7 +268,7 @@ export const SingleValueHistoryChart = <T,>(props: {
|
||||||
yAxis={yAxis}
|
yAxis={yAxis}
|
||||||
onSelect={onSelect}
|
onSelect={onSelect}
|
||||||
onMouseOver={onMouseOver}
|
onMouseOver={onMouseOver}
|
||||||
onMouseLeave={onMouseLeave}
|
Tooltip={Tooltip}
|
||||||
>
|
>
|
||||||
<AreaWithTopStroke
|
<AreaWithTopStroke
|
||||||
color={color}
|
color={color}
|
||||||
|
@ -327,10 +279,10 @@ export const SingleValueHistoryChart = <T,>(props: {
|
||||||
curve={curveStepAfter}
|
curve={curveStepAfter}
|
||||||
/>
|
/>
|
||||||
</SVGChart>
|
</SVGChart>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SingleValueHistoryTooltipProps<T = unknown> = HistoryPoint<T> & {
|
export type SingleValueHistoryTooltipProps<T = unknown> = {
|
||||||
|
p: HistoryPoint<T>
|
||||||
xScale: React.ComponentProps<typeof SingleValueHistoryChart<T>>['xScale']
|
xScale: React.ComponentProps<typeof SingleValueHistoryChart<T>>['xScale']
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import { ReactNode, SVGProps, memo, useRef, useEffect, useMemo } from 'react'
|
import {
|
||||||
import { select } from 'd3-selection'
|
ReactNode,
|
||||||
|
SVGProps,
|
||||||
|
memo,
|
||||||
|
useRef,
|
||||||
|
useEffect,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from 'react'
|
||||||
|
import { pointer, select } from 'd3-selection'
|
||||||
import { Axis } from 'd3-axis'
|
import { Axis } from 'd3-axis'
|
||||||
import { brushX, D3BrushEvent } from 'd3-brush'
|
import { brushX, D3BrushEvent } from 'd3-brush'
|
||||||
import { area, line, curveStepAfter, CurveFactory } from 'd3-shape'
|
import { area, line, curveStepAfter, CurveFactory } from 'd3-shape'
|
||||||
|
@ -108,19 +116,18 @@ export const AreaWithTopStroke = <P,>(props: {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SVGChart = <X, Y>(props: {
|
export const SVGChart = <X, Y, P, XS>(props: {
|
||||||
children: ReactNode
|
children: ReactNode
|
||||||
w: number
|
w: number
|
||||||
h: number
|
h: number
|
||||||
xAxis: Axis<X>
|
xAxis: Axis<X>
|
||||||
yAxis: Axis<Y>
|
yAxis: Axis<Y>
|
||||||
onSelect?: (ev: D3BrushEvent<any>) => void
|
onSelect?: (ev: D3BrushEvent<any>) => void
|
||||||
onMouseOver?: (ev: React.PointerEvent) => void
|
onMouseOver?: (mouseX: number, mouseY: number) => P | undefined
|
||||||
onMouseLeave?: (ev: React.PointerEvent) => void
|
Tooltip?: TooltipContent<{ xScale: XS } & { p: P }>
|
||||||
pct?: boolean
|
|
||||||
}) => {
|
}) => {
|
||||||
const { children, w, h, xAxis, yAxis, onMouseOver, onMouseLeave, onSelect } =
|
const { children, w, h, xAxis, yAxis, onMouseOver, onSelect, Tooltip } = props
|
||||||
props
|
const [mouseState, setMouseState] = useState<TooltipPosition & { p: P }>()
|
||||||
const overlayRef = useRef<SVGGElement>(null)
|
const overlayRef = useRef<SVGGElement>(null)
|
||||||
const innerW = w - MARGIN_X
|
const innerW = w - MARGIN_X
|
||||||
const innerH = h - MARGIN_Y
|
const innerH = h - MARGIN_Y
|
||||||
|
@ -139,6 +146,7 @@ export const SVGChart = <X, Y>(props: {
|
||||||
if (!justSelected.current) {
|
if (!justSelected.current) {
|
||||||
justSelected.current = true
|
justSelected.current = true
|
||||||
onSelect(ev)
|
onSelect(ev)
|
||||||
|
setMouseState(undefined)
|
||||||
if (overlayRef.current) {
|
if (overlayRef.current) {
|
||||||
select(overlayRef.current).call(brush.clear)
|
select(overlayRef.current).call(brush.clear)
|
||||||
}
|
}
|
||||||
|
@ -156,7 +164,29 @@ export const SVGChart = <X, Y>(props: {
|
||||||
}
|
}
|
||||||
}, [innerW, innerH, onSelect])
|
}, [innerW, innerH, onSelect])
|
||||||
|
|
||||||
|
const onPointerMove = (ev: React.PointerEvent) => {
|
||||||
|
if (ev.pointerType === 'mouse' && onMouseOver) {
|
||||||
|
const [mouseX, mouseY] = pointer(ev)
|
||||||
|
const p = onMouseOver(mouseX, mouseY)
|
||||||
|
if (p != null) {
|
||||||
|
setMouseState({ top: mouseY - 10, left: mouseX + 60, p })
|
||||||
|
} else {
|
||||||
|
setMouseState(undefined)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onPointerLeave = () => {
|
||||||
|
setMouseState(undefined)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div className="relative">
|
||||||
|
{mouseState && Tooltip && (
|
||||||
|
<TooltipContainer top={mouseState.top} left={mouseState.left}>
|
||||||
|
<Tooltip xScale={xAxis.scale() as XS} p={mouseState.p} />
|
||||||
|
</TooltipContainer>
|
||||||
|
)}
|
||||||
<svg className="w-full" width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
|
<svg className="w-full" width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
|
||||||
<clipPath id={clipPathId}>
|
<clipPath id={clipPathId}>
|
||||||
<rect x={0} y={0} width={innerW} height={innerH} />
|
<rect x={0} y={0} width={innerW} height={innerH} />
|
||||||
|
@ -173,12 +203,13 @@ export const SVGChart = <X, Y>(props: {
|
||||||
height={innerH}
|
height={innerH}
|
||||||
fill="none"
|
fill="none"
|
||||||
pointerEvents="all"
|
pointerEvents="all"
|
||||||
onPointerEnter={onMouseOver}
|
onPointerEnter={onPointerMove}
|
||||||
onPointerMove={onMouseOver}
|
onPointerMove={onPointerMove}
|
||||||
onPointerLeave={onMouseLeave}
|
onPointerLeave={onPointerLeave}
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user