import DateFormatter from '../helper/DateFormatter' ; import NoData from './NoData' ; import NumberFormatter from '../helper/NumberFormatter' ; import React , { memo , useCallback } from 'react' ; import TooltipComponent from './TooltipComponent' ; import { default as ReactResizeDetector } from 'react-resize-detector' ; import { emphasize } from '@material-ui/core/styles' ; import { mapCurveType } from './mapCurveType' ; import { PlotCurveTypes } from '../../reducers/Charts' ; import { Point , Tooltip } from './Model' ; import { Theme , withTheme } from '@material-ui/core' ; import { useCustomXDomain } from './effects/useCustomXDomain' ; import { useCustomYDomain } from './effects/useCustomYDomain' ; import 'react-vis/dist/style.css' ; const { XYPlot , LineMarkSeries , YAxis , HorizontalGridLines , Hint } = require ( 'react-vis' ) ; const abbreviate = require ( 'number-abbreviate' ) ; export interface Props { data : Array < { x : number ; y : number ; } > ; theme : Theme ; interpolation ? : PlotCurveTypes ; range ? : [ number ? , number ? ] ; timeRangeStart ? : number ; color ? : string ; } export default withTheme ( memo ( ( props ) => { const [ width , setWidth ] = React . useState ( 300 ) ; const [ tooltip , setTooltip ] = React . useState < Tooltip | undefined > ( ) ; const detectResize = React . useCallback ( newWidth => setWidth ( newWidth ) , [ ] ) ; const hintFormatter = React . useCallback ( ( point ) => [ { title : < b > Time < /b>, value: <DateFormatter timeFirst={true} date={new Date(point.x)}/ > } , { title : < b > Value < /b>, value: <NumberFormatter value={point.y}/ > } , { title : < b > Raw < /b>, value: <span>{point.y}</span > } , ] , [ ] ) ; const onMouseLeave = React . useCallback ( ( ) => { setTooltip ( undefined ) ; } , [ ] ) ; const showTooltip = React . useCallback ( ( point , something ) => { if ( ! something ) { return ; } setTooltip ( { point , value : hintFormatter ( point ) , element : something . event . target as any } ) ; } , [ ] ) ; const paletteColor = props . theme . palette . type === 'light' ? props . theme . palette . secondary . dark : props . theme . palette . primary . light ; const color = props . color ? props . color : paletteColor ; const highlightSelectedPoint = useCallback ( ( point ) => { const highlight = tooltip && tooltip . point . x === point . x && tooltip . point . y === point . y ; return highlight ? emphasize ( color , 0.8 ) : color ; } , [ tooltip , color ] ) ; const formatYAxis = useCallback ( ( num ) => abbreviate ( num ) , [ ] ) ; const xDomain = useCustomXDomain ( props ) ; const yDomain = useCustomYDomain ( props ) ; const data = props . data ; const hasData = data . length > 0 ; const dummyDomain = [ - 1 , 1 ] ; const dummyData = [ { x : - 2 , y : - 2 } ] ; return ( < div > < div style = { { height : '150px' , width : '100%' , position : 'relative' } } > { data . length === 0 ? < NoData /> : null} < XYPlot width = { width } height = { 180 } yDomain = { hasData ? yDomain : dummyDomain } xDomain = { hasData ? xDomain : dummyDomain } onMouseLeave = { onMouseLeave } > < HorizontalGridLines /> < YAxis width = { 45 } tickFormat = { formatYAxis } / > < LineMarkSeries color = { color } colorType = "literal" getColor = { highlightSelectedPoint } onValueMouseOver = { showTooltip } size = { 3 } data = { hasData ? data : dummyData } curve = { mapCurveType ( props . interpolation ) } /> < Hint value = { { x : 0 , y : 0 } } style = { { pointerEvents : 'none' } } > < TooltipComponent tooltip = { tooltip } theme = { props . theme } / > < /Hint> < /XYPlot> < ReactResizeDetector handleWidth = { true } onResize = { detectResize } / > < /div> < /div>); } ) ) ;