目前,工作台界面的上半部分已经基本梳理完毕了。
接下来,我们看看这个环形图卡片是怎么实现的?
具体代码如下:
{/*图表卡片*/}
<Row gutter={[16, 16]} className="mt-4" justify="center">
{/*环形图表卡片*/}
<Col span={24} md={12} lg={8}>
<CurrentDownload />
</Col>
{/*折线图表卡片*/}
<Col span={24} md={12} lg={16}>
<AreaDownload />
</Col>
</Row>
这里的Row和Col都是从antd这个样式库进行导入的:
import { Col, Row, Space } from 'antd';
采用的是一行两列的布局,而且是响应式的。
我们在这篇文章中主要分析环形图表卡片是怎么实现的:
<CurrentDownload />
我们追踪一下代码,关于代码我已经配了详细的中文注释,大家看代码的时候配合注释看应该会稍微好点:
import { Typography } from 'antd';
import Card from '@/components/card';
import Chart from '@/components/chart/chart';
import useChart from '@/components/chart/useChart';
// 环形图表卡片:当前下载量
export default function CurrentDownload() {
return (
// 这是一个自定义的卡片:import Card from '@/components/card';
<Card className="flex-col">
{/*标题*/}
<header className="self-start">
<Typography.Title level={5}>当前下载量</Typography.Title>
</header>
{/*主体:核心图表*/}
<main>
<ChartDonut />
</main>
</Card>
);
}
// 用的是一个假数据
const labels = ['Mac', 'Window', 'IOS', 'Android']
const series = [44, 55, 13, 43]
// 环形图表
function ChartDonut() {
// 属性配置
const chartOptions = useChart({
labels: labels,
stroke: {
show: false,
},
legend: {
position: 'bottom',
horizontalAlign: 'center',
},
tooltip: {
fillSeriesColor: false,
},
chart: {
width: 240,
},
plotOptions: {
pie: {
donut: {
size: '90%',
labels: {
total: {
fontSize: '12px',
},
value: {
fontSize: '18px',
fontWeight: 700,
},
},
},
},
},
});
// 图表,这里用的是Apex Chart进行最终渲染
return <Chart type="donut" series={series} options={chartOptions} height={360} />;
}
在这个代码中,有个自定义的Card组件,这个我们之前没有详细的分析,那么这次我们追踪一下代码,看看,Card这个组件是如何实现的。
import { CSSProperties, ReactNode } from 'react';
import { useSettings } from '@/store/settingStore';
import { useThemeToken } from '@/theme/hooks';
import { ThemeMode } from '#/enum';
// 卡片组件的属性
type Props = {
children?: ReactNode; // 子元素,支持JSX
className?: string; // 类名
style?: CSSProperties; // 自定义样式
};
// 自定义的卡片组件
export default function Card({ children, ...other }: Props) {
// 获取背景颜色
const { colorBgContainer } = useThemeToken();
// 获取主题模式
const { themeMode } = useSettings();
// 计算阴影
const boxShadow: { [key in ThemeMode]: string } = {
light: 'rgba(145, 158, 171, 0.2) 0px 0px 2px 0px, rgba(145, 158, 171, 0.12) 0px 12px 24px -4px',
dark: 'rgba(0, 0, 0, 0.2) 0px 0px 2px 0px, rgba(0, 0, 0, 0.12) 0px 12px 24px -4px',
};
// 组件核心元素和样式,JSX
return (
<div
style={{
backgroundColor: colorBgContainer,
backgroundImage: 'none',
boxShadow: boxShadow[themeMode],
transition: `box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms`,
borderRadius: '16px',
padding: '24px',
overflow: 'hidden',
position: 'relative',
display: 'flex',
alignItems: 'center',
}}
{...other}
>
{children}
</div>
);
}
这个自定义的卡片实现了根据主题模式动态切换样式的效果。背景颜色,阴影也是动态计算出来的。
最终的效果如下:
这里有个问题,就是这个环形图有四种属性,但是看上去只有两种颜色,不太好区分,那么能不能自定义颜色呢?
这个留给大家去做吧,这个笔记暂时就到这里。
创作不易,麻烦大家给个打赏,或者点赞和收藏,感谢!