Skip to content

Commit

Permalink
Merge pull request #60 from QuickSwap/feature/update-analytics-charts
Browse files Browse the repository at this point in the history
Update charts on analytics page
  • Loading branch information
totop716 authored Jan 28, 2022
2 parents 40f292c + 420bac4 commit 95ea8ab
Show file tree
Hide file tree
Showing 17 changed files with 1,009 additions and 838 deletions.
2 changes: 1 addition & 1 deletion src/apollo/queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ const PairFields = `
export const PAIRS_CURRENT: any = (count: number) => {
const queryString = `
query pairs {
pairs(first: ${count}, orderBy: reserveUSD, orderDirection: desc) {
pairs(first: ${count}, orderBy: trackedReserveETH, orderDirection: desc) {
id
}
}`;
Expand Down
2 changes: 1 addition & 1 deletion src/components/BarChart/BarChart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const BarChart: React.FC<BarChartProps> = ({
key={index}
className={classes.barChartItem}
width={`calc(${100 / data.length}% - 2px)`}
height={(value / maxValue) * height}
height={`${Math.max(6, (value / maxValue) * height)}px`} // set min height of bar to 6px for the items with small amount
onMouseOver={() => onHover && onHover(index)}
/>
))}
Expand Down
52 changes: 52 additions & 0 deletions src/components/ChartType/ChartType.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React from 'react';
import { Box, Typography } from '@material-ui/core';
import { makeStyles, useTheme } from '@material-ui/core/styles';

const useStyles = makeStyles(({ palette }) => ({
chartType: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: 20,
padding: '0 8px',
borderRadius: 10,
cursor: 'pointer',
'& span': {
color: palette.text.primary,
},
},
}));

interface ChartTypeProps {
typeTexts: string[];
chartTypes: number[];
chartType: number;
setChartType: (chartType: number) => void;
}

const ChartType: React.FC<ChartTypeProps> = ({
typeTexts,
chartTypes,
chartType,
setChartType,
}) => {
const classes = useStyles();
const { palette } = useTheme();

return (
<Box display='flex' alignItems='center'>
{chartTypes.map((value, index) => (
<Box
key={index}
className={classes.chartType}
bgcolor={chartType === value ? palette.grey.A400 : 'transparent'}
onClick={() => setChartType(value)}
>
<Typography variant='caption'>{typeTexts[index]}</Typography>
</Box>
))}
</Box>
);
};

export default ChartType;
1 change: 1 addition & 0 deletions src/components/ChartType/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ChartType';
1 change: 1 addition & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export { default as Footer } from './Footer';
export { default as ListLogo } from './ListLogo';
export { default as AreaChart } from './AreaChart';
export { default as BarChart } from './BarChart';
export { default as ChartType } from './ChartType';
export { default as ColoredSlider } from './ColoredSlider';
export { default as CustomTooltip } from './CustomTooltip';
export { default as ToggleSwitch } from './ToggleSwitch';
Expand Down
18 changes: 18 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,14 @@ export const GlobalConst = {
DEFAULT_TOKEN_LIST_URL:
'https://unpkg.com/[email protected]/build/quickswap-default.tokenlist.json',
},
analyticChart: {
ONE_MONTH_CHART: 1,
THREE_MONTH_CHART: 2,
SIX_MONTH_CHART: 3,
ONE_YEAR_CHART: 4,
ALL_CHART: 5,
CHART_COUNT: 60, //limit analytics chart items not more than 60
},
farmIndex: {
LPFARM_INDEX: 0,
DUALFARM_INDEX: 1,
Expand Down Expand Up @@ -212,6 +220,16 @@ export const GlobalData = {
[ChainId.MUMBAI]: undefined,
},
},
analytics: {
CHART_DURATIONS: [
GlobalConst.analyticChart.ONE_MONTH_CHART,
GlobalConst.analyticChart.THREE_MONTH_CHART,
GlobalConst.analyticChart.SIX_MONTH_CHART,
GlobalConst.analyticChart.ONE_YEAR_CHART,
GlobalConst.analyticChart.ALL_CHART,
],
CHART_DURATION_TEXTS: ['1M', '3M', '6M', '1Y', 'All'],
},
};

export const GlobalValue = {
Expand Down
142 changes: 142 additions & 0 deletions src/pages/AnalyticsPage/AnalyticsLiquidityChart.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import React, { useEffect, useState, useMemo } from 'react';
import { Box, Typography } from '@material-ui/core';
import { useTheme } from '@material-ui/core/styles';
import Skeleton from '@material-ui/lab/Skeleton';
import moment from 'moment';
import { useGlobalData } from 'state/application/hooks';
import {
formatCompact,
getChartData,
getPriceColor,
getChartDates,
getChartStartTime,
getLimitedData,
} from 'utils';
import { GlobalConst, GlobalData } from 'constants/index';
import { AreaChart, ChartType } from 'components';

const AnalyticsLiquidityChart: React.FC = () => {
const { palette } = useTheme();
const { globalData } = useGlobalData();
const [durationIndex, setDurationIndex] = useState(
GlobalConst.analyticChart.ONE_MONTH_CHART,
);
const [globalChartData, updateGlobalChartData] = useState<any[] | null>(null);

useEffect(() => {
const fetchChartData = async () => {
updateGlobalChartData(null);
const [newChartData] = await getChartData(
durationIndex === GlobalConst.analyticChart.ALL_CHART
? 0
: getChartStartTime(durationIndex),
);
if (newChartData) {
const chartData = getLimitedData(
newChartData,
GlobalConst.analyticChart.CHART_COUNT,
);
updateGlobalChartData(chartData);
}
};
fetchChartData();
}, [updateGlobalChartData, durationIndex]);

const liquidityPercentColor = getPriceColor(
globalData ? Number(globalData.liquidityChangeUSD) : 0,
palette,
);

const yAxisValues = useMemo(() => {
if (globalChartData) {
const dailyVolumes: number[] = globalChartData.map((value: any) =>
Number(value.totalLiquidityUSD),
);
// this is for defining the scale for the liquidity values to present in graph. Liquidity values are more than 100M so set the min and max amount with rounding after dividing into 20000000 to show all liquidity values into the graph
const minVolume =
Math.floor(Math.min(...dailyVolumes) / 20000000) * 20000000;
const maxVolume =
Math.ceil(Math.max(...dailyVolumes) / 20000000) * 20000000;
const values = [];
// show 10 values in the y axis of the graph
const step = (maxVolume - minVolume) / 10;
for (let i = maxVolume; i >= minVolume; i -= step) {
values.push(i);
}
return values;
} else {
return undefined;
}
}, [globalChartData]);

return (
<>
<Box display='flex' justifyContent='space-between'>
<Typography
variant='caption'
style={{ color: palette.text.disabled, fontWeight: 'bold' }}
>
LIQUIDITY
</Typography>
<ChartType
typeTexts={GlobalData.analytics.CHART_DURATION_TEXTS}
chartTypes={GlobalData.analytics.CHART_DURATIONS}
chartType={durationIndex}
setChartType={setDurationIndex}
/>
</Box>
{globalData ? (
<Box mt={0.5} display='flex' alignItems='center'>
<Typography variant='h5' style={{ color: palette.text.primary }}>
${formatCompact(globalData.totalLiquidityUSD)}
</Typography>
<Box
ml={1}
height={23}
px={1}
borderRadius={40}
bgcolor={liquidityPercentColor.bgColor}
color={liquidityPercentColor.textColor}
>
<Typography variant='caption'>
{`${globalData.liquidityChangeUSD > 0 ? '+' : ''}
${globalData.liquidityChangeUSD.toLocaleString()}`}
%
</Typography>
</Box>
</Box>
) : (
<Box my={0.5}>
<Skeleton variant='rect' width='100%' height={24} />
</Box>
)}
<Box>
<Typography style={{ color: palette.text.disabled }} variant='caption'>
{moment().format('MMM DD, YYYY')}
</Typography>
</Box>
<Box mt={2}>
{globalChartData ? (
<AreaChart
data={globalChartData.map((value: any) =>
Number(value.totalLiquidityUSD),
)}
yAxisValues={yAxisValues}
dates={globalChartData.map((value: any) =>
moment(value.date * 1000)
.add(1, 'day')
.unix(),
)}
width='100%'
height={250}
categories={getChartDates(globalChartData, durationIndex)}
/>
) : (
<Skeleton variant='rect' width='100%' height={223} />
)}
</Box>
</>
);
};

export default AnalyticsLiquidityChart;
Loading

0 comments on commit 95ea8ab

Please sign in to comment.