Commit 958286c8 authored by tom's avatar tom

add spline chart and line color customization

parent 8193c7d1
import { useToken } from '@chakra-ui/react';
import React from 'react';
import ethTxsData from 'data/charts_eth_txs.json';
import ChartLine from 'ui/shared/chart/ChartLine';
import useChartSize from 'ui/shared/chart/useChartSize';
import useTimeChartController from 'ui/shared/chart/useTimeChartController';
import { BlueLinearGradient } from 'ui/shared/chart/utils/gradients';
const CHART_MARGIN = { bottom: 0, left: 0, right: 0, top: 0 };
const DATA = ethTxsData.slice(-30).map((d) => ({ ...d, date: new Date(d.date) }));
const SplineChartExample = () => {
const ref = React.useRef<SVGSVGElement>(null);
const { width, height, innerWidth, innerHeight } = useChartSize(ref.current, CHART_MARGIN);
const color = useToken('colors', 'blue.500');
const { xScale, yScale } = useTimeChartController({
data: [ { items: DATA, name: 'spline', color } ],
width: innerWidth,
height: innerHeight,
});
return (
<svg width={ width || '100%' } height={ height || '100%' } ref={ ref }>
<defs>
<BlueLinearGradient.defs/>
</defs>
<ChartLine
data={ DATA }
xScale={ xScale }
yScale={ yScale }
stroke={ `url(#${ BlueLinearGradient.id })` }
animation="left"
strokeWidth={ 3 }
/>
</svg>
);
};
export default SplineChartExample;
......@@ -2,6 +2,7 @@ import { Box, Heading } from '@chakra-ui/react';
import React from 'react';
import EthereumChart from 'ui/charts/EthereumChart';
import SplineChartExample from 'ui/charts/SplineChartExample';
import Page from 'ui/shared/Page/Page';
import PageTitle from 'ui/shared/Page/PageTitle';
......@@ -13,6 +14,10 @@ const Graph = () => {
<Box w="100%" h="400px">
<EthereumChart/>
</Box>
<Heading as="h2" size="sm" fontWeight="500" mb={ 3 } mt="100px">Ethereum Daily Transactions For Last Month</Heading>
<Box w="240px" h="150px">
<SplineChartExample/>
</Box>
</Page>
);
};
......
......@@ -6,7 +6,7 @@ import type { TimeChartItem } from 'ui/shared/chart/types';
interface Props extends React.SVGProps<SVGPathElement> {
xScale: d3.ScaleTime<number, number> | d3.ScaleLinear<number, number>;
yScale: d3.ScaleTime<number, number> | d3.ScaleLinear<number, number>;
color: string;
color?: string;
data: Array<TimeChartItem>;
disableAnimation?: boolean;
}
......@@ -28,19 +28,22 @@ const ChartArea = ({ xScale, yScale, color, data, disableAnimation, ...props }:
const area = d3.area<TimeChartItem>()
.x(({ date }) => xScale(date))
.y1(({ value }) => yScale(value))
.y0(() => yScale(yScale.domain()[0]));
.y0(() => yScale(yScale.domain()[0]))
.curve(d3.curveNatural);
return area(data) || undefined;
}, [ xScale, yScale, data ]);
return (
<>
<path ref={ ref } d={ d } fill={ `url(#gradient-${ color })` } opacity={ 0 } { ...props }/>
<defs>
<linearGradient id={ `gradient-${ color }` } x1="0%" x2="0%" y1="0%" y2="100%">
<stop offset="0%" stopColor={ color } stopOpacity={ 1 }/>
<stop offset="100%" stopColor={ color } stopOpacity={ 0.15 }/>
</linearGradient>
</defs>
<path ref={ ref } d={ d } fill={ color ? `url(#gradient-${ color })` : 'none' } opacity={ 0 } { ...props }/>
{ color && (
<defs>
<linearGradient id={ `gradient-${ color }` } x1="0%" x2="0%" y1="0%" y2="100%">
<stop offset="0%" stopColor={ color } stopOpacity={ 0.8 }/>
<stop offset="100%" stopColor={ color } stopOpacity={ 0.02 }/>
</linearGradient>
</defs>
) }
</>
);
};
......
......@@ -61,7 +61,8 @@ const ChartLine = ({ xScale, yScale, data, animation, ...props }: Props) => {
const line = d3.line<TimeChartItem>()
.x((d) => xScale(d.date))
.y((d) => yScale(d.value));
.y((d) => yScale(d.value))
.curve(d3.curveNatural);
return (
<path
......
......@@ -13,7 +13,7 @@ export interface ChartMargin {
export interface TimeChartDataItem {
items: Array<TimeChartItem>;
name: string;
color: string;
color?: string;
}
export type TimeChartData = Array<TimeChartDataItem>;
import React from 'react';
export const BlueLinearGradient = {
id: 'blue-linear-gradient',
defs: () => (
<linearGradient id="blue-linear-gradient">
<stop offset="0%" stopColor="#4299E1"/>
<stop offset="100%" stopColor="#00B5D8"/>
</linearGradient>
),
};
export const RainbowGradient = {
id: 'rainbow-gradient',
defs: () => (
<linearGradient id="rainbow-gradient">
<stop offset="0%" stopColor="rgba(255, 0, 0, 1)"/>
<stop offset="10%" stopColor="rgba(255, 154, 0, 1)"/>
<stop offset="20%" stopColor="rgba(208, 222, 33, 1)"/>
<stop offset="30%" stopColor="rgba(79, 220, 74, 1)"/>
<stop offset="40%" stopColor="rgba(63, 218, 216, 1)"/>
<stop offset="50%" stopColor="rgba(47, 201, 226, 1)"/>
<stop offset="60%" stopColor="rgba(28, 127, 238, 1)"/>
<stop offset="70%" stopColor="rgba(95, 21, 242, 1)"/>
<stop offset="80%" stopColor="rgba(186, 12, 248, 1)"/>
<stop offset="90%" stopColor="rgba(251, 7, 217, 1)"/>
<stop offset="100%" stopColor="rgba(255, 0, 0, 1)"/>
</linearGradient>
),
};
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