getting site numbers to update graph upon hover

This commit is contained in:
ingawei 2022-09-23 13:12:16 -07:00
parent f916f2bd74
commit e3520a5650
2 changed files with 60 additions and 55 deletions

View File

@ -1,18 +1,22 @@
import { ResponsiveLine } from '@nivo/line' import { ResponsiveLine } from '@nivo/line'
import { PortfolioMetrics } from 'common/user' import { PortfolioMetrics } from 'common/user'
import { formatMoney } from 'common/util/format' import { formatMoney } from 'common/util/format'
import { last } from 'lodash' import dayjs from 'dayjs'
import { last, set } from 'lodash'
import { memo } from 'react' import { memo } from 'react'
import { useWindowSize } from 'web/hooks/use-window-size' import { useWindowSize } from 'web/hooks/use-window-size'
import { formatTime } from 'web/lib/util/time' import { formatTime } from 'web/lib/util/time'
import { Col } from '../layout/col'
export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: { export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
portfolioHistory: PortfolioMetrics[] portfolioHistory: PortfolioMetrics[]
mode: 'value' | 'profit' mode: 'value' | 'profit'
setGraphDisplayNumber: (value: number | string) => void
height?: number height?: number
includeTime?: boolean includeTime?: boolean
}) { }) {
const { portfolioHistory, height, includeTime, mode } = props const { portfolioHistory, height, includeTime, mode, setGraphDisplayNumber } =
props
const { width } = useWindowSize() const { width } = useWindowSize()
function getPoints(line: 'value' | 'posProfit' | 'negProfit') { function getPoints(line: 'value' | 'posProfit' | 'negProfit') {
@ -62,8 +66,8 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
] ]
} }
const firstPoints = data[0].data const firstPoints = data[0].data
const numXTickValues = !width || width < 800 ? 2 : 5 // const numXTickValues = !width || width < 800 ? 2 : 5
const numYTickValues = 4 // const numYTickValues = 4
const endDate = last(firstPoints)?.x const endDate = last(firstPoints)?.x
const firstPointsY = firstPoints const firstPointsY = firstPoints
@ -73,8 +77,7 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
.map((p) => p.y) .map((p) => p.y)
// console.log(firstPointsY) // console.log(firstPointsY)
console.log( const yMin =
'MIN: ',
mode === 'value' mode === 'value'
? Math.min(...firstPointsY) ? Math.min(...firstPointsY)
: Math.min( : Math.min(
@ -84,9 +87,9 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
return p.y !== null return p.y !== null
}) })
.map((p) => p.y) .map((p) => p.y)
), )
'MAX: ', const yMax =
mode === 'value' mode === 'value'
? Math.max(...firstPointsY) ? Math.max(...firstPointsY)
: Math.max( : Math.max(
@ -97,16 +100,15 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
}) })
.map((p) => p.y) .map((p) => p.y)
) )
)
return ( return (
<div <div
className="w-full overflow-hidden" className="w-full overflow-hidden"
style={{ height: height ?? (!width || width >= 800 ? 350 : 250) }} style={{ height: height ?? (!width || width >= 800 ? 200 : 100) }}
> >
<ResponsiveLine <ResponsiveLine
margin={{ top: 10, right: 0, left: 0, bottom: 10 }}
data={data} data={data}
margin={{ top: 20, right: 28, bottom: 22, left: 60 }}
xScale={{ xScale={{
type: 'time', type: 'time',
min: firstPoints[0]?.x, min: firstPoints[0]?.x,
@ -115,63 +117,56 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
yScale={{ yScale={{
type: 'linear', type: 'linear',
stacked: false, stacked: false,
min: min: yMin,
mode === 'value' max: yMax,
? Math.min(...firstPointsY)
: Math.min(
...firstPointsY,
...data[1].data
.filter((p) => {
return p.y !== null
})
.map((p) => p.y)
),
max:
mode === 'value'
? Math.max(...firstPointsY)
: Math.max(
...firstPointsY,
...data[1].data
.filter((p) => {
return p.y !== null
})
.map((p) => p.y)
),
}} }}
gridYValues={numYTickValues} curve="stepAfter"
curve="linear"
enablePoints={false} enablePoints={false}
colors={{ datum: 'color' }} colors={{ datum: 'color' }}
axisBottom={{ axisBottom={{
tickValues: numXTickValues, tickValues: 0,
format: (time) => formatTime(+time, !!includeTime), format: (time) => formatTime(+time, !!includeTime),
}} }}
pointBorderColor="#fff" pointBorderColor="#fff"
pointSize={firstPoints.length > 100 ? 0 : 6} pointSize={firstPoints.length > 100 ? 0 : 6}
axisLeft={{ axisLeft={{
tickValues: numYTickValues, tickValues: 0,
format: (value) => formatMoney(value), format: (value) => formatMoney(value),
}} }}
enableGridX={!!width && width >= 800} enableGridX={false}
enableGridY={true} enableGridY={false}
enableSlices="x" enableSlices="x"
animate={false} animate={false}
yFormat={(value) => formatMoney(+value)} yFormat={(value) => formatMoney(+value)}
// defs={[
// {
// id: 'purpleGradient',
// type: 'linearGradient',
// colors: [
// { offset: 0, color: '#7c3aed' },
// {
// offset: 100,
// color: '#inherit',
// opacity: 0,
// },
// ],
// },
// ]}
enableArea={true} enableArea={true}
areaOpacity={0.1}
sliceTooltip={({ slice }) => {
slice.points.map((point) =>
setGraphDisplayNumber(point.data.yFormatted)
)
return (
<div className="rounded bg-white px-4 py-2 opacity-80">
{slice.points.map((point) => (
<div
key={point.id}
style={{
color: point.serieColor,
padding: '3px 0',
}}
>
<Col>
<div>
<strong>Time</strong> [{point.data.xFormatted}]
</div>
<div>
<strong>{point.serieId}</strong> [{point.data.yFormatted}]
</div>
</Col>
</div>
))}
</div>
)
}}
></ResponsiveLine> ></ResponsiveLine>
</div> </div>
) )

View File

@ -17,6 +17,7 @@ export const PortfolioValueSection = memo(
const [portfolioPeriod, setPortfolioPeriod] = useState<Period>('weekly') const [portfolioPeriod, setPortfolioPeriod] = useState<Period>('weekly')
const portfolioHistory = usePortfolioHistory(userId, portfolioPeriod) const portfolioHistory = usePortfolioHistory(userId, portfolioPeriod)
const [graphMode, setGraphMode] = useState<'profit' | 'value'>('profit') const [graphMode, setGraphMode] = useState<'profit' | 'value'>('profit')
const [graphDisplayNumber, setGraphDisplayNumber] = useState(null)
// Remember the last defined portfolio history. // Remember the last defined portfolio history.
const portfolioRef = useRef(portfolioHistory) const portfolioRef = useRef(portfolioHistory)
@ -41,7 +42,11 @@ export const PortfolioValueSection = memo(
Portfolio value Portfolio value
</div> </div>
<div className="text-lg text-indigo-600 sm:text-xl"> <div className="text-lg text-indigo-600 sm:text-xl">
{formatMoney(totalValue)} {graphMode === 'value'
? graphDisplayNumber
? graphDisplayNumber
: formatMoney(totalValue)
: formatMoney(totalValue)}
</div> </div>
</Col> </Col>
<Col> <Col>
@ -52,7 +57,11 @@ export const PortfolioValueSection = memo(
'text-lg sm:text-xl' 'text-lg sm:text-xl'
)} )}
> >
{formatMoney(totalProfit)} {graphMode === 'profit'
? graphDisplayNumber
? graphDisplayNumber
: formatMoney(totalProfit)
: formatMoney(totalProfit)}
</div> </div>
</Col> </Col>
</Row> </Row>
@ -62,6 +71,7 @@ export const PortfolioValueSection = memo(
portfolioHistory={currPortfolioHistory} portfolioHistory={currPortfolioHistory}
includeTime={true} includeTime={true}
mode={graphMode} mode={graphMode}
setGraphDisplayNumber={setGraphDisplayNumber}
/> />
<PortfolioPeriodSelection <PortfolioPeriodSelection
portfolioPeriod={portfolioPeriod} portfolioPeriod={portfolioPeriod}