import React , { useRef , useState , useEffect , useCallback , Dispatch , SetStateAction , ReactNode } from 'react' ; import { createChart , IChartApi } from 'lightweight-charts' ; import { RowBetween } from 'components/Row' ; import Card from '../Card' ; import styled from 'styled-components' ; import useTheme from 'hooks/useTheme' ; import usePrevious from 'hooks/usePrevious' ; import { formatDollarAmount } from 'utils/numbers' ; import dayjs from 'dayjs' ; import utc from 'dayjs/plugin/utc' ; dayjs . extend ( utc ) ; const Wrapper = styled ( Card ) `
  width: 100%;
  padding: 1rem;
  padding-right: 2rem;
  display: flex;
  background-color: ${ ( { theme } ) => theme . bg0 }
  flex-direction: column;
  > * {
    font-size: 1rem;
  }
` ; const DEFAULT_HEIGHT = 300 ; export type LineChartProps = { data : any [ ] ; color ? : string | undefined ; height ? : number | undefined ; minHeight ? : number ; setValue ? : Dispatch < SetStateAction < number | undefined > > ; setLabel ? : Dispatch < SetStateAction < string | undefined > > ; topLeft ? : ReactNode | undefined ; topRight ? : ReactNode | undefined ; bottomLeft ? : ReactNode | undefined ; bottomRight ? : ReactNode | undefined ; } & React . HTMLAttributes < HTMLDivElement > ; const BarChart = ( { data , color = '#56B2A4' , setValue , setLabel , topLeft , topRight , bottomLeft , bottomRight , height = DEFAULT_HEIGHT , minHeight = DEFAULT_HEIGHT , ... rest } ) => { const theme = useTheme ( ) ; const textColor = theme . text2 ; const chartRef = useRef < HTMLDivElement > ( null ) ; const [ chartCreated , setChart ] = useState < IChartApi | undefined > ( ) ; const dataPrev = usePrevious ( data ) ; useEffect ( ( ) => { if ( dataPrev !== data && chartCreated ) { chartCreated . resize ( 0 , 0 ) ; setChart ( undefined ) ; } } , [ data , dataPrev , chartCreated ] ) ; const currentValue = data [ data . length - 1 ] ?. value ; const handleResize = useCallback ( ( ) => { if ( chartCreated && chartRef ?. current ?. parentElement ) { chartCreated . resize ( chartRef . current . parentElement . clientWidth - 32 , height ) ; chartCreated . timeScale ( ) . fitContent ( ) ; chartCreated . timeScale ( ) . scrollToPosition ( 0 , false ) ; } } , [ chartCreated , chartRef , height ] ) ; const isClient = typeof window === 'object' ; useEffect ( ( ) => { if ( ! isClient ) { return ; } window . addEventListener ( 'resize' , handleResize ) ; return ( ) => window . removeEventListener ( 'resize' , handleResize ) ; } , [ isClient , chartRef , handleResize ] ) ; useEffect ( ( ) => { if ( ! chartCreated && data && ! ! chartRef ?. current ?. parentElement ) { const chart = createChart ( chartRef . current , { height : height , width : chartRef . current . parentElement . clientWidth - 62 , layout : { backgroundColor : 'transparent' , textColor : '#565A69' , fontFamily : 'Inter var' , } , rightPriceScale : { scaleMargins : { top : 0.1 , bottom : 0 , } , drawTicks : false , borderVisible : false , visible : false , } , timeScale : { borderVisible : false , } , watermark : { color : 'rgba(0, 0, 0, 0)' , } , grid : { horzLines : { visible : false , } , vertLines : { visible : false , } , } , crosshair : { horzLine : { visible : false , labelVisible : false , } , vertLine : { visible : true , style : 3 , width : 1 , color : '#505050' , labelBackgroundColor : color , labelVisible : false , } , } , } ) ; chart . timeScale ( ) . fitContent ( ) ; setChart ( chart ) ; } } , [ color , chartCreated , currentValue , data , height , setValue , textColor , theme ] ) ; useEffect ( ( ) => { if ( chartCreated && data ) { const series = chartCreated . addHistogramSeries ( { color : color , } ) ; series . setData ( data ) ; chartCreated . timeScale ( ) . fitContent ( ) ; series . applyOptions ( { priceFormat : { type : 'custom' , minMove : 0.02 , formatter : ( price ) => formatDollarAmount ( price ) , } , } ) ; chartCreated . subscribeCrosshairMove ( function ( param ) { if ( chartRef ?. current && ( param === undefined || param . time === undefined || ( param && param . point && param . point . x < 0 ) || ( param && param . point && param . point . x > chartRef . current . clientWidth ) || ( param && param . point && param . point . y < 0 ) || ( param && param . point && param . point . y > height ) ) ) { setValue && setValue ( undefined ) ; setLabel && setLabel ( undefined ) ; } else if ( series && param ) { const time = param ?. time as { day : number ; year : number ; month : number ; } ; const timeString = dayjs ( time . year + '-' + time . month + '-' + time . day ) . format ( 'MMM D, YYYY' ) ; const price = parseFloat ( param ?. seriesPrices ?. get ( series ) ?. toString ( ) ?? currentValue ) ; setValue && setValue ( price ) ; setLabel && timeString && setLabel ( timeString ) ; } } ) ; } } , [ chartCreated , color , currentValue , data , height , setLabel , setValue , theme . bg0 ] ) ; return ( < Wrapper minHeight = { minHeight } > < RowBetween > { topLeft ?? null } { topRight ?? null } < /RowBetween> < div ref = { chartRef } id = { 'bar-chart' } { ... rest } /> < RowBetween > { bottomLeft ?? null } { bottomRight ?? null } < /RowBetween> < /Wrapper>); } ; export default BarChart ;