|
@@ -2,6 +2,7 @@ import BarElement from './BarElement';
|
|
|
import BaseContainer from './BaseContainer';
|
|
import BaseContainer from './BaseContainer';
|
|
|
import ModuleHeader from './ModuleHeader';
|
|
import ModuleHeader from './ModuleHeader';
|
|
|
import ModuleHeaderBackground from './ModuleHeaderBackground';
|
|
import ModuleHeaderBackground from './ModuleHeaderBackground';
|
|
|
|
|
+import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
|
|
|
|
|
|
|
interface AssetMetricsProps {
|
|
interface AssetMetricsProps {
|
|
|
className?: string;
|
|
className?: string;
|
|
@@ -15,14 +16,12 @@ const assetData = [
|
|
|
{ year: '2025年', assetTotal: 840.12, assetNet: 421.55 }
|
|
{ year: '2025年', assetTotal: 840.12, assetNet: 421.55 }
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
-// 按照Figma设计规范中的精确柱形高度
|
|
|
|
|
-const barHeights = {
|
|
|
|
|
- '2021年': { assetTotal: 90, assetNet: 41 },
|
|
|
|
|
- '2022年': { assetTotal: 100, assetNet: 48 },
|
|
|
|
|
- '2023年': { assetTotal: 145, assetNet: 92 },
|
|
|
|
|
- '2024年': { assetTotal: 175, assetNet: 122 },
|
|
|
|
|
- '2025年': { assetTotal: 180, assetNet: 125 }
|
|
|
|
|
-};
|
|
|
|
|
|
|
+// Recharts格式的数据
|
|
|
|
|
+const chartData = assetData.map(item => ({
|
|
|
|
|
+ year: item.year,
|
|
|
|
|
+ '资产总额': item.assetTotal,
|
|
|
|
|
+ '资产净额': item.assetNet
|
|
|
|
|
+}));
|
|
|
|
|
|
|
|
export function AssetMetrics({ className }: AssetMetricsProps) {
|
|
export function AssetMetrics({ className }: AssetMetricsProps) {
|
|
|
return (
|
|
return (
|
|
@@ -30,7 +29,7 @@ export function AssetMetrics({ className }: AssetMetricsProps) {
|
|
|
{/* 底部容器 - 使用BaseContainer作为背景 */}
|
|
{/* 底部容器 - 使用BaseContainer作为背景 */}
|
|
|
<BaseContainer className="absolute h-[490px] left-0 overflow-clip top-0 w-[930px]" />
|
|
<BaseContainer className="absolute h-[490px] left-0 overflow-clip top-0 w-[930px]" />
|
|
|
|
|
|
|
|
- {/* 表格区域 */}
|
|
|
|
|
|
|
+ {/* 表格区域 - 使用Recharts实现 */}
|
|
|
<div className="absolute content-stretch flex flex-col gap-[20px] h-[388px] items-start left-[41.4px] top-[79px] w-[847.191px]">
|
|
<div className="absolute content-stretch flex flex-col gap-[20px] h-[388px] items-start left-[41.4px] top-[79px] w-[847.191px]">
|
|
|
{/* 顶部标题和说明 */}
|
|
{/* 顶部标题和说明 */}
|
|
|
<div className="content-stretch flex items-start justify-between relative shrink-0 w-[847px]">
|
|
<div className="content-stretch flex items-start justify-between relative shrink-0 w-[847px]">
|
|
@@ -65,75 +64,64 @@ export function AssetMetrics({ className }: AssetMetricsProps) {
|
|
|
单位:亿元
|
|
单位:亿元
|
|
|
</p>
|
|
</p>
|
|
|
|
|
|
|
|
- {/* 年份标签 */}
|
|
|
|
|
- <div className="grid-cols-[max-content] grid-rows-[max-content] inline-grid justify-items-start leading-[0] relative shrink-0">
|
|
|
|
|
- <div className="col-[1] grid-cols-[max-content] grid-rows-[max-content] inline-grid justify-items-start leading-[21.504px] ml-[93px] mt-[calc(50%+125.72px)] relative row-[1] text-[15px] text-[rgba(255,255,255,0.8)] whitespace-pre-wrap">
|
|
|
|
|
- {assetData.map((data, index) => (
|
|
|
|
|
- <p
|
|
|
|
|
- key={data.year}
|
|
|
|
|
- className={`col-[1] mt-0 relative row-[1] ${
|
|
|
|
|
- index === 0 ? 'ml-0 w-[49.92px]' :
|
|
|
|
|
- index === 1 ? 'ml-[207.76px] text-right translate-x-[-100%] w-[53.76px]' :
|
|
|
|
|
- index === 2 ? 'ml-[376.68px] text-right translate-x-[-100%] w-[55.68px]' :
|
|
|
|
|
- index === 3 ? 'ml-[490px] w-[52.48px]' :
|
|
|
|
|
- 'ml-[656px] mt-px w-[58px]'
|
|
|
|
|
- }`}
|
|
|
|
|
- >
|
|
|
|
|
- {data.year}
|
|
|
|
|
- </p>
|
|
|
|
|
- ))}
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- {/* 网格线背景 */}
|
|
|
|
|
- <div className="col-[1] grid-cols-[max-content] grid-rows-[max-content] inline-grid justify-items-start ml-[52px] mt-0 relative row-[1]">
|
|
|
|
|
- {/* 水平网格线 */}
|
|
|
|
|
- <div className="col-[1] h-[2px] ml-[0.12px] mt-0 relative row-[1] w-[794.879px] bg-gradient-to-r from-[rgba(255,255,255,0.1)] to-[rgba(255,255,255,0.05)]" />
|
|
|
|
|
- <div className="col-[1] h-[2px] ml-0 mt-[40px] relative row-[1] w-[795px] bg-gradient-to-r from-[rgba(255,255,255,0.1)] to-[rgba(255,255,255,0.05)]" />
|
|
|
|
|
- <div className="col-[1] h-[2px] ml-0 mt-[80px] relative row-[1] w-[795px] bg-gradient-to-r from-[rgba(255,255,255,0.1)] to-[rgba(255,255,255,0.05)]" />
|
|
|
|
|
- <div className="col-[1] h-[2px] ml-0 mt-[120px] relative row-[1] w-[795px] bg-gradient-to-r from-[rgba(255,255,255,0.1)] to-[rgba(255,255,255,0.05)]" />
|
|
|
|
|
- <div className="col-[1] h-[2px] ml-0 mt-[160px] relative row-[1] w-[795px] bg-gradient-to-r from-[rgba(255,255,255,0.1)] to-[rgba(255,255,255,0.05)]" />
|
|
|
|
|
- <div className="col-[1] h-[2px] ml-0 mt-[200px] relative row-[1] w-[795.191px] bg-gradient-to-r from-[rgba(255,255,255,0.1)] to-[rgba(255,255,255,0.05)]" />
|
|
|
|
|
- <div className="col-[1] h-[2px] ml-0 mt-[240px] relative row-[1] w-[795px] bg-gradient-to-r from-[rgba(255,255,255,0.1)] to-[rgba(255,255,255,0.05)]" />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- {/* 柱形图数据 */}
|
|
|
|
|
- <div className="box-border col-[1] content-stretch flex items-end justify-between ml-[69px] mt-[3.44px] relative row-[1] w-[753px]">
|
|
|
|
|
- {assetData.map((data) => (
|
|
|
|
|
- <div key={data.year} className="content-stretch flex gap-[10px] items-end relative shrink-0">
|
|
|
|
|
- {/* 资产总额 */}
|
|
|
|
|
- <div className="content-stretch flex flex-col gap-[10px] items-center relative shrink-0 w-[43px]">
|
|
|
|
|
- <p className="leading-[21.504px] min-w-full not-italic relative shrink-0 text-[13px] text-white w-[min-content] whitespace-pre-wrap">
|
|
|
|
|
- {data.assetTotal}
|
|
|
|
|
- </p>
|
|
|
|
|
- <div className="flex items-center justify-center relative shrink-0">
|
|
|
|
|
- <div className="flex-none rotate-[180deg]">
|
|
|
|
|
- <BarElement
|
|
|
|
|
- variant="asset-total"
|
|
|
|
|
- className={`w-[35px]`}
|
|
|
|
|
- style={{ height: `${barHeights[data.year as keyof typeof barHeights].assetTotal}px` }}
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
-
|
|
|
|
|
- {/* 资产净额 */}
|
|
|
|
|
- <div className="content-stretch flex flex-col gap-[10px] items-center relative shrink-0 w-[35px]">
|
|
|
|
|
- <p className="leading-[21.504px] min-w-full not-italic relative shrink-0 text-[13px] text-white w-[min-content] whitespace-pre-wrap">
|
|
|
|
|
- {data.assetNet}
|
|
|
|
|
- </p>
|
|
|
|
|
- <div className="flex items-center justify-center relative shrink-0">
|
|
|
|
|
- <div className="flex-none rotate-[180deg]">
|
|
|
|
|
- <BarElement
|
|
|
|
|
- variant="asset-net"
|
|
|
|
|
- className={`w-[35px] rounded-[2px]`}
|
|
|
|
|
- style={{ height: `${barHeights[data.year as keyof typeof barHeights].assetNet}px` }}
|
|
|
|
|
- />
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- </div>
|
|
|
|
|
- ))}
|
|
|
|
|
|
|
+ {/* Recharts图表区域 */}
|
|
|
|
|
+ <div className="w-full h-[300px] mt-4">
|
|
|
|
|
+ <ResponsiveContainer width="100%" height="100%">
|
|
|
|
|
+ <BarChart
|
|
|
|
|
+ data={chartData}
|
|
|
|
|
+ margin={{ top: 20, right: 30, left: 20, bottom: 5 }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <CartesianGrid
|
|
|
|
|
+ strokeDasharray="3 3"
|
|
|
|
|
+ stroke="rgba(255,255,255,0.1)"
|
|
|
|
|
+ horizontal={true}
|
|
|
|
|
+ vertical={false}
|
|
|
|
|
+ />
|
|
|
|
|
+ <XAxis
|
|
|
|
|
+ dataKey="year"
|
|
|
|
|
+ axisLine={false}
|
|
|
|
|
+ tickLine={false}
|
|
|
|
|
+ tick={{ fill: 'rgba(255,255,255,0.8)', fontSize: 14 }}
|
|
|
|
|
+ />
|
|
|
|
|
+ <YAxis
|
|
|
|
|
+ axisLine={false}
|
|
|
|
|
+ tickLine={false}
|
|
|
|
|
+ tick={{ fill: 'rgba(255,255,255,0.8)', fontSize: 12 }}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Tooltip
|
|
|
|
|
+ contentStyle={{
|
|
|
|
|
+ backgroundColor: 'rgba(0,0,0,0.8)',
|
|
|
|
|
+ border: '1px solid rgba(255,255,255,0.2)',
|
|
|
|
|
+ color: 'white'
|
|
|
|
|
+ }}
|
|
|
|
|
+ formatter={(value) => [`${value} 亿元`, '']}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Bar
|
|
|
|
|
+ dataKey="资产总额"
|
|
|
|
|
+ fill="url(#assetTotalGradient)"
|
|
|
|
|
+ radius={[2, 2, 0, 0]}
|
|
|
|
|
+ barSize={35}
|
|
|
|
|
+ />
|
|
|
|
|
+ <Bar
|
|
|
|
|
+ dataKey="资产净额"
|
|
|
|
|
+ fill="url(#assetNetGradient)"
|
|
|
|
|
+ radius={[2, 2, 0, 0]}
|
|
|
|
|
+ barSize={35}
|
|
|
|
|
+ />
|
|
|
|
|
+ <defs>
|
|
|
|
|
+ {/* 资产总额渐变 - 匹配BarElement的蓝色渐变 */}
|
|
|
|
|
+ <linearGradient id="assetTotalGradient" x1="0" y1="0" x2="0" y2="1">
|
|
|
|
|
+ <stop offset="0%" stopColor="#a2beff" stopOpacity={0.8}/>
|
|
|
|
|
+ <stop offset="100%" stopColor="#a2beff" stopOpacity={0}/>
|
|
|
|
|
+ </linearGradient>
|
|
|
|
|
+ {/* 资产净额渐变 - 匹配BarElement的黄色渐变 */}
|
|
|
|
|
+ <linearGradient id="assetNetGradient" x1="0" y1="0" x2="0" y2="1">
|
|
|
|
|
+ <stop offset="0%" stopColor="#edce59" stopOpacity={0.8}/>
|
|
|
|
|
+ <stop offset="100%" stopColor="#edce59" stopOpacity={0}/>
|
|
|
|
|
+ </linearGradient>
|
|
|
|
|
+ </defs>
|
|
|
|
|
+ </BarChart>
|
|
|
|
|
+ </ResponsiveContainer>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|