cleaning up, no mapping in graph tooltip
This commit is contained in:
parent
33b33c92f9
commit
4ed62fd5d7
|
@ -155,8 +155,6 @@ export function BetsList(props: { user: User }) {
|
||||||
(c) => contractsMetrics[c.id].netPayout
|
(c) => contractsMetrics[c.id].netPayout
|
||||||
)
|
)
|
||||||
|
|
||||||
// const totalPnl = user.profitCached.allTime
|
|
||||||
// const totalProfitPercent = (totalPnl / user.totalDeposits) * 100
|
|
||||||
const investedProfitPercent =
|
const investedProfitPercent =
|
||||||
((currentBetsValue - currentInvested) / (currentInvested + 0.1)) * 100
|
((currentBetsValue - currentInvested) / (currentInvested + 0.1)) * 100
|
||||||
|
|
||||||
|
|
|
@ -55,13 +55,6 @@ export function ContractsGrid(props: {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (contracts.length === 0) {
|
if (contracts.length === 0) {
|
||||||
// if (profile) {
|
|
||||||
// return (
|
|
||||||
// <p className="mx-2 text-gray-500">
|
|
||||||
// This creator does not yet have any markets.
|
|
||||||
// </p>
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
return (
|
return (
|
||||||
<p className="mx-2 text-gray-500">
|
<p className="mx-2 text-gray-500">
|
||||||
No markets found. Why not{' '}
|
No markets found. Why not{' '}
|
||||||
|
@ -70,7 +63,6 @@ export function ContractsGrid(props: {
|
||||||
</SiteLink>
|
</SiteLink>
|
||||||
</p>
|
</p>
|
||||||
)
|
)
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { ResponsiveLine } from '@nivo/line'
|
import { ResponsiveLine } from '@nivo/line'
|
||||||
import { PortfolioMetrics } from 'common/user'
|
import { PortfolioMetrics } from 'common/user'
|
||||||
|
import { filterDefined } from 'common/util/array'
|
||||||
import { formatMoney } from 'common/util/format'
|
import { formatMoney } from 'common/util/format'
|
||||||
import dayjs from 'dayjs'
|
import dayjs from 'dayjs'
|
||||||
import { last } from 'lodash'
|
import { last } from 'lodash'
|
||||||
|
@ -10,103 +11,69 @@ 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: (arg0: number | string | null) => void
|
handleGraphDisplayChange: (arg0: string | number | null) => void
|
||||||
height?: number
|
height?: number
|
||||||
}) {
|
}) {
|
||||||
const { portfolioHistory, height, mode, setGraphDisplayNumber } = props
|
const { portfolioHistory, height, mode, handleGraphDisplayChange } = props
|
||||||
const { width } = useWindowSize()
|
const { width } = useWindowSize()
|
||||||
|
|
||||||
function getPoints(line: 'value' | 'posProfit' | 'negProfit') {
|
const valuePoints = getPoints('value', portfolioHistory)
|
||||||
const points = portfolioHistory.map((p) => {
|
const posProfitPoints = getPoints('posProfit', portfolioHistory)
|
||||||
const { timestamp, balance, investmentValue, totalDeposits } = p
|
const negProfitPoints = getPoints('negProfit', portfolioHistory)
|
||||||
const value = balance + investmentValue
|
|
||||||
|
|
||||||
const profit = value - totalDeposits
|
const valuePointsY = valuePoints.map((p) => p.y)
|
||||||
let posProfit = null
|
const posProfitPointsY = posProfitPoints.map((p) => p.y)
|
||||||
let negProfit = null
|
const negProfitPointsY = negProfitPoints.map((p) => p.y)
|
||||||
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
|
let data
|
||||||
|
|
||||||
if (mode === 'value') {
|
if (mode === 'value') {
|
||||||
data = [{ id: 'value', data: getPoints('value'), color: '#4f46e5' }]
|
data = [{ id: 'value', data: valuePoints, color: '#4f46e5' }]
|
||||||
} else {
|
} else {
|
||||||
data = [
|
data = [
|
||||||
{
|
{
|
||||||
id: 'negProfit',
|
id: 'negProfit',
|
||||||
data: getPoints('negProfit'),
|
data: negProfitPoints,
|
||||||
color: '#dc2626',
|
color: '#dc2626',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'posProfit',
|
id: 'posProfit',
|
||||||
data: getPoints('posProfit'),
|
data: posProfitPoints,
|
||||||
color: '#14b8a6',
|
color: '#14b8a6',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
const firstPoints = data[0].data
|
|
||||||
const numYTickValues = 2
|
const numYTickValues = 2
|
||||||
const endDate = last(data[0].data)?.x
|
const endDate = last(data[0].data)?.x
|
||||||
|
|
||||||
const firstPointsY = firstPoints
|
|
||||||
.map((p) => p.y)
|
|
||||||
.filter((y) => {
|
|
||||||
return y !== null
|
|
||||||
})
|
|
||||||
|
|
||||||
const yMin =
|
const yMin =
|
||||||
mode === 'value'
|
mode === 'value'
|
||||||
? Math.min(...firstPointsY)
|
? Math.min(...filterDefined(valuePointsY))
|
||||||
: Math.min(
|
: Math.min(
|
||||||
...firstPointsY,
|
...filterDefined(negProfitPointsY),
|
||||||
...data[1].data
|
...filterDefined(posProfitPointsY)
|
||||||
.filter((p) => {
|
|
||||||
return p.y !== null
|
|
||||||
})
|
|
||||||
.map((p) => p.y)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const yMax =
|
const yMax =
|
||||||
mode === 'value'
|
mode === 'value'
|
||||||
? Math.max(...firstPointsY)
|
? Math.max(...filterDefined(valuePointsY))
|
||||||
: Math.max(
|
: Math.max(
|
||||||
...firstPointsY,
|
...filterDefined(negProfitPointsY),
|
||||||
...data[1].data
|
...filterDefined(posProfitPointsY)
|
||||||
.filter((p) => {
|
|
||||||
return p.y !== null
|
|
||||||
})
|
|
||||||
.map((p) => p.y)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="w-full overflow-hidden"
|
className="w-full overflow-hidden"
|
||||||
style={{ height: height ?? (!width || width >= 800 ? 200 : 100) }}
|
style={{ height: height ?? (!width || width >= 800 ? 200 : 100) }}
|
||||||
onMouseLeave={() => setGraphDisplayNumber(null)}
|
onMouseLeave={() => handleGraphDisplayChange(null)}
|
||||||
>
|
>
|
||||||
<ResponsiveLine
|
<ResponsiveLine
|
||||||
margin={{ top: 10, right: 0, left: 40, bottom: 10 }}
|
margin={{ top: 10, right: 0, left: 40, bottom: 10 }}
|
||||||
data={data}
|
data={data}
|
||||||
xScale={{
|
xScale={{
|
||||||
type: 'time',
|
type: 'time',
|
||||||
min: firstPoints[0]?.x,
|
min: valuePoints[0]?.x,
|
||||||
max: endDate,
|
max: endDate,
|
||||||
}}
|
}}
|
||||||
yScale={{
|
yScale={{
|
||||||
|
@ -122,7 +89,7 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
|
||||||
tickValues: 0,
|
tickValues: 0,
|
||||||
}}
|
}}
|
||||||
pointBorderColor="#fff"
|
pointBorderColor="#fff"
|
||||||
pointSize={firstPoints.length > 100 ? 0 : 6}
|
pointSize={valuePoints.length > 100 ? 0 : 6}
|
||||||
axisLeft={{
|
axisLeft={{
|
||||||
tickValues: numYTickValues,
|
tickValues: numYTickValues,
|
||||||
format: '.3s',
|
format: '.3s',
|
||||||
|
@ -136,24 +103,23 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
|
||||||
enableArea={true}
|
enableArea={true}
|
||||||
areaOpacity={0.1}
|
areaOpacity={0.1}
|
||||||
sliceTooltip={({ slice }) => {
|
sliceTooltip={({ slice }) => {
|
||||||
slice.points.map((point) =>
|
handleGraphDisplayChange(slice.points[0].data.yFormatted)
|
||||||
setGraphDisplayNumber(point.data.yFormatted)
|
|
||||||
)
|
|
||||||
return (
|
return (
|
||||||
<div className="rounded bg-white px-4 py-2 opacity-80">
|
<div className="rounded bg-white px-4 py-2 opacity-80">
|
||||||
{slice.points.map((point) => (
|
<div
|
||||||
<div
|
key={slice.points[0].id}
|
||||||
key={point.id}
|
className="text-xs font-semibold sm:text-sm"
|
||||||
className="text-xs font-semibold sm:text-sm"
|
>
|
||||||
>
|
<Col>
|
||||||
<Col>
|
<div>
|
||||||
<div>{dayjs(point.data.xFormatted).format('MMM/D/YY')}</div>
|
{dayjs(slice.points[0].data.xFormatted).format('MMM/D/YY')}
|
||||||
<div className="text-greyscale-6 text-2xs font-normal sm:text-xs">
|
</div>
|
||||||
{dayjs(point.data.xFormatted).format('h:mm A')}
|
<div className="text-greyscale-6 text-2xs font-normal sm:text-xs">
|
||||||
</div>
|
{dayjs(slice.points[0].data.xFormatted).format('h:mm A')}
|
||||||
</Col>
|
</div>
|
||||||
</div>
|
</Col>
|
||||||
))}
|
</div>
|
||||||
|
{/* ))} */}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
|
@ -161,3 +127,29 @@ export const PortfolioValueGraph = memo(function PortfolioValueGraph(props: {
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
export function getPoints(
|
||||||
|
line: 'value' | 'posProfit' | 'negProfit',
|
||||||
|
portfolioHistory: PortfolioMetrics[]
|
||||||
|
) {
|
||||||
|
const points = portfolioHistory.map((p) => {
|
||||||
|
const { timestamp, balance, investmentValue, totalDeposits } = p
|
||||||
|
const value = balance + investmentValue
|
||||||
|
|
||||||
|
const profit = value - totalDeposits
|
||||||
|
let posProfit = null
|
||||||
|
let negProfit = null
|
||||||
|
if (profit < 0) {
|
||||||
|
negProfit = profit
|
||||||
|
} else {
|
||||||
|
posProfit = profit
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
x: new Date(timestamp),
|
||||||
|
y:
|
||||||
|
line === 'value' ? value : line === 'posProfit' ? posProfit : negProfit,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return points
|
||||||
|
}
|
||||||
|
|
|
@ -16,8 +16,10 @@ 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'>('value')
|
const [graphMode, setGraphMode] = useState<'profit' | 'value'>('value')
|
||||||
const [graphDisplayNumber, setGraphDisplayNumber] = useState(null)
|
const [graphDisplayNumber, setGraphDisplayNumber] = useState<
|
||||||
const handleGraphDisplayChange = (num) => {
|
number | string | null
|
||||||
|
>(null)
|
||||||
|
const handleGraphDisplayChange = (num: string | number | null) => {
|
||||||
setGraphDisplayNumber(num)
|
setGraphDisplayNumber(num)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +72,7 @@ export const PortfolioValueSection = memo(
|
||||||
className={clsx(
|
className={clsx(
|
||||||
graphMode === 'profit'
|
graphMode === 'profit'
|
||||||
? graphDisplayNumber
|
? graphDisplayNumber
|
||||||
? graphDisplayNumber[2] === '-'
|
? graphDisplayNumber.toString().includes('-')
|
||||||
? 'text-red-600'
|
? 'text-red-600'
|
||||||
: 'text-teal-500'
|
: 'text-teal-500'
|
||||||
: totalProfit > 0
|
: totalProfit > 0
|
||||||
|
@ -90,13 +92,11 @@ export const PortfolioValueSection = memo(
|
||||||
</div>
|
</div>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
{/* <GraphToggle setGraphMode={setGraphMode} graphMode={graphMode} /> */}
|
|
||||||
</Row>
|
</Row>
|
||||||
<PortfolioValueGraph
|
<PortfolioValueGraph
|
||||||
portfolioHistory={currPortfolioHistory}
|
portfolioHistory={currPortfolioHistory}
|
||||||
includeTime={true}
|
|
||||||
mode={graphMode}
|
mode={graphMode}
|
||||||
setGraphDisplayNumber={handleGraphDisplayChange}
|
handleGraphDisplayChange={handleGraphDisplayChange}
|
||||||
/>
|
/>
|
||||||
<PortfolioPeriodSelection
|
<PortfolioPeriodSelection
|
||||||
portfolioPeriod={portfolioPeriod}
|
portfolioPeriod={portfolioPeriod}
|
||||||
|
|
|
@ -47,7 +47,8 @@ export function UserPage(props: { user: User }) {
|
||||||
const isMobile = useIsMobile()
|
const isMobile = useIsMobile()
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// const claimedMana = router.query['claimed-mana'] === 'yes'
|
const claimedMana = router.query['claimed-mana'] === 'yes'
|
||||||
|
setShowConfetti(claimedMana)
|
||||||
const query = { ...router.query }
|
const query = { ...router.query }
|
||||||
if (query.claimedMana || query.show) {
|
if (query.claimedMana || query.show) {
|
||||||
delete query['claimed-mana']
|
delete query['claimed-mana']
|
||||||
|
@ -218,14 +219,6 @@ export function UserPage(props: { user: User }) {
|
||||||
</Col>
|
</Col>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// title: 'Stats',
|
|
||||||
// content: (
|
|
||||||
// <Col className="mb-8">
|
|
||||||
// <PortfolioValueSection userId={user.id} />
|
|
||||||
// </Col>
|
|
||||||
// ),
|
|
||||||
// },
|
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</Col>
|
</Col>
|
||||||
|
@ -263,6 +256,7 @@ export function ProfilePrivateStats(props: {
|
||||||
|
|
||||||
const showLoansModel = router.query['show'] === 'loans'
|
const showLoansModel = router.query['show'] === 'loans'
|
||||||
setShowLoansModal(showLoansModel)
|
setShowLoansModal(showLoansModel)
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [])
|
}, [])
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user