Skip to content

Commit

Permalink
feat: update basin chart
Browse files Browse the repository at this point in the history
  • Loading branch information
Space-Bean committed Jul 11, 2024
1 parent e5534a8 commit 7d68ca0
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 36 deletions.
91 changes: 63 additions & 28 deletions projects/dex-ui/src/components/Well/Chart/Chart.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,45 @@
import React, { useEffect, useMemo, useState } from "react";
import { FC } from "src/types";
import { ChartContainer } from "./ChartStyles";
import { createChart } from "lightweight-charts";
import { createChart, IChartApi, ISeriesApi, Time } from "lightweight-charts";
import { useRef } from "react";
import styled from "styled-components";
import { IChartDataItem } from "./ChartSection";

type Props = {
legend: string;
data: IChartDataItem[];
refetching?: boolean;
};

type ChartData = {
value: number;
time: Time;
};

function formatToUSD(value: any) {
const formattedValue = Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(value);
const formattedValue = Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(
value
);
return formattedValue;
}

export const Chart: FC<Props> = ({ legend, data: _data }) => {
function mapChartData(data: IChartDataItem[]) {
return data.map(({ time, value }) => ({
time: time as Time,
value: parseFloat(value)
}));
}

export const Chart: FC<Props> = ({ legend, data: _data, refetching }) => {
const chartContainerRef = useRef<any>();
const chart = useRef<any>();
const lineSeries = useRef<any>();
const [lastDataPoint, setLastDataPoint] = useState<any>();
const chart = useRef<IChartApi>();
const lineSeries = useRef<ISeriesApi<"Line">>();
const [lastDataPoint, setLastDataPoint] = useState<ChartData | null>(null);
const [dataPoint, setDataPoint] = useState<any>();
const [dataPointValue, setDataPointValue] = useState<any>();

const data = useMemo(() => {
return _data.map(({ time, value }) => ({
time,
value: parseFloat(value)
}));
}, [_data]);
const data = useMemo(() => mapChartData(_data), [_data]);

useEffect(() => {
if (!chartContainerRef.current) return;
Expand All @@ -51,47 +61,72 @@ export const Chart: FC<Props> = ({ legend, data: _data }) => {
},
timeScale: {
timeVisible: true,
secondsVisible: false
secondsVisible: false,
minBarSpacing: 0.01 // allow for zooming out
}
};

const handleResize = () => {
chart.current.applyOptions({ width: chartContainerRef.current.clientWidth });
chart.current?.applyOptions({
width: chartContainerRef.current.clientWidth,
height: chartContainerRef.current.clientHeight
});
};

chart.current = createChart(chartContainerRef.current, chartOptions);
lineSeries.current = chart.current.addLineSeries({ color: "#000" });
lineSeries.current = chart.current.addLineSeries({ color: "#000", lineWidth: 2 });

window.addEventListener("resize", handleResize);

return () => {
window.removeEventListener("resize", handleResize);
chart.current.remove();
chart.current?.remove();
};
}, []);

useEffect(() => {
lineSeries.current.setData(data);
chart.current.timeScale().fitContent();
setLastDataPoint(data[data.length - 1] && data[data.length - 1].value ? data[data.length - 1].value : null);
chart.current.subscribeCrosshairMove((param: any) => setDataPoint(param.seriesData.get(lineSeries.current) || null));
lineSeries.current?.setData(data);
let lastData = null;
let firstData = null;

if (data.length) {
lastData = data[data.length - 1];
firstData = data[0];
}
if (!lastData || !firstData) {
chart.current?.timeScale().fitContent();
} else {
chart.current?.timeScale().setVisibleRange({
from: 0 as Time,
to: lastData.time
});
}

const handleSubscribeCrosshairMove = (param: any) => {
setDataPoint(param.seriesData.get(lineSeries.current) || null);
};

setLastDataPoint(lastData);
chart.current?.subscribeCrosshairMove(handleSubscribeCrosshairMove);

return () => {
chart.current.unsubscribeCrosshairMove();
chart.current?.unsubscribeCrosshairMove(handleSubscribeCrosshairMove);
};
}, [data, lastDataPoint]);
}, [data]);

useEffect(() => {
setDataPointValue(dataPoint && dataPoint.value ? dataPoint.value : null);
}, [dataPoint]);

