-
Notifications
You must be signed in to change notification settings - Fork 267
Expand file tree
/
Copy pathLineChart.tsx
More file actions
109 lines (94 loc) · 3.14 KB
/
Copy pathLineChart.tsx
File metadata and controls
109 lines (94 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { alpha, useTheme } from '@mui/material';
import { SparkLineChart, type SparkLineChartProps } from '@mui/x-charts';
import { areaElementClasses } from '@mui/x-charts/LineChart';
import BigNumber from 'bignumber.js';
import JSONbig from 'json-bigint';
import React, { useMemo, memo } from 'react';
import styled from 'styled-components';
import Color from '../../constants/Color';
const StyledGraphContainer = styled.div<{ height: number }>`
position: relative;
min-height: 80px;
height: ${({ height }) => `${height}px`};
`;
function LinearGradient({ chartColor }: { chartColor: string }) {
return (
<defs>
<linearGradient id="graph-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" stopColor={alpha(chartColor, 0.4)} />
<stop offset="100%" stopColor={alpha(chartColor, 0)} />
</linearGradient>
</defs>
);
}
const chartMargin = { top: 0, bottom: 0, left: 0, right: 0 };
const defaultXValueFormatter = (value: number) => value.toString();
const defaultYValueFormatter = (value: number | BigNumber | null) => (value !== null ? value.toString() : '');
type Point = {
x: number;
y: number | BigNumber;
};
const MemoLineChart = memo((props: SparkLineChartProps & { chartColor: string }) => {
const { chartColor, sx, ...rest } = props;
const areaSx = {
[`& .${areaElementClasses.root}`]: {
fill: 'url(#graph-gradient)',
},
...sx,
};
return (
<SparkLineChart {...rest} sx={areaSx}>
<LinearGradient chartColor={chartColor} />
<rect x={0} y={0} width={0} height="100%" fill="url(#graph-gradient)" />
</SparkLineChart>
);
});
export type LineChartProps = {
data: Point[];
height?: number;
xValueFormatter?: (value: number) => string;
yValueFormatter?: (value: number | BigNumber | null) => string;
};
export default function LineChart(props: LineChartProps) {
const {
data,
xValueFormatter = defaultXValueFormatter,
yValueFormatter = defaultYValueFormatter,
height = 150,
} = props;
const theme = useTheme();
const chartColor = theme.palette.primary?.main ?? Color.Green[500];
const chartColors = useMemo(() => [chartColor], [chartColor]);
const stringifiedData = useMemo(() => JSONbig.stringify(data), [data]);
const freezedData = useMemo<Point[]>(() => JSONbig.parse(stringifiedData), [stringifiedData]);
const yData = useMemo(() => freezedData.map((item) => item.y), [freezedData]);
const xData = useMemo(() => freezedData.map((item) => item.x), [freezedData]);
const yDataNumber = useMemo(
() => yData.map((value) => (value instanceof BigNumber ? value.toNumber() : value)),
[yData],
);
const xAxis = useMemo(
() => ({
data: xData,
valueFormatter: xValueFormatter,
}),
[xData, xValueFormatter],
);
return (
<StyledGraphContainer height={height}>
<MemoLineChart
xAxis={xAxis}
data={yDataNumber}
height={height || 0}
valueFormatter={yValueFormatter}
curve="monotoneX"
margin={chartMargin}
colors={chartColors}
chartColor={chartColor}
area
showHighlight
showTooltip
/>
</StyledGraphContainer>
);
}