Improve tooltip behavior of charts
This commit is contained in:
@@ -1,16 +1,13 @@
|
|||||||
import DateFormatter from '../helper/DateFormatter'
|
import DateFormatter from '../helper/DateFormatter'
|
||||||
import NumberFormatter from '../helper/NumberFormatter'
|
import NumberFormatter from '../helper/NumberFormatter'
|
||||||
import Portal from '@material-ui/core/Portal'
|
import React, { useCallback, useState } from 'react'
|
||||||
import React, { useRef, useCallback, useState } from 'react'
|
|
||||||
import { default as ReactResizeDetector } from 'react-resize-detector'
|
import { default as ReactResizeDetector } from 'react-resize-detector'
|
||||||
|
import { emphasize, fade } from '@material-ui/core/styles'
|
||||||
|
import { Paper, Popper, Theme, Typography, withTheme } from '@material-ui/core'
|
||||||
import { PlotCurveTypes } from '../../reducers/Charts'
|
import { PlotCurveTypes } from '../../reducers/Charts'
|
||||||
import { Theme, Typography, withTheme, Popper, Paper } from '@material-ui/core'
|
|
||||||
import { useCustomXDomain } from './useCustomXDomain'
|
import { useCustomXDomain } from './useCustomXDomain'
|
||||||
import 'react-vis/dist/style.css'
|
import 'react-vis/dist/style.css'
|
||||||
import { number } from 'prop-types'
|
const { XYPlot, LineMarkSeries, Hint, YAxis, HorizontalGridLines } = require('react-vis')
|
||||||
import { fade } from '@material-ui/core/styles'
|
|
||||||
import { toggleAdvancedSettings } from '../../actions/ConnectionManager'
|
|
||||||
const { XYPlot, LineMarkSeries, Hint, XAxis, YAxis, HorizontalGridLines, Highlight, MouseEvent } = require('react-vis')
|
|
||||||
const abbreviate = require('number-abbreviate')
|
const abbreviate = require('number-abbreviate')
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@@ -48,10 +45,15 @@ function useToggle(initialState: boolean): [boolean, () => void, (value: boolean
|
|||||||
return [value, toggle, setValue]
|
return [value, toggle, setValue]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Point {
|
||||||
|
x: any
|
||||||
|
y: any
|
||||||
|
}
|
||||||
|
|
||||||
export default withTheme((props: Props) => {
|
export default withTheme((props: Props) => {
|
||||||
const [hintStaysOpen, toggleHintStaysOpen, setStaysOpen] = useToggle(false)
|
const [hintStaysOpen, toggleHintStaysOpen, setStaysOpen] = useToggle(false)
|
||||||
const [width, setWidth] = React.useState(300)
|
const [width, setWidth] = React.useState(300)
|
||||||
const [tooltip, setTooltip] = React.useState<{ value: any; element: any } | undefined>()
|
const [tooltip, setTooltip] = React.useState<{ value: any; point: Point; element: any } | undefined>()
|
||||||
const detectResize = React.useCallback(newWidth => setWidth(newWidth), [])
|
const detectResize = React.useCallback(newWidth => setWidth(newWidth), [])
|
||||||
|
|
||||||
const hintFormatter = React.useCallback((point: any) => {
|
const hintFormatter = React.useCallback((point: any) => {
|
||||||
@@ -62,34 +64,32 @@ export default withTheme((props: Props) => {
|
|||||||
]
|
]
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const hideTooltip = React.useCallback(() => {
|
|
||||||
if (!hintStaysOpen) {
|
|
||||||
setTooltip(undefined)
|
|
||||||
}
|
|
||||||
}, [hintStaysOpen])
|
|
||||||
|
|
||||||
const onMouseLeave = React.useCallback(() => {
|
const onMouseLeave = React.useCallback(() => {
|
||||||
setStaysOpen(false)
|
setStaysOpen(false)
|
||||||
setTooltip(undefined)
|
setTooltip(undefined)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const showTooltip = React.useCallback((value: any, something: { event: MouseEvent }) => {
|
const showTooltip = React.useCallback((point: Point, something: { event: MouseEvent }) => {
|
||||||
if (!something) {
|
if (!something) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setTooltip({ value: hintFormatter(value), element: something.event.target })
|
setTooltip({ point, value: hintFormatter(point), element: something.event.target })
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const onValueClick = React.useCallback(
|
const paletteColor =
|
||||||
(value: any, something: { event: MouseEvent }) => {
|
props.theme.palette.type === 'light' ? props.theme.palette.secondary.dark : props.theme.palette.primary.light
|
||||||
toggleHintStaysOpen()
|
const color = props.color ? props.color : paletteColor
|
||||||
console.log('onValueClick')
|
|
||||||
|
|
||||||
showTooltip(value, something)
|
const highlightSelectedPoint = useCallback(
|
||||||
|
(point: Point) => {
|
||||||
|
const highlight = tooltip && tooltip.point.x === point.x && tooltip.point.y === point.y
|
||||||
|
return highlight ? emphasize(color, 0.8) : color
|
||||||
},
|
},
|
||||||
[toggleHintStaysOpen]
|
[tooltip, color]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const getAnchorElement = useCallback(() => tooltip && tooltip.element, [tooltip])
|
||||||
|
|
||||||
const xDomain = useCustomXDomain(props)
|
const xDomain = useCustomXDomain(props)
|
||||||
|
|
||||||
return React.useMemo(() => {
|
return React.useMemo(() => {
|
||||||
@@ -99,12 +99,6 @@ export default withTheme((props: Props) => {
|
|||||||
? [props.range[0] || calculatedDomain[0], props.range[1] || calculatedDomain[1]]
|
? [props.range[0] || calculatedDomain[0], props.range[1] || calculatedDomain[1]]
|
||||||
: calculatedDomain
|
: calculatedDomain
|
||||||
|
|
||||||
let color: string =
|
|
||||||
props.theme.palette.type === 'light' ? props.theme.palette.secondary.dark : props.theme.palette.primary.light
|
|
||||||
if (props.color) {
|
|
||||||
color = props.color
|
|
||||||
}
|
|
||||||
|
|
||||||
const hasData = data.length > 0
|
const hasData = data.length > 0
|
||||||
const dummyDomain = [-1, 1]
|
const dummyDomain = [-1, 1]
|
||||||
const dummyData = [{ x: -2, y: -2 }]
|
const dummyData = [{ x: -2, y: -2 }]
|
||||||
@@ -122,16 +116,20 @@ export default withTheme((props: Props) => {
|
|||||||
<HorizontalGridLines />
|
<HorizontalGridLines />
|
||||||
<YAxis width={45} tickFormat={(num: number) => abbreviate(num)} />
|
<YAxis width={45} tickFormat={(num: number) => abbreviate(num)} />
|
||||||
<LineMarkSeries
|
<LineMarkSeries
|
||||||
color={color}
|
colorType="literal"
|
||||||
|
getColor={highlightSelectedPoint}
|
||||||
onValueMouseOver={showTooltip}
|
onValueMouseOver={showTooltip}
|
||||||
onValueMouseOut={hideTooltip}
|
|
||||||
onValueClick={onValueClick}
|
|
||||||
size={3}
|
size={3}
|
||||||
data={hasData ? data : dummyData}
|
data={hasData ? data : dummyData}
|
||||||
curve={mapCurveType(props.interpolation)}
|
curve={mapCurveType(props.interpolation)}
|
||||||
/>
|
/>
|
||||||
<Hint value={{}}>
|
<Hint
|
||||||
<Popper open={Boolean(tooltip)} placement="top" anchorEl={tooltip && tooltip.element}>
|
value={{}}
|
||||||
|
style={{
|
||||||
|
pointerEvents: 'none',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Popper open={Boolean(tooltip)} placement="top" anchorEl={getAnchorElement}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
paddingBottom: '8px',
|
paddingBottom: '8px',
|
||||||
|
|||||||
Reference in New Issue
Block a user