Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit

Permalink
fix: simplify liqudity depth hooks and improve chart primitives (#1999)
Browse files Browse the repository at this point in the history
* updated hooks and chart primitives

* add lodash.inrange to package.json
  • Loading branch information
Justin Domingue authored Jul 8, 2021
1 parent 3ae9e2a commit 2db29f2
Show file tree
Hide file tree
Showing 8 changed files with 98 additions and 86 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"@types/lingui__macro": "^2.7.4",
"@types/lingui__react": "^2.8.3",
"@types/lodash.flatmap": "^4.5.6",
"@types/lodash.inrange": "^3.3.6",
"@types/luxon": "^1.24.4",
"@types/ms.macro": "^2.0.0",
"@types/multicodec": "^1.0.0",
Expand Down Expand Up @@ -78,6 +79,7 @@
"inter-ui": "^3.13.1",
"lightweight-charts": "^3.3.0",
"lodash.flatmap": "^4.5.0",
"lodash.inrange": "^3.3.6",
"luxon": "^1.25.0",
"ms.macro": "^2.0.0",
"multicodec": "^3.0.1",
Expand Down
2 changes: 1 addition & 1 deletion src/components/LiquidityChartRangeInput/AxisBottom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const Axis = ({ axisGenerator }: { axisGenerator: d3Axis<NumberValue> }) => {
export const AxisBottom = ({
xScale,
innerHeight,
offset = 5,
offset = 0,
}: {
xScale: ScaleLinear<number, number>
innerHeight: number
Expand Down
7 changes: 5 additions & 2 deletions src/components/LiquidityChartRangeInput/Brush.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ const Tooltip = styled.text`
fill: ${({ theme }) => theme.text1};
`

// flips the handles draggers when close to the container edges
const FLIP_HANDLE_THRESHOLD_PX = 20

export const Brush = ({
id,
xScale,
Expand Down Expand Up @@ -144,8 +147,8 @@ export const Brush = ({
return () => clearTimeout(timeout)
}, [localBrushExtent])

const flipWestHandle = localBrushExtent && xScale(localBrushExtent[0]) > 15
const flipEastHandle = localBrushExtent && xScale(localBrushExtent[1]) > innerWidth - 15
const flipWestHandle = localBrushExtent && xScale(localBrushExtent[0]) > FLIP_HANDLE_THRESHOLD_PX
const flipEastHandle = localBrushExtent && xScale(localBrushExtent[1]) > innerWidth - FLIP_HANDLE_THRESHOLD_PX

return useMemo(
() => (
Expand Down
10 changes: 5 additions & 5 deletions src/components/LiquidityChartRangeInput/Zoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ const Button = styled(ButtonGray)`
color: ${({ theme }) => theme.text1};
}
width: 28px;
height: 28px;
width: 32px;
height: 32px;
padding: 4px;
`

Expand Down Expand Up @@ -91,14 +91,14 @@ export default function Zoom({
<Wrapper count={showClear ? 3 : 2}>
{showClear && (
<Button onClick={reset} disabled={false}>
<RefreshCcw size={14} />
<RefreshCcw size={16} />
</Button>
)}
<Button onClick={zoomIn} disabled={false}>
<ZoomIn size={14} />
<ZoomIn size={16} />
</Button>
<Button onClick={zoomOut} disabled={false}>
<ZoomOut size={14} />
<ZoomOut size={16} />
</Button>
</Wrapper>
)
Expand Down
68 changes: 24 additions & 44 deletions src/components/LiquidityChartRangeInput/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { useEffect, useState } from 'react'
import { useCallback, useMemo } from 'react'
import { Currency } from '@uniswap/sdk-core'
import { FeeAmount } from '@uniswap/v3-sdk'
import { usePoolActiveLiquidity } from 'hooks/usePoolTickData'
import { ChartEntry } from './types'
import JSBI from 'jsbi'

// Tick with fields parsed to JSBIs, and active liquidity computed.
export interface TickProcessed {
tickIdx: number
liquidityActive: JSBI
liquidityNet: JSBI
price0: string
}

Expand All @@ -22,53 +19,36 @@ export function useDensityChartData({
currencyB: Currency | undefined
feeAmount: FeeAmount | undefined
}) {
const [formattedData, setFormattedData] = useState<ChartEntry[] | undefined>()
const { isLoading, isUninitialized, isError, error, data } = usePoolActiveLiquidity(currencyA, currencyB, feeAmount)

const { isLoading, isUninitialized, isError, error, activeTick, data } = usePoolActiveLiquidity(
currencyA,
currencyB,
feeAmount
)

useEffect(() => {
// clear data when inputs are cleared
setFormattedData(undefined)
}, [currencyA, currencyB, feeAmount])

useEffect(() => {
function formatData() {
if (!data?.length) {
return
}

const newData: ChartEntry[] = []
const formatData = useCallback(() => {
if (!data?.length) {
return undefined
}

for (let i = 0; i < data.length; i++) {
const t: TickProcessed = data[i]
const newData: ChartEntry[] = []

const chartEntry = {
activeLiquidity: parseFloat(t.liquidityActive.toString()),
price0: parseFloat(t.price0),
}
for (let i = 0; i < data.length; i++) {
const t: TickProcessed = data[i]

newData.push(chartEntry)
const chartEntry = {
activeLiquidity: parseFloat(t.liquidityActive.toString()),
price0: parseFloat(t.price0),
}

if (newData) {
setFormattedData(newData)
}
newData.push(chartEntry)
}

if (!isLoading) {
formatData()
}
}, [isLoading, activeTick, data])
return newData
}, [data])

return {
isLoading,
isUninitialized,
isError,
error,
formattedData,
}
return useMemo(() => {
return {
isLoading,
isUninitialized,
isError,
error,
formattedData: !isLoading && !isUninitialized ? formatData() : undefined,
}
}, [isLoading, isUninitialized, isError, error, formatData])
}
11 changes: 3 additions & 8 deletions src/components/LiquidityChartRangeInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,6 @@ export default function LiquidityChartRangeInput({
category: 'Liquidity',
fatal: false,
})

if (error?.name === 'UnsupportedChainId') {
// do not show the chart container when the chain is not supported
return null
}
}

return (
Expand All @@ -142,20 +137,20 @@ export default function LiquidityChartRangeInput({
<InfoBox icon={<Loader size="40px" stroke={theme.text4} />} />
) : isError ? (
<InfoBox
message={<Trans>Subgraph data not available</Trans>}
message={<Trans>Liquidity data not available.</Trans>}
icon={<CloudOff size={56} stroke={theme.text4} />}
/>
) : !formattedData || formattedData === [] || !price ? (
<InfoBox
message={<Trans>There is no liquidity data</Trans>}
message={<Trans>There is no liquidity data.</Trans>}
icon={<BarChart2 size={56} stroke={theme.text4} />}
/>
) : (
<ChartWrapper>
<Chart
data={{ series: formattedData, current: price }}
dimensions={{ width: 400, height: 200 }}
margins={{ top: 10, right: 2, bottom: 30, left: 0 }}
margins={{ top: 10, right: 2, bottom: 20, left: 0 }}
styles={{
area: {
selection: theme.blue1,
Expand Down
72 changes: 46 additions & 26 deletions src/hooks/usePoolTickData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Currency } from '@uniswap/sdk-core'
import { FeeAmount, Pool, tickToPrice, TICK_SPACINGS } from '@uniswap/v3-sdk'
import JSBI from 'jsbi'
import { PoolState, usePool } from './usePools'
import { useEffect, useMemo, useState } from 'react'
import { useMemo } from 'react'
import computeSurroundingTicks from 'utils/computeSurroundingTicks'
import { useAllV3TicksQuery } from 'state/data/enhanced'
import { skipToken } from '@reduxjs/toolkit/query/react'
Expand Down Expand Up @@ -52,25 +52,40 @@ export function usePoolActiveLiquidity(
currencyA: Currency | undefined,
currencyB: Currency | undefined,
feeAmount: FeeAmount | undefined
) {
const [ticksProcessed, setTicksProcessed] = useState<TickProcessed[]>([])

): {
isLoading: boolean
isUninitialized: boolean
isError: boolean
error: any
activeTick: number | undefined
data: TickProcessed[] | undefined
} {
const pool = usePool(currencyA, currencyB, feeAmount)

// Find nearest valid tick for pool in case tick is not initialized.
const activeTick = useMemo(() => getActiveTick(pool[1]?.tickCurrent, feeAmount), [pool, feeAmount])

const { isLoading, isUninitialized, isError, error, ticks } = useAllV3Ticks(currencyA, currencyB, feeAmount)

useEffect(() => {
// reset local ticks processed
setTicksProcessed([])
}, [currencyA, currencyB, feeAmount])

useEffect(() => {
if (!currencyA || !currencyB || !activeTick || pool[0] !== PoolState.EXISTS || !ticks || ticks.length === 0) {
setTicksProcessed([])
return
return useMemo(() => {
if (
!currencyA ||
!currencyB ||
!activeTick ||
pool[0] !== PoolState.EXISTS ||
!ticks ||
ticks.length === 0 ||
isLoading ||
isUninitialized
) {
return {
isLoading: isLoading || pool[0] === PoolState.LOADING,
isUninitialized,
isError,
error,
activeTick,
data: undefined,
}
}

const token0 = currencyA?.wrapped
Expand All @@ -84,7 +99,14 @@ export function usePoolActiveLiquidity(
if (pivot < 0) {
// consider setting a local error
console.error('TickData pivot not found')
return
return {
isLoading,
isUninitialized,
isError,
error,
activeTick,
data: undefined,
}
}

const activeTickProcessed: TickProcessed = {
Expand All @@ -99,17 +121,15 @@ export function usePoolActiveLiquidity(

const previousTicks = computeSurroundingTicks(token0, token1, activeTickProcessed, ticks, pivot, false)

const newTicksProcessed = previousTicks.concat(activeTickProcessed).concat(subsequentTicks)
const ticksProcessed = previousTicks.concat(activeTickProcessed).concat(subsequentTicks)

setTicksProcessed(newTicksProcessed)
}, [currencyA, currencyB, activeTick, pool, ticks])

return {
isLoading: isLoading || pool[0] === PoolState.LOADING,
isUninitialized,
isError: isError,
error,
activeTick,
data: ticksProcessed,
}
return {
isLoading,
isUninitialized,
isError: isError,
error,
activeTick,
data: ticksProcessed,
}
}, [currencyA, currencyB, activeTick, pool, ticks, isLoading, isUninitialized, isError, error])
}
12 changes: 12 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3572,6 +3572,13 @@
dependencies:
"@types/lodash" "*"

"@types/lodash.inrange@^3.3.6":
version "3.3.6"
resolved "https://registry.yarnpkg.com/@types/lodash.inrange/-/lodash.inrange-3.3.6.tgz#bc2be446082069604d96ee8c30bd07317af6fcc7"
integrity sha512-lB01EnNz+7lj9IVWDZ0cUTbKnTyyyuX2elKbqtrRj0oXWm66BaILR8bwVzYu99KX21PiiwOLXeQcXw62FV88fw==
dependencies:
"@types/lodash" "*"

"@types/lodash@*", "@types/lodash@^4.14.53":
version "4.14.169"
resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.169.tgz"
Expand Down Expand Up @@ -12748,6 +12755,11 @@ lodash.includes@^4.3.0:
resolved "https://registry.yarnpkg.com/lodash.includes/-/lodash.includes-4.3.0.tgz#60bb98a87cb923c68ca1e51325483314849f553f"
integrity sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=

lodash.inrange@^3.3.6:
version "3.3.6"
resolved "https://registry.yarnpkg.com/lodash.inrange/-/lodash.inrange-3.3.6.tgz#dfdfe915f6e30e8056293707e2395dab88ea128d"
integrity sha1-39/pFfbjDoBWKTcH4jldq4jqEo0=

lodash.isboolean@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz#6c2e171db2a257cd96802fd43b01b20d5f5870f6"
Expand Down

0 comments on commit 2db29f2

Please sign in to comment.