diff --git a/package.json b/package.json index fe05e6314c..7dc43a794e 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@mui/material": "^5.10.9", "@paraswap/sdk": "6.2.4", "@tanstack/react-query": "^4.28.0", + "@visx/annotation": "^3.3.0", "@visx/axis": "^2.14.0", "@visx/curve": "^2.1.0", "@visx/event": "^2.6.0", diff --git a/src/modules/reserve-overview/graphs/ApyGraph.tsx b/src/modules/reserve-overview/graphs/ApyGraph.tsx index 00686db80a..2807fecbe7 100644 --- a/src/modules/reserve-overview/graphs/ApyGraph.tsx +++ b/src/modules/reserve-overview/graphs/ApyGraph.tsx @@ -1,4 +1,5 @@ -import { Box, Typography, useMediaQuery, useTheme } from '@mui/material'; +import { Box, Stack, Typography, useMediaQuery, useTheme } from '@mui/material'; +import { Annotation, HtmlLabel } from '@visx/annotation'; import { AxisBottom, AxisLeft } from '@visx/axis'; import { curveMonotoneX } from '@visx/curve'; import { localPoint } from '@visx/event'; @@ -10,7 +11,7 @@ import { defaultStyles, TooltipWithBounds, withTooltip } from '@visx/tooltip'; import { WithTooltipProvidedProps } from '@visx/tooltip/lib/enhancers/withTooltip'; import { bisector, extent, max } from 'd3-array'; import { timeFormat } from 'd3-time-format'; -import React, { Fragment, useCallback, useMemo } from 'react'; +import React, { Fragment, ReactNode, useCallback, useMemo } from 'react'; import { FormattedReserveHistoryItem, ReserveRateTimeRange } from 'src/hooks/useReservesHistory'; type TooltipData = FormattedReserveHistoryItem; @@ -59,6 +60,7 @@ export type AreaProps = { data: FormattedReserveHistoryItem[]; fields: { name: Field; color: string; text: string }[]; selectedTimeRange: ReserveRateTimeRange; + avgFieldName?: Field; }; export const ApyGraph = withTooltip( @@ -73,6 +75,7 @@ export const ApyGraph = withTooltip( data, fields, selectedTimeRange, + avgFieldName, }: AreaProps & WithTooltipProvidedProps) => { if (width < 10) return null; const theme = useTheme(); @@ -140,6 +143,57 @@ export const ApyGraph = withTooltip( [showTooltip, dateScale, data, margin] ); + let avgLine: ReactNode = null; + if (avgFieldName) { + const avg = data.reduce((acc, cur) => acc + cur[avgFieldName], 0) / data.length; + if (avg > 0) { + const avgFormatted = (avg * 100).toFixed(2); + const avgArray = data.map((d) => { + return { + ...d, + [avgFieldName]: avg, + }; + }); + + const annotationX = (dateScale(getDate(avgArray[0])) ?? 0) + 70; + const annotationY = (yValueScale(getData(avgArray[0], avgFieldName)) ?? 0) - 8; + + avgLine = ( + <> + dateScale(getDate(d)) ?? 0} + y={(d) => yValueScale(getData(d, avgFieldName)) ?? 0} + /> + + + + + Avg {avgFormatted}% + + + + + + ); + } + } + return ( <> @@ -167,6 +221,8 @@ export const ApyGraph = withTooltip( /> ))} + {avgLine} + {/* X Axis */} )} diff --git a/yarn.lock b/yarn.lock index fdb0d54e04..4d4fce3494 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3767,6 +3767,19 @@ "@typescript-eslint/types" "5.46.0" eslint-visitor-keys "^3.3.0" +"@visx/annotation@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@visx/annotation/-/annotation-3.3.0.tgz#2297ed3ea30ec334ced586cff014a69ec7e843b9" + integrity sha512-v0htpd/sT1kdU1N7frqmj078UByJXUwPQJT9LENv0ypssjGyRgvZERjkgSUuMKMjZquOBs/f6XOzxF4mLV57sA== + dependencies: + "@types/react" "*" + "@visx/drag" "3.3.0" + "@visx/group" "3.3.0" + "@visx/text" "3.3.0" + classnames "^2.3.1" + prop-types "^15.5.10" + react-use-measure "^2.0.4" + "@visx/axis@^2.14.0": version "2.14.0" resolved "https://registry.yarnpkg.com/@visx/axis/-/axis-2.14.0.tgz#4fe3bf42c20aae599dc94ef5387dfcb1ba3a85ea" @@ -3798,6 +3811,24 @@ "@types/d3-shape" "^1.3.1" d3-shape "^1.0.6" +"@visx/drag@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@visx/drag/-/drag-3.3.0.tgz#d44a9f7409c9da468ae37ef9bf30899144da7720" + integrity sha512-fLNsorq6GyANCqAE/dToG0q7YoGVxihGC9FZQUp0MCV1wMJIJ45ximhrl5NDng2ytbpWnBmXu8M8hdsdFuvIXw== + dependencies: + "@types/react" "*" + "@visx/event" "3.3.0" + "@visx/point" "3.3.0" + prop-types "^15.5.10" + +"@visx/event@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@visx/event/-/event-3.3.0.tgz#30bb7f02857800749219e4ba76fce53df4d47353" + integrity sha512-fKalbNgNz2ooVOTXhvcOx5IlEQDgVfX66rI7bgZhBxI2/scy+5rWcXJXpwkheRF68SMx9R93SjKW6tmiD0h+jA== + dependencies: + "@types/react" "*" + "@visx/point" "3.3.0" + "@visx/event@^2.6.0": version "2.6.0" resolved "https://registry.npmjs.org/@visx/event/-/event-2.6.0.tgz" @@ -3837,6 +3868,15 @@ classnames "^2.3.1" prop-types "^15.6.2" +"@visx/group@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@visx/group/-/group-3.3.0.tgz#20c1b75c1ab31798c3c702b6f58c412c688a6373" + integrity sha512-yKepDKwJqlzvnvPS0yDuW13XNrYJE4xzT6xM7J++441nu6IybWWwextyap8ey+kU651cYDb+q1Oi6aHvQwyEyw== + dependencies: + "@types/react" "*" + classnames "^2.3.1" + prop-types "^15.6.2" + "@visx/legend@^2.10.0": version "2.10.0" resolved "https://registry.yarnpkg.com/@visx/legend/-/legend-2.10.0.tgz#d561f86e4bc536f9d50e21d607e65f05640f73d5" @@ -3853,6 +3893,11 @@ resolved "https://registry.npmjs.org/@visx/point/-/point-2.6.0.tgz" integrity sha512-amBi7yMz4S2VSchlPdliznN41TuES64506ySI22DeKQ+mc1s1+BudlpnY90sM1EIw4xnqbKmrghTTGfy6SVqvQ== +"@visx/point@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@visx/point/-/point-3.3.0.tgz#7a705e09892ae45b4c9cf3155e9be3a3845460d8" + integrity sha512-03eBBIJarkmX79WbeEGTUZwmS5/MUuabbiM9KfkGS9pETBTWkp1DZtEHZdp5z34x5TDQVLSi0rk1Plg3/8RtDg== + "@visx/responsive@^2.10.0": version "2.10.0" resolved "https://registry.yarnpkg.com/@visx/responsive/-/responsive-2.10.0.tgz#3e5c5853c7b2b33481e99a64678063cef717de0b" @@ -3906,6 +3951,18 @@ prop-types "^15.7.2" reduce-css-calc "^1.3.0" +"@visx/text@3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@visx/text/-/text-3.3.0.tgz#f53366a9c18bc448c6b8869527c0f75c9591e7a7" + integrity sha512-fOimcsf0GtQE9whM5MdA/xIkHMaV29z7qNqNXysUDE8znSMKsN+ott7kSg2ljAEE89CQo3WKHkPNettoVsa84w== + dependencies: + "@types/lodash" "^4.14.172" + "@types/react" "*" + classnames "^2.3.1" + lodash "^4.17.21" + prop-types "^15.7.2" + reduce-css-calc "^1.3.0" + "@visx/tooltip@^2.16.0": version "2.16.0" resolved "https://registry.yarnpkg.com/@visx/tooltip/-/tooltip-2.16.0.tgz#b88caf9cd91c50c98b6ed60e59323060b77a28a2"