Commit b1fb499e authored by Connor McEwen's avatar Connor McEwen Committed by GitHub

feat: animate in token details line chart (#4745)

* WIP

* animated in chart

* add comment

* revert env change

* comments

* merge main

* fix hard reload
parent 64207f29
import { Group } from '@visx/group'
import { LinePath } from '@visx/shape'
import { easeCubicInOut } from 'd3'
import React from 'react'
import { useEffect, useRef, useState } from 'react'
import { animated, useSpring } from 'react-spring'
import { useTheme } from 'styled-components/macro'
import { LineChartProps } from './LineChart'
const config = {
duration: 800,
easing: easeCubicInOut,
}
// code reference: https://airbnb.io/visx/lineradial
function AnimatedInLineChart<T>({
data,
getX,
getY,
marginTop,
curve,
color,
strokeWidth,
width,
height,
children,
}: LineChartProps<T>) {
const lineRef = useRef<SVGPathElement>(null)
const [lineLength, setLineLength] = useState(0)
const [shouldAnimate, setShouldAnimate] = useState(false)
const [hasAnimatedIn, setHasAnimatedIn] = useState(false)
const spring = useSpring({
frame: shouldAnimate ? 0 : 1,
config,
onRest: () => {
setShouldAnimate(false)
setHasAnimatedIn(true)
},
})
const effectDependency = lineRef.current
useEffect(() => {
if (lineRef.current) {
setLineLength(lineRef.current.getTotalLength())
setShouldAnimate(true)
}
}, [effectDependency])
const theme = useTheme()
const lineColor = color ?? theme.accentAction
return (
<svg width={width} height={height}>
<Group top={marginTop}>
<LinePath curve={curve} x={getX} y={getY}>
{({ path }) => {
const d = path(data) || ''
return (
<>
<animated.path
d={d}
ref={lineRef}
strokeWidth={strokeWidth}
strokeOpacity={hasAnimatedIn ? 1 : 0}
fill="none"
stroke={lineColor}
/>
{shouldAnimate && lineLength !== 0 && (
<animated.path
d={d}
strokeWidth={strokeWidth}
fill="none"
stroke={lineColor}
strokeDashoffset={spring.frame.to((v) => v * lineLength)}
strokeDasharray={lineLength}
/>
)}
</>
)
}}
</LinePath>
</Group>
{children}
</svg>
)
}
export default AnimatedInLineChart
......@@ -6,7 +6,7 @@ import { ReactNode } from 'react'
import { useTheme } from 'styled-components/macro'
import { Color } from 'theme/styled'
interface LineChartProps<T> {
export interface LineChartProps<T> {
data: T[]
getX: (t: T) => number
getY: (t: T) => number
......
......@@ -3,6 +3,7 @@ import { localPoint } from '@visx/event'
import { EventType } from '@visx/event/lib/types'
import { GlyphCircle } from '@visx/glyph'
import { Line } from '@visx/shape'
import AnimatedInLineChart from 'components/Charts/AnimatedInLineChart'
import { filterTimeAtom } from 'components/Tokens/state'
import {
bisect,
......@@ -32,7 +33,6 @@ import {
weekFormatter,
} from 'utils/formatChartTimes'
import LineChart from '../../Charts/LineChart'
import { MEDIUM_MEDIA_BREAKPOINT } from '../constants'
import { DISPLAYS, ORDERED_TIMES } from '../TokenTable/TimeSelector'
......@@ -288,7 +288,7 @@ export function PriceChart({ width, height, prices }: PriceChartProps) {
<ArrowCell>{arrow}</ArrowCell>
</DeltaContainer>
</ChartHeader>
<LineChart
<AnimatedInLineChart
data={prices}
getX={(p: PricePoint) => timeScale(p.timestamp)}
getY={(p: PricePoint) => rdScale(p.value)}
......@@ -357,7 +357,7 @@ export function PriceChart({ width, height, prices }: PriceChartProps) {
onMouseMove={handleHover}
onMouseLeave={resetDisplay}
/>
</LineChart>
</AnimatedInLineChart>
<TimeOptionsWrapper>
<TimeOptionsContainer>
{ORDERED_TIMES.map((time) => (
......
......@@ -4522,7 +4522,7 @@
dependencies:
"@vibrant/types" "^3.2.1-alpha.1"
"@visx/axis@^2.12.2":
"@visx/axis@2.12.2", "@visx/axis@^2.12.2":
version "2.12.2"
resolved "https://registry.yarnpkg.com/@visx/axis/-/axis-2.12.2.tgz#0aa50ae35d0cd6d8a11c59ad0d874cfeea9e3b89"
integrity sha512-nE+DGNwRzXOmp6ZwMQ1yUhbF7uR2wd3j6Xja/kVgGA7wSbqUeCZzqKZvhRsCqyay6PtHVlRRAhHP31Ob39+jtw==
......@@ -4564,6 +4564,20 @@
d3-shape "^1.2.0"
prop-types "^15.6.2"
"@visx/grid@2.12.2":
version "2.12.2"
resolved "https://registry.yarnpkg.com/@visx/grid/-/grid-2.12.2.tgz#32956dbb2ca88b24a057a7d559a46ba5e617df08"
integrity sha512-lyMQvq5afjOh0nRqF0OBjgsLfsgUeLcFc95oj0FJ/NJ/MvtI6Gd5BxxbmYzuVfZ4f0Dm1pvtBu1swoB3451tkg==
dependencies:
"@types/react" "*"
"@visx/curve" "2.1.0"
"@visx/group" "2.10.0"
"@visx/point" "2.6.0"
"@visx/scale" "2.2.2"
"@visx/shape" "2.12.2"
classnames "^2.3.1"
prop-types "^15.6.2"
"@visx/group@2.10.0", "@visx/group@^2.10.0":
version "2.10.0"
resolved "https://registry.yarnpkg.com/@visx/group/-/group-2.10.0.tgz#95839851832545621eb0d091866a61dafe552ae1"
......@@ -4578,6 +4592,19 @@
resolved "https://registry.yarnpkg.com/@visx/point/-/point-2.6.0.tgz#c4316ca409b5b829c5455f07118d8c14a92cc633"
integrity sha512-amBi7yMz4S2VSchlPdliznN41TuES64506ySI22DeKQ+mc1s1+BudlpnY90sM1EIw4xnqbKmrghTTGfy6SVqvQ==
"@visx/react-spring@^2.12.2":
version "2.12.2"
resolved "https://registry.yarnpkg.com/@visx/react-spring/-/react-spring-2.12.2.tgz#f753ead7fc62ff2541e56ea128c109601dd7a016"
integrity sha512-+Oo9S75lSbpF6VV3Ym8kB/I4H7O3qYk5Nltv2CNUoVuWvzd4tRnxiVLBxYuGjtj6lIAhDJ+W8QYHXhZhe0zNHw==
dependencies:
"@types/react" "*"
"@visx/axis" "2.12.2"
"@visx/grid" "2.12.2"
"@visx/scale" "2.2.2"
"@visx/text" "2.12.2"
classnames "^2.3.1"
prop-types "^15.6.2"
"@visx/responsive@^2.10.0":
version "2.10.0"
resolved "https://registry.yarnpkg.com/@visx/responsive/-/responsive-2.10.0.tgz#3e5c5853c7b2b33481e99a64678063cef717de0b"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment