115 lines
3.4 KiB
TypeScript
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>
|
|
)
|
|
}
|