return (
<ChartContainer ref={chartContainerRef} id="container">
<Legend>
<div>{legend}</div>
<LegendValue>{formatToUSD(dataPointValue || lastDataPoint || 0)}</LegendValue>
</Legend>
</ChartContainer>
<div>
<ChartContainer ref={chartContainerRef} id="container">
<Legend>
<div>{legend}</div>
<LegendValue>{formatToUSD(dataPointValue || lastDataPoint?.value || 0)}</LegendValue>
</Legend>
</ChartContainer>
</div>
);
};

Expand Down
38 changes: 30 additions & 8 deletions projects/dex-ui/src/components/Well/Chart/ChartSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,13 @@ const ChartSectionContent: FC<{ well: Well }> = ({ well }) => {
const [timePeriod, setTimePeriod] = useState("week");
const [dropdownButtonText, setDropdownButtonText] = useState("1 WEEK");

const { data: chartData, refetch, error, isLoading: chartDataLoading } = useWellChartData(well, timePeriod);
const {
data: chartData,
refetch,
error,
isLoading: chartDataLoading,
isRefetching
} = useWellChartData(well, timePeriod);

const [liquidityData, setLiquidityData] = useState<IChartDataItem[]>([]);
const [volumeData, setVolumeData] = useState<IChartDataItem[]>([]);
Expand Down Expand Up @@ -174,8 +180,14 @@ const ChartSectionContent: FC<{ well: Well }> = ({ well }) => {
</>
</DesktopRow>
<MobileRow>
<TabButton onClick={() => setChartTypeDrawerOpen(true)}>{tab === 0 ? "LIQUIDITY" : "VOLUME"}</TabButton>
<BottomDrawer showDrawer={isChartTypeDrawerOpen} headerText={"View Chart"} toggleDrawer={setChartTypeDrawerOpen}>
<TabButton onClick={() => setChartTypeDrawerOpen(true)}>
{tab === 0 ? "LIQUIDITY" : "VOLUME"}
</TabButton>
<BottomDrawer
showDrawer={isChartTypeDrawerOpen}
headerText={"View Chart"}
toggleDrawer={setChartTypeDrawerOpen}
>
<DrawerRow
onClick={() => {
setTab(0), setChartTypeDrawerOpen(false);
Expand All @@ -194,7 +206,11 @@ const ChartSectionContent: FC<{ well: Well }> = ({ well }) => {
<FilterButton onClick={() => setChartRangeDrawerOpen(true)}>
{dropdownButtonText} <ChevronDown width={6} />
</FilterButton>
<BottomDrawer showDrawer={isChartRangeDrawerOpen} headerText={"Time Period"} toggleDrawer={setChartRangeDrawerOpen}>
<BottomDrawer
showDrawer={isChartRangeDrawerOpen}
headerText={"Time Period"}
toggleDrawer={setChartRangeDrawerOpen}
>
<DrawerRow
onClick={() => {
setChartRange("day"), setChartRangeDrawerOpen(false);
Expand Down Expand Up @@ -235,15 +251,22 @@ const ChartSectionContent: FC<{ well: Well }> = ({ well }) => {
</ChartLoader>
) : (
<>
{tab === 0 && !error && <Chart data={liquidityData} legend={"TOTAL LIQUIDITY"} />}
{tab === 1 && !error && <Chart data={volumeData} legend={"HOURLY VOLUME"} />}
{tab === 0 && !error && (
<Chart data={liquidityData} legend={"TOTAL LIQUIDITY"} refetching={isRefetching} />
)}
{tab === 1 && !error && (
<Chart data={volumeData} legend={"HOURLY VOLUME"} refetching={isRefetching} />
)}
</>
)}
</Container>
);
};

export const ChartSection: FC<{ well: Well | undefined; loading?: boolean }> = ({ well, loading }) => {
export const ChartSection: FC<{ well: Well | undefined; loading?: boolean }> = ({
well,
loading
}) => {
if (!well || loading) {
return (
<Container id="chart-section-loading">
Expand Down Expand Up @@ -325,7 +348,6 @@ const Container = styled.div`
display: flex;
flex-direction: column;
outline: 0.5px solid #9ca3af;
outline-offset: -0.5px;
background-color: #f9f8f6;
`;

Expand Down

0 comments on commit 7d68ca0

Please sign in to comment.