diff --git a/packages/web/src/components/common/pool-selection-graph/PoolSelectionGraph.tsx b/packages/web/src/components/common/pool-selection-graph/PoolSelectionGraph.tsx index ca961dd43..9d833f626 100644 --- a/packages/web/src/components/common/pool-selection-graph/PoolSelectionGraph.tsx +++ b/packages/web/src/components/common/pool-selection-graph/PoolSelectionGraph.tsx @@ -1,28 +1,42 @@ +import { useTheme } from "@emotion/react"; +import BigNumber from "bignumber.js"; +import * as d3 from "d3"; import React, { useEffect, useMemo, useRef, useState } from "react"; +import * as uuid from "uuid"; import { EventBlocker, PoolSelectionGraphTooltipWrapper, PoolSelectionGraphWrapper, } from "./PoolSelectionGraph.styles"; -import * as d3 from "d3"; + +import { + SwapFeeTierMaxPriceRangeMap, + SwapFeeTierType, +} from "@constants/option.constant"; +import { useColorGraph } from "@hooks/common/use-color-graph"; +import { FloatingPosition } from "@hooks/common/use-floating-tooltip"; import { PoolBinModel } from "@models/pool/pool-bin-model"; import { TokenModel } from "@models/token/token-model"; -import { useColorGraph } from "@hooks/common/use-color-graph"; +import { convertToKMB } from "@utils/stake-position-utils"; +import { displayTickNumber } from "@utils/string-utils"; import { priceToTick, tickToPrice, tickToPriceStr } from "@utils/swap-utils"; + import FloatingTooltip from "../tooltip/FloatingTooltip"; -import { FloatingPosition } from "@hooks/common/use-floating-tooltip"; -import { convertToKMB } from "@utils/stake-position-utils"; import { PoolSelectionGraphBinTooptip, TooltipInfo, } from "./PoolSelectionGraphBinTooltip"; -import { useTheme } from "@emotion/react"; -import BigNumber from "bignumber.js"; -import { displayTickNumber } from "@utils/string-utils"; -import { - SwapFeeTierMaxPriceRangeMap, - SwapFeeTierType, -} from "@constants/option.constant"; + +interface SelectionColor { + startPercent: string; + endPercent: string; + start: string; + end: string; + lineStart: string; + lineEnd: string; + badgeStart: string; + badgeEnd: string; +} interface ResolveBinModel { index: number; @@ -95,6 +109,8 @@ const PoolSelectionGraph: React.FC = ({ onFinishMove, }) => { const { themeKey } = useTheme(); + const graphIdRef = useRef(uuid.v4()); + const graphId = graphIdRef.current.toString(); const svgRef = useRef(null); const chartRef = useRef(null); const brushRef = useRef(null); @@ -110,7 +126,7 @@ const PoolSelectionGraph: React.FC = ({ const { redColor, greenColor } = useColorGraph(); - const [selectionColor, setSelectionColor] = useState( + const [selectionColor, setSelectionColor] = useState( getSelectionColor("0", "0"), ); @@ -250,7 +266,6 @@ const PoolSelectionGraph: React.FC = ({ } return `${isStart ? "right" : "left"}`; }, [width, height, positionX, positionY, position]); - const random = Math.random().toString(); const minBrushX = scaleX(swapFeeTierMaxPriceRange.minTick - graphMinTick) >= -20 @@ -355,12 +370,14 @@ const PoolSelectionGraph: React.FC = ({ ); } - function onBrushEnd(this: SVGGElement, event: d3.D3BrushEvent) { + function onBrushEnd(this: SVGGElement, event: d3.D3BrushEvent) { if (!brushRef.current || event.mode === undefined) { return; } - onFinishMove && onFinishMove(); + if (!!onFinishMove) { + onFinishMove(); + } if (fullRange) { setMinPrice(null); setMaxPrice(null); @@ -441,9 +458,9 @@ const PoolSelectionGraph: React.FC = ({ return themeKey === "dark" ? "#1C2230" : "#E0E8F4"; } if (Number(bin.maxTick) - 5 < currentTick) { - return `url(#gradient-bar-green-${random})`; + return `url(#gradient-bar-green-${graphId})`; } - return `url(#gradient-bar-red-${random})`; + return `url(#gradient-bar-red-${graphId})`; } // Clean child elements. @@ -687,14 +704,6 @@ const PoolSelectionGraph: React.FC = ({ .on("mousemove", onMouseoverChartBin) .on("mouseout", onMouseoutChartBin); - svgElement - .append("defs") - .append("clipPath") - .attr("id", "clip") - .append("rect") - .attr("width", width) - .attr("height", height); - const defElement = svgElement.select("defs"); const existClipPath = defElement.select("clipPath").empty(); @@ -710,7 +719,7 @@ const PoolSelectionGraph: React.FC = ({ if (!!width && !!height && !!scaleX && !!scaleY) { updateChart(); } - }, [width, height, scaleX, scaleY]); + }, [width, height, svgRef?.current, chartRef?.current, resolvedDisplayBins]); // Brush settings, on currentPrice change, zoom, move ... useEffect(() => { @@ -794,7 +803,7 @@ const PoolSelectionGraph: React.FC = ({ = ({ { }; function makeLeftBadge( - refer: d3.Selection, + refer: d3.Selection, reverse = false, - selectionColor: any, + selectionColor: SelectionColor, ) { const badge = refer .append("svg") @@ -936,9 +945,9 @@ function makeLeftBadge( } function makeRightBadge( - refer: d3.Selection, + refer: d3.Selection, reverse = false, - selectionColor: any, + selectionColor: SelectionColor, ) { const badge = refer .append("svg") @@ -974,10 +983,10 @@ function makeRightBadge( } function makeLabel( - refer: d3.Selection, + refer: d3.Selection, right = false, reverse = false, - selectionColor: any, + selectionColor: SelectionColor, ) { const id = right === false ? "start-price" : "end-price"; const color = @@ -1007,13 +1016,13 @@ function makeLabel( } function changeLine( - selectionElement: d3.Selection, + selectionElement: d3.Selection, type: "start" | "end", x: number, rate: number, right = false, selectedFullRange = false, - selectionColor: any, + selectionColor: SelectionColor, ) { const hidden = type === "end" && selectedFullRange === true; const rateStr = `${rate > 0 ? "+" : ""}${Math.round(rate).toFixed(0)}%`;