Изменено поведение подсказки у графика при его зуме или скроле на странице операций.

This commit is contained in:
Майоров Александр 2022-12-22 12:34:09 +05:00
parent f896a22f1d
commit 73ae239148
Signed by untrusted user: av.maiorov
GPG Key ID: 7436B52B8035EBE6
2 changed files with 37 additions and 6 deletions

View File

@ -115,7 +115,7 @@ const _D3Chart = <DataType extends Record<string, unknown>>({
height: givenHeight = '100%', height: givenHeight = '100%',
loading, loading,
offset: _offset, offset: _offset,
animDurationMs = 200, animDurationMs = 20,
backgroundColor = 'transparent', backgroundColor = 'transparent',
ticks, ticks,
plugins, plugins,
@ -417,7 +417,7 @@ const _D3Chart = <DataType extends Record<string, unknown>>({
<D3MouseZone width={width} height={height} offset={offset}> <D3MouseZone width={width} height={height} offset={offset}>
<D3Cursor {...plugins?.cursor} /> <D3Cursor {...plugins?.cursor} />
<D3Legend<DataType> charts={charts} {...plugins?.legend} /> <D3Legend<DataType> charts={charts} {...plugins?.legend} />
<D3Tooltip<DataType> charts={charts} {...plugins?.tooltip} /> <D3Tooltip<DataType> charts={charts} {...plugins?.tooltip} zoomState={currentZoomState}/>
</D3MouseZone> </D3MouseZone>
</svg> </svg>
</D3ContextMenu> </D3ContextMenu>

View File

@ -76,6 +76,7 @@ export const makeDefaultRender = <DataType extends BaseDataType>(): D3RenderFunc
export type D3TooltipProps<DataType extends BaseDataType> = Partial<D3TooltipSettings<DataType>> & { export type D3TooltipProps<DataType extends BaseDataType> = Partial<D3TooltipSettings<DataType>> & {
charts: ChartRegistry<DataType>[], charts: ChartRegistry<DataType>[],
zoomState?: d3.ZoomTransform | null,
} }
function _D3Tooltip<DataType extends BaseDataType>({ function _D3Tooltip<DataType extends BaseDataType>({
@ -86,7 +87,8 @@ function _D3Tooltip<DataType extends BaseDataType>({
position: _position = 'bottom', position: _position = 'bottom',
className = '', className = '',
style: _style = {}, style: _style = {},
limit = 2 limit = 2,
zoomState,
}: D3TooltipProps<DataType>) { }: D3TooltipProps<DataType>) {
const { mouseState, zoneRect, subscribe } = useD3MouseZone() const { mouseState, zoneRect, subscribe } = useD3MouseZone()
const [tooltipBody, setTooltipBody] = useState<any>() const [tooltipBody, setTooltipBody] = useState<any>()
@ -94,6 +96,7 @@ function _D3Tooltip<DataType extends BaseDataType>({
const [position, setPosition] = useState<D3TooltipPosition>(_position ?? 'bottom') const [position, setPosition] = useState<D3TooltipPosition>(_position ?? 'bottom')
const [visible, setVisible] = useState(false) const [visible, setVisible] = useState(false)
const [fixed, setFixed] = useState(false) const [fixed, setFixed] = useState(false)
const [currentZoom, setCurrentZoom] = useState<d3.ZoomTransform | null>(null);
const tooltipRef = useRef<HTMLDivElement>(null) const tooltipRef = useRef<HTMLDivElement>(null)
@ -113,7 +116,7 @@ function _D3Tooltip<DataType extends BaseDataType>({
}, [subscribe, visible]) }, [subscribe, visible])
useEffect(() => { useEffect(() => {
if (!tooltipRef.current || !zoneRect || fixed) return if (!tooltipRef.current || !zoneRect || fixed || !visible) return
const rect = tooltipRef.current.getBoundingClientRect() const rect = tooltipRef.current.getBoundingClientRect()
if (!mouseState.visible) return if (!mouseState.visible) return
@ -121,8 +124,9 @@ function _D3Tooltip<DataType extends BaseDataType>({
const offsetX = -rect.width / 2 // По центру const offsetX = -rect.width / 2 // По центру
const offsetY = 15 // Чуть выше курсора const offsetY = 15 // Чуть выше курсора
const left = Math.max(10, Math.min(zoneRect.width - rect.width - 10, mouseState.x + offsetX)) const left = mouseState.x + offsetX
let top = mouseState.y - offsetY - rect.height let top = mouseState.y - offsetY - rect.height
setPosition(top <= 0 ? 'top' : 'bottom') setPosition(top <= 0 ? 'top' : 'bottom')
if (top <= 0) top = mouseState.y + offsetY if (top <= 0) top = mouseState.y + offsetY
@ -131,7 +135,34 @@ function _D3Tooltip<DataType extends BaseDataType>({
left, left,
top, top,
})) }))
}, [tooltipRef.current, mouseState, zoneRect, fixed]) }, [tooltipRef.current, mouseState, zoneRect, fixed, visible])
useEffect(() => {
if (!zoomState) return
setCurrentZoom(zoomState)
if (!fixed) {
setVisible(false)
return
}
const offsetX = Number(style.left) + Number(width) + 7
if (zoneRect && ((offsetX <= zoneRect.left) || (offsetX > zoneRect.right)) || zoomState.k !== currentZoom?.k) {
setVisible(false)
setFixed(false)
return
}
const distanceMoveX = currentZoom ? currentZoom.x - zoomState.x : 1
setStyle((prevStyle) => ({
...prevStyle,
left: prevStyle?.left ? +prevStyle.left - distanceMoveX : 0,
}))
}, [zoomState, fixed])
useEffect(() => { useEffect(() => {
if (fixed) return if (fixed) return