import { ResponsiveLine } from '@nivo/line' import { PortfolioMetrics } from 'common/user' import { formatMoney } from 'common/util/format' import dayjs from 'dayjs' import { last, set } from 'lodash' import { memo } from 'react' import { useWindowSize } from 'web/hooks/use-window-size' import { formatTime } from 'web/lib/util/time' import { Col } from '../layout/col' export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: { portfolioHistory: PortfolioMetrics[] mode: 'value' | 'profit' setGraphDisplayNumber: (value: number | string) => void height?: number includeTime?: boolean }) { const { portfolioHistory, height, includeTime, mode, setGraphDisplayNumber } = props const { width } = useWindowSize() function getPoints(line: 'value' | 'posProfit' | 'negProfit') { let points = portfolioHistory.map((p) => { const { timestamp, balance, investmentValue, totalDeposits } = p const value = balance + investmentValue const profit = value - totalDeposits let posProfit = null let negProfit = null // const profit = value - totalDeposits if (profit < 0) { negProfit = profit } else { posProfit = profit } return { x: new Date(timestamp), y: line === 'value' ? value : line === 'posProfit' ? posProfit : negProfit, } }) return points } let data if (mode === 'value') { data = [{ id: 'value', data: getPoints('value'), color: '#4f46e5' }] } else { data = [ { id: 'negProfit', data: getPoints('negProfit'), color: '#dc2626', }, { id: 'posProfit', data: getPoints('posProfit'), color: '#14b8a6', }, ] } const firstPoints = data[0].data // const numXTickValues = !width || width < 800 ? 2 : 5 // const numYTickValues = 4 const endDate = last(firstPoints)?.x const firstPointsY = firstPoints .filter((p) => { return p.y !== null }) .map((p) => p.y) // console.log(firstPointsY) const yMin = mode === 'value' ? Math.min(...firstPointsY) : Math.min( ...firstPointsY, ...data[1].data .filter((p) => { return p.y !== null }) .map((p) => p.y) ) const yMax = mode === 'value' ? Math.max(...firstPointsY) : Math.max( ...firstPointsY, ...data[1].data .filter((p) => { return p.y !== null }) .map((p) => p.y) ) return (
= 800 ? 200 : 100) }} > formatTime(+time, !!includeTime), }} pointBorderColor="#fff" pointSize={firstPoints.length > 100 ? 0 : 6} axisLeft={{ tickValues: 0, format: (value) => formatMoney(value), }} enableGridX={false} enableGridY={false} enableSlices="x" animate={false} yFormat={(value) => formatMoney(+value)} enableArea={true} areaOpacity={0.1} sliceTooltip={({ slice }) => { slice.points.map((point) => setGraphDisplayNumber(point.data.yFormatted) ) return (
{slice.points.map((point) => (
Time [{point.data.xFormatted}]
{point.serieId} [{point.data.yFormatted}]
))}
) }} >
) })