Commit 1b86a74e authored by Yuri Mikhin's avatar Yuri Mikhin Committed by Yuri Mikhin

Improve Stats page layout.

parent 7886d41a
......@@ -15,7 +15,7 @@ interface Props {
caption?: string;
}
const CHART_MARGIN = { bottom: 0, left: 10, right: 10, top: 0 };
const CHART_MARGIN = { bottom: 5, left: 10, right: 10, top: 0 };
const ChainIndicatorChart = ({ data }: Props) => {
const ref = React.useRef<SVGSVGElement>(null);
......
......@@ -14,7 +14,7 @@ interface Props extends Omit<React.SVGProps<SVGGElement>, 'scale'> {
const ChartAxis = ({ type, scale, ticks, tickFormat, disableAnimation, anchorEl, ...props }: Props) => {
const ref = React.useRef<SVGGElement>(null);
const textColorToken = useColorModeValue('blackAlpha.500', 'whiteAlpha.500');
const textColorToken = useColorModeValue('blackAlpha.600', 'whiteAlpha.500');
const textColor = useToken('colors', textColorToken);
React.useEffect(() => {
......
......@@ -13,7 +13,7 @@ interface Props extends Omit<React.SVGProps<SVGGElement>, 'scale'> {
const ChartGridLine = ({ type, scale, ticks, size, disableAnimation, ...props }: Props) => {
const ref = React.useRef<SVGGElement>(null);
const strokeColorToken = useColorModeValue('blackAlpha.300', 'whiteAlpha.300');
const strokeColorToken = useColorModeValue('blackAlpha.200', 'whiteAlpha.200');
const strokeColor = useToken('colors', strokeColorToken);
React.useEffect(() => {
......
import { Box, Grid, Heading, Icon, IconButton, Menu, MenuButton, MenuItem, MenuList, Text, useColorModeValue, VisuallyHidden } from '@chakra-ui/react';
import { Box, Grid, Icon, IconButton, Menu, MenuButton, MenuItem, MenuList, Text, Tooltip, useColorModeValue, VisuallyHidden } from '@chakra-ui/react';
import React, { useCallback, useState } from 'react';
import type { TimeChartItem } from './types';
......@@ -21,7 +21,6 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
const [ isFullscreen, setIsFullscreen ] = useState(false);
const [ isZoomResetInitial, setIsZoomResetInitial ] = React.useState(true);
const menuButtonColor = useColorModeValue('black', 'white');
const borderColor = useColorModeValue('gray.200', 'gray.600');
const handleZoom = useCallback(() => {
......@@ -56,7 +55,7 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
return (
<>
<Box
padding={{ base: 3, md: 4 }}
padding={{ base: 3, lg: 4 }}
borderRadius="md"
border="1px"
borderColor={ borderColor }
......@@ -65,12 +64,15 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
gridTemplateColumns="auto auto 36px"
gridColumnGap={ 2 }
>
<Heading
mb={ 1 }
size={{ base: 'xs', md: 'sm' }}
<Text
fontWeight={ 600 }
fontSize="md"
lineHeight={ 6 }
as="p"
size={{ base: 'xs', lg: 'sm' }}
>
{ title }
</Heading>
</Text>
<Text
mb={ 1 }
......@@ -82,10 +84,10 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
{ description }
</Text>
<Tooltip label="Reset zoom">
<IconButton
hidden={ isZoomResetInitial }
aria-label="Reset zoom"
title="Reset zoom"
colorScheme="blue"
w={ 9 }
h={ 8 }
......@@ -94,10 +96,11 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
alignSelf="top"
gridRow="1/3"
size="sm"
variant="ghost"
variant="outline"
onClick={ handleZoomResetClick }
icon={ <Icon as={ repeatArrow } w={ 4 } h={ 4 } color="blue.700"/> }
icon={ <Icon as={ repeatArrow } w={ 4 } h={ 4 }/> }
/>
</Tooltip>
<Menu>
<MenuButton
......@@ -106,8 +109,9 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
justifySelf="end"
w="36px"
h="32px"
icon={ <Icon as={ dotsIcon } w={ 4 } h={ 4 } color={ menuButtonColor }/> }
colorScheme="transparent"
icon={ <Icon as={ dotsIcon } w={ 4 } h={ 4 }/> }
colorScheme="gray"
variant="ghost"
as={ IconButton }
>
<VisuallyHidden>
......@@ -132,6 +136,7 @@ const ChartWidget = ({ items, title, description, isLoading }: Props) => {
isOpen={ isFullscreen }
items={ items }
title={ title }
description={ description }
onClose={ clearFullscreenChart }
/>
</>
......
......@@ -15,20 +15,21 @@ import useChartSize from 'ui/shared/chart/useChartSize';
import useTimeChartController from 'ui/shared/chart/useTimeChartController';
interface Props {
isEnlarged?: boolean;
title: string;
items: Array<TimeChartItem>;
onZoom: () => void;
isZoomResetInitial: boolean;
}
const CHART_MARGIN = { bottom: 20, left: 52, right: 30, top: 10 };
const CHART_MARGIN = { bottom: 20, left: 30, right: 20, top: 10 };
const ChartWidgetGraph = ({ items, onZoom, isZoomResetInitial, title }: Props) => {
const ChartWidgetGraph = ({ isEnlarged, items, onZoom, isZoomResetInitial, title }: Props) => {
const isMobile = useIsMobile();
const ref = React.useRef<SVGSVGElement>(null);
const color = useToken('colors', 'blue.200');
const overlayRef = React.useRef<SVGRectElement>(null);
const chartId = useMemo(() => `chart-${ crypto.randomUUID() }`, []);
const chartId = useMemo(() => `chart-${ title.split(' ').join('') }`, [ title ]);
const [ range, setRange ] = React.useState<[ number, number ]>([ 0, Infinity ]);
const { innerWidth, innerHeight } = useChartSize(ref.current, CHART_MARGIN);
......@@ -60,7 +61,7 @@ const ChartWidgetGraph = ({ items, onZoom, isZoomResetInitial, title }: Props) =
<ChartGridLine
type="horizontal"
scale={ yScale }
ticks={ 3 }
ticks={ isEnlarged ? 6 : 3 }
size={ innerWidth }
disableAnimation
/>
......@@ -79,27 +80,27 @@ const ChartWidgetGraph = ({ items, onZoom, isZoomResetInitial, title }: Props) =
yScale={ yScale }
stroke={ color }
animation="none"
strokeWidth={ 3 }
strokeWidth={ isMobile ? 1 : 2 }
/>
<ChartAxis
type="left"
scale={ yScale }
ticks={ 5 }
ticks={ isEnlarged ? 6 : 3 }
tickFormat={ yTickFormat }
disableAnimation
/>
<ChartOverlay ref={ overlayRef } width={ innerWidth } height={ innerHeight }>
<ChartAxis
type="bottom"
scale={ xScale }
transform={ `translate(0, ${ innerHeight })` }
ticks={ isMobile ? 1 : 3 }
ticks={ isMobile ? 1 : 4 }
anchorEl={ overlayRef.current }
disableAnimation
/>
<ChartOverlay ref={ overlayRef } width={ innerWidth } height={ innerHeight }>
<ChartTooltip
chartId={ chartId }
anchorEl={ overlayRef.current }
......
......@@ -5,7 +5,7 @@ const ChartWidgetSkeleton = () => {
return (
<Box
height="235px"
paddingY={{ base: 3, md: 4 }}
paddingY={{ base: 3, lg: 4 }}
>
<Skeleton w="75%" h="24px" mb={ 1 }/>
<Skeleton w="50%" h="18px" mb={ 5 }/>
......
import { Button, Flex, Heading, Modal, ModalBody, ModalCloseButton, ModalContent, ModalHeader, ModalOverlay } from '@chakra-ui/react';
import { Box, Button, Grid, Heading, Icon, Modal, ModalBody, ModalCloseButton, ModalContent, ModalOverlay, Text } from '@chakra-ui/react';
import React, { useCallback } from 'react';
import type { TimeChartItem } from './types';
import repeatArrow from 'icons/repeat_arrow.svg';
import ChartWidgetGraph from './ChartWidgetGraph';
type Props = {
isOpen: boolean;
title: string;
description: string;
items: Array<TimeChartItem>;
onClose: () => void;
}
......@@ -15,6 +18,7 @@ type Props = {
const FullscreenChartModal = ({
isOpen,
title,
description,
items,
onClose,
}: Props) => {
......@@ -39,44 +43,53 @@ const FullscreenChartModal = ({
<ModalContent>
<ModalHeader>
<Flex
alignItems="center"
<Box
mb={ 1 }
>
<Grid
gridColumnGap={ 2 }
>
<Heading
as="h2"
gridColumn={ 2 }
fontSize={{ base: '2xl', sm: '3xl' }}
fontWeight="medium"
lineHeight={ 1 }
color="blue.600"
mb={ 1 }
size={{ base: 'xs', sm: 'md' }}
>
{ title }
</Heading>
<Text
gridColumn={ 1 }
as="p"
variant="secondary"
fontSize="xs"
>
{ description }
</Text>
{ !isZoomResetInitial && (
<Button
ml="auto"
leftIcon={ <Icon as={ repeatArrow } w={ 4 } h={ 4 }/> }
colorScheme="blue"
gridColumn={ 2 }
justifySelf="end"
alignSelf="top"
gridRow="1/3"
size="md"
size="sm"
variant="outline"
onClick={ handleZoomResetClick }
>
Reset zoom
</Button>
) }
</Flex>
</ModalHeader>
</Grid>
</Box>
<ModalCloseButton/>
<ModalBody
h="75%"
h="100%"
>
<ChartWidgetGraph
isEnlarged
items={ items }
onZoom={ handleZoom }
isZoomResetInitial={ isZoomResetInitial }
......
......@@ -37,7 +37,8 @@ export default function useTimeChartController({ data, width, height }: Props) {
);
const yScale = useMemo(() => {
const indention = (yMax - yMin) * 0.3;
const indention = (yMax - yMin) * 0.15;
return d3.scaleLinear()
.domain([ yMin >= 0 && yMin - indention <= 0 ? 0 : yMin - indention, yMax + indention ])
.range([ height, 0 ]);
......
......@@ -10,7 +10,8 @@ const NumberWidget = ({ label, value }: Props) => {
return (
<Box
bg={ useColorModeValue('blue.50', 'blue.800') }
p={ 3 }
px={ 3 }
py={{ base: 2, lg: 3 }}
borderRadius={ 12 }
>
<Text
......
......@@ -10,7 +10,7 @@ import useFetch from 'lib/hooks/useFetch';
import NumberWidget from './NumberWidget';
import NumberWidgetSkeleton from './NumberWidgetSkeleton';
const skeletonsCount = 5;
const skeletonsCount = 8;
const NumberWidgetsList = () => {
const fetch = useFetch();
......
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