import { useMemo } from 'react' import { scaleTime, scaleLinear } from 'd3-scale' import { curveStepAfter } from 'd3-shape' import { min, max } from 'lodash' import dayjs from 'dayjs' import { PortfolioMetrics } from 'common/user' import { Col } from '../layout/col' import { TooltipProps } from 'web/components/charts/helpers' import { HistoryPoint, SingleValueHistoryChart, } from 'web/components/charts/generic-charts' const MARGIN = { top: 20, right: 10, bottom: 20, left: 70 } const MARGIN_X = MARGIN.left + MARGIN.right const MARGIN_Y = MARGIN.top + MARGIN.bottom export type GraphMode = 'profit' | 'value' export const PortfolioTooltip = (props: TooltipProps) => { const { x, xScale } = props const d = dayjs(xScale.invert(x)) return (
{d.format('MMM/D/YY')}
{d.format('h:mm A')}
) } const getY = (mode: GraphMode, p: PortfolioMetrics) => p.balance + p.investmentValue - (mode === 'profit' ? p.totalDeposits : 0) export function getPoints(mode: GraphMode, history: PortfolioMetrics[]) { return history.map((p) => ({ x: new Date(p.timestamp), y: getY(mode, p), obj: p, })) } export const PortfolioGraph = (props: { mode: 'profit' | 'value' history: PortfolioMetrics[] width: number height: number onMouseOver?: (p: HistoryPoint | undefined) => void }) => { const { mode, history, onMouseOver, width, height } = props const { data, minDate, maxDate, minValue, maxValue } = useMemo(() => { const data = getPoints(mode, history) // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const minDate = min(data.map((d) => d.x))! // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const maxDate = max(data.map((d) => d.x))! // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const minValue = min(data.map((d) => d.y))! // eslint-disable-next-line @typescript-eslint/no-non-null-assertion const maxValue = max(data.map((d) => d.y))! return { data, minDate, maxDate, minValue, maxValue } }, [mode, history]) return ( (p.y >= 0 ? '#14b8a6' : '#f00') } /> ) }