Просмотр исходного кода

✨ feat(FinancialDashboard): 升级资产指标图表为3D视觉效果

- 添加自定义3D柱状图组件AssetTotalBar和AssetNetBar
- 实现SVG路径与渐变效果,增强视觉层次感
- 替换原有2D柱状图为新的3D样式,提升数据可视化体验
- 移除旧的线性渐变定义,采用新的3D渐变方案
yourname 2 месяцев назад
Родитель
Сommit
3c09fb4dc9
1 измененных файлов с 117 добавлено и 16 удалено
  1. 117 16
      src/client/home/pages/FinancialDashboard/components/AssetMetrics.tsx

+ 117 - 16
src/client/home/pages/FinancialDashboard/components/AssetMetrics.tsx

@@ -23,6 +23,121 @@ const chartData = assetData.map(item => ({
   '资产净额': item.assetNet
   '资产净额': item.assetNet
 }));
 }));
 
 
+// 自定义 3D 柱状图组件 - 资产总额(高版本)
+const AssetTotalBar = (props: any) => {
+  const { x, y, width, height } = props;
+
+  // 将Recharts的坐标系转换为SVG的坐标系
+  const svgWidth = 36;
+  const svgHeight = 225;
+  const scaleX = width / svgWidth;
+  const scaleY = height / svgHeight;
+
+  return (
+    <g transform={`translate(${x},${y}) scale(${scaleX},${scaleY})`}>
+      <path d="M35.25 222H0.25L0.25 3L35.25 3L35.25 222Z" fill="url(#paint0_linear_1977_58501)"/>
+      <path d="M35.25 222H0.25L0.25 3L35.25 3L35.25 222Z" fill="url(#paint1_linear_1977_58501)" fillOpacity="0.6"/>
+      <ellipse cx="17.75" cy="221.5" rx="17.5" ry="2.5" fill="url(#paint2_linear_1977_58501)"/>
+      <ellipse cx="17.75" cy="221.5" rx="17.5" ry="2.5" fill="url(#paint3_linear_1977_58501)" fillOpacity="0.6"/>
+      <path d="M35.25 221.5C35.25 222.881 27.415 224 17.75 224C8.08502 224 0.25 222.881 0.25 221.5" stroke="url(#paint4_linear_1977_58501)" strokeWidth="0.5"/>
+      <ellipse cx="17.75" cy="2.5" rx="17.5" ry="2.5" fill="url(#paint5_linear_1977_58501)"/>
+      <path d="M35.25 2.5C35.25 3.88071 27.415 5 17.75 5C8.08502 5 0.25 3.88071 0.25 2.5" stroke="url(#paint6_linear_1977_58501)" strokeWidth="0.5"/>
+      <defs>
+        <linearGradient id="paint0_linear_1977_58501" x1="17.7421" y1="220.876" x2="17.7421" y2="3.00582" gradientUnits="userSpaceOnUse">
+          <stop stopColor="#4DBBBA" stopOpacity="0"/>
+          <stop offset="1" stopColor="#4DBBBA" stopOpacity="0.5"/>
+        </linearGradient>
+        <linearGradient id="paint1_linear_1977_58501" x1="0.25" y1="112.5" x2="35.25" y2="112.5" gradientUnits="userSpaceOnUse">
+          <stop offset="0.125" stopColor="#4DBBBA"/>
+          <stop offset="0.497375" stopColor="#9FFFFE"/>
+          <stop offset="0.911458" stopColor="#4DBBBA"/>
+        </linearGradient>
+        <linearGradient id="paint2_linear_1977_58501" x1="17.7528" y1="223.997" x2="17.7528" y2="219" gradientUnits="userSpaceOnUse">
+          <stop stopColor="#4DBBBA"/>
+          <stop offset="1" stopColor="#0F918F"/>
+        </linearGradient>
+        <linearGradient id="paint3_linear_1977_58501" x1="0.25" y1="221.5" x2="35.25" y2="221.5" gradientUnits="userSpaceOnUse">
+          <stop offset="0.125" stopColor="#4DBBBA"/>
+          <stop offset="0.497375" stopColor="#9FFFFE"/>
+          <stop offset="0.911458" stopColor="#4DBBBA"/>
+        </linearGradient>
+        <linearGradient id="paint4_linear_1977_58501" x1="17.75" y1="221.5" x2="17.75" y2="224" gradientUnits="userSpaceOnUse">
+          <stop stopColor="white" stopOpacity="0"/>
+          <stop offset="1" stopColor="white"/>
+        </linearGradient>
+        <linearGradient id="paint5_linear_1977_58501" x1="17.7528" y1="4.99708" x2="17.7528" y2="0" gradientUnits="userSpaceOnUse">
+          <stop stopColor="#4DBBBA"/>
+          <stop offset="1" stopColor="#0F918F"/>
+        </linearGradient>
+        <linearGradient id="paint6_linear_1977_58501" x1="17.75" y1="2.5" x2="17.75" y2="5" gradientUnits="userSpaceOnUse">
+          <stop stopColor="white" stopOpacity="0"/>
+          <stop offset="1" stopColor="white"/>
+        </linearGradient>
+      </defs>
+    </g>
+  );
+};
+
+// 自定义 3D 柱状图组件 - 资产净额(高版本)
+const AssetNetBar = (props: any) => {
+  const { x, y, width, height } = props;
+
+  // 将Recharts的坐标系转换为SVG的坐标系
+  const svgWidth = 36;
+  const svgHeight = 135;
+  const scaleX = width / svgWidth;
+  const scaleY = height / svgHeight;
+
+  return (
+    <g transform={`translate(${x},${y}) scale(${scaleX},${scaleY})`}>
+      <rect width="35" height="132" transform="translate(0.25 3)" fill="url(#paint0_linear_1977_58512)"/>
+      <path d="M35.25 7L0.25 7L0.25 3L35.25 3V7Z" fill="url(#paint1_linear_1977_58512)"/>
+      <path d="M35.25 7L0.25 7L0.25 3L35.25 3V7Z" fill="url(#paint2_linear_1977_58512)" fillOpacity="0.8"/>
+      <ellipse cx="17.75" cy="6.5" rx="17.5" ry="2.5" fill="url(#paint3_linear_1977_58512)"/>
+      <ellipse cx="17.75" cy="6.5" rx="17.5" ry="2.5" fill="url(#paint4_linear_1977_58512)" fillOpacity="0.6"/>
+      <path d="M35.25 6.5C35.25 7.88071 27.415 9 17.75 9C8.08502 9 0.25 7.88071 0.25 6.5" stroke="url(#paint5_linear_1977_58512)" strokeWidth="0.5"/>
+      <ellipse cx="17.75" cy="2.5" rx="17.5" ry="2.5" fill="url(#paint6_linear_1977_58512)"/>
+      <path d="M35.25 2.5C35.25 3.88071 27.415 5 17.75 5C8.08502 5 0.25 3.88071 0.25 2.5" stroke="url(#paint7_linear_1977_58512)" strokeWidth="0.5"/>
+      <defs>
+        <linearGradient id="paint0_linear_1977_58512" x1="17.5" y1="0" x2="17.5" y2="132" gradientUnits="userSpaceOnUse">
+          <stop stopColor="#EDCE59" stopOpacity="0.807843"/>
+          <stop offset="1" stopColor="#EDCE59" stopOpacity="0"/>
+        </linearGradient>
+        <linearGradient id="paint1_linear_1977_58512" x1="17.7421" y1="6.97946" x2="17.7421" y2="3.00011" gradientUnits="userSpaceOnUse">
+          <stop offset="0.177083" stopColor="#EDCE59" stopOpacity="0"/>
+          <stop offset="1" stopColor="#EDCE59" stopOpacity="0.6"/>
+        </linearGradient>
+        <linearGradient id="paint2_linear_1977_58512" x1="0.25" y1="5" x2="35.25" y2="5.00003" gradientUnits="userSpaceOnUse">
+          <stop offset="0.1875" stopColor="#EDCE59"/>
+          <stop offset="0.497375" stopColor="white"/>
+          <stop offset="0.875" stopColor="#EDCE59"/>
+        </linearGradient>
+        <linearGradient id="paint3_linear_1977_58512" x1="17.7528" y1="8.99708" x2="17.7528" y2="4" gradientUnits="userSpaceOnUse">
+          <stop stopColor="#EDCE59"/>
+          <stop offset="1" stopColor="#B4910E"/>
+        </linearGradient>
+        <linearGradient id="paint4_linear_1977_58512" x1="0.25" y1="6.5" x2="35.25" y2="6.50002" gradientUnits="userSpaceOnUse">
+          <stop offset="0.1875" stopColor="#EDCE59"/>
+          <stop offset="0.497375" stopColor="#FFF3C5"/>
+          <stop offset="0.875" stopColor="#EDCE59"/>
+        </linearGradient>
+        <linearGradient id="paint5_linear_1977_58512" x1="17.75" y1="6.5" x2="17.75" y2="9" gradientUnits="userSpaceOnUse">
+          <stop stopColor="#EDCE59" stopOpacity="0"/>
+          <stop offset="1" stopColor="white"/>
+        </linearGradient>
+        <linearGradient id="paint6_linear_1977_58512" x1="17.7528" y1="4.99708" x2="17.7528" y2="0" gradientUnits="userSpaceOnUse">
+          <stop stopColor="#EDCE59"/>
+          <stop offset="1" stopColor="#B4910E" stopOpacity="0.807843"/>
+        </linearGradient>
+        <linearGradient id="paint7_linear_1977_58512" x1="17.75" y1="2.5" x2="17.75" y2="5" gradientUnits="userSpaceOnUse">
+          <stop stopColor="#EDCE59" stopOpacity="0"/>
+          <stop offset="1" stopColor="white"/>
+        </linearGradient>
+      </defs>
+    </g>
+  );
+};
+
 export function AssetMetrics({ className }: AssetMetricsProps) {
 export function AssetMetrics({ className }: AssetMetricsProps) {
   return (
   return (
     <div className={`h-[480px] overflow-clip relative shrink-0 w-full ${className || ''}`}>
     <div className={`h-[480px] overflow-clip relative shrink-0 w-full ${className || ''}`}>
@@ -98,28 +213,14 @@ export function AssetMetrics({ className }: AssetMetricsProps) {
                 />
                 />
                 <Bar
                 <Bar
                   dataKey="资产总额"
                   dataKey="资产总额"
-                  fill="url(#assetTotalGradient)"
-                  radius={[2, 2, 0, 0]}
+                  shape={<AssetTotalBar />}
                   barSize={35}
                   barSize={35}
                 />
                 />
                 <Bar
                 <Bar
                   dataKey="资产净额"
                   dataKey="资产净额"
-                  fill="url(#assetNetGradient)"
-                  radius={[2, 2, 0, 0]}
+                  shape={<AssetNetBar />}
                   barSize={35}
                   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>
               </BarChart>
             </ResponsiveContainer>
             </ResponsiveContainer>
           </div>
           </div>