market/src/components/Asset/AssetActions/Pool/Graph/index.tsx

115 lines
3.4 KiB
TypeScript

import React, { ReactElement, useEffect, useState } from 'react'
import { ChartData, ChartOptions } from 'chart.js'
import { Bar, Line } from 'react-chartjs-2'
import Loader from '@shared/atoms/Loader'
import { useUserPreferences } from '@context/UserPreferences'
import useDarkMode from 'use-dark-mode'
import { darkModeConfig } from '../../../../../../app.config'
import { LoggerInstance } from '@oceanprotocol/lib'
import styles from './index.module.css'
import Decimal from 'decimal.js'
import { lineStyle, GraphType } from './_constants'
import Nav from './Nav'
import { getOptions } from './_utils'
import { usePrices } from '@context/Prices'
import { MAX_DECIMALS } from '@utils/constants'
import { usePool } from '@context/Pool'
export default function Graph(): ReactElement {
const { locale, currency } = useUserPreferences()
const { prices } = usePrices()
const { poolSnapshots } = usePool()
const darkMode = useDarkMode(false, darkModeConfig)
const [options, setOptions] = useState<ChartOptions<any>>()
const [graphType, setGraphType] = useState<GraphType>('tvl')
const [graphData, setGraphData] = useState<ChartData<any>>()
//
// 0 Get Graph options
//
useEffect(() => {
if (!poolSnapshots) return
LoggerInstance.log('[pool graph] Fired getOptions().')
const symbol =
graphType === 'tvl' ? currency : poolSnapshots[0]?.baseToken?.symbol
const options = getOptions(locale, darkMode.value, symbol)
setOptions(options)
}, [locale, darkMode.value, graphType, currency, poolSnapshots])
//
// 1 Data manipulation
//
useEffect(() => {
if (!poolSnapshots) return
const timestamps = poolSnapshots.map((item) => {
const date = new Date(item.date * 1000)
return `${date.toLocaleDateString(locale)}`
})
const tvlHistory = poolSnapshots.map((item) => {
const conversionSpotPrice = prices[currency.toLowerCase()]
const tvl = new Decimal(item.baseTokenLiquidity)
.mul(conversionSpotPrice) // convert to user currency
.toString()
return tvl
})
const priceHistory = poolSnapshots.map((item) => item.spotPrice)
const volumeHistory = poolSnapshots.map((item) => {
const volume = new Decimal(item.swapVolume)
.toDecimalPlaces(MAX_DECIMALS)
.toString()
return volume
})
let data
switch (graphType) {
case 'price':
data = priceHistory
break
case 'volume':
data = volumeHistory
break
default:
data = tvlHistory
break
}
const newGraphData = {
labels: timestamps,
datasets: [
{
...lineStyle,
data,
borderColor: `#8b98a9`,
backgroundColor: darkMode.value ? '#201f1f' : '#f7f7f7'
}
]
}
setGraphData(newGraphData)
LoggerInstance.log('[pool graph] New graph data created:', newGraphData)
}, [poolSnapshots, graphType, currency, prices, locale, darkMode.value])
return (
<div className={styles.graphWrap}>
{!graphData ? (
<Loader />
) : (
<>
{graphType === 'volume' ? (
<Bar width={416} height={120} data={graphData} options={options} />
) : (
<Line width={416} height={120} data={graphData} options={options} />
)}
<Nav graphType={graphType} setGraphType={setGraphType} />
</>
)}
</div>
)
}