数据如果只是干巴巴的数字,很难让人直观地发现规律。作为数据分析平台,高质量的数据可视化是提升用户体验(UX)的核心手段。
在现代 Web 前端生态中,数据可视化方案百花齐放。本节我们将打破局限,在项目中集成业界最顶级的 2D 图表库(Apache ECharts) 以及炫酷的 3D 渲染库(Three.js 及其 React 封装),为我们的 AI Analyzer 注入强大的视觉表现力。
源码地址:https://github.com/you-want/ai-data-analyzer
欢迎 star,支持一波。
1. 为什么选择 ECharts 和 Three.js?
对于企业级和需要极强视觉冲击力的产品而言,我们需要重型的武器:
- Apache ECharts:百度开源、现已捐赠给 Apache 基金会。它是目前国内乃至全球功能最丰富、性能最强悍(支持 Canvas 和 SVG 双引擎,轻松处理十万级数据)的 2D 图表库。
- Three.js & React Three Fiber (R3F):Three.js 是 WebGL 的标准。而 R3F 是一个极其优秀的 React 封装,允许我们用声明式的组件语法来写 3D 场景。我们将用它来构建一个炫酷的"3D 数据星系"。
安装依赖
进入 frontend 目录,安装这些强大的可视化工具:
bash
cd frontend
# 安装 ECharts 相关
pnpm add echarts echarts-for-react
# 安装 3D 渲染相关
pnpm add three @react-three/fiber @react-three/drei
pnpm add -D @types/three
2. 构建高级 2D 销售趋势图 (ECharts)
ECharts 的配置项 (Option) 非常强大。我们创建一个支持渐变色、双折线、堆叠以及自适应暗黑模式的复杂图表组件。
新建文件 frontend/src/components/charts/AdvancedSalesChart.tsx:
tsx
"use client";
import React, { useMemo } from 'react';
import ReactECharts from 'echarts-for-react';
interface EChartsComponentProps {
title?: string;
data?: Record<string, unknown>[]; // 后续对接真实数据
}
export default function AdvancedSalesChart({ title = '全渠道销售趋势与预测' }: EChartsComponentProps) {
// 模拟数据
const xAxisData = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月'];
const onlineSales = [120, 132, 101, 134, 90, 230, 210, 250, 300];
const offlineSales = [220, 182, 191, 234, 290, 330, 310, 280, 250];
// 这里简化处理,实际项目可从 next-themes 获取 isDark 状态
const isDark = false;
const option = useMemo(() => ({
backgroundColor: 'transparent',
tooltip: { trigger: 'axis' },
legend: { data: ['线上销售', '线下销售'] },
grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
xAxis: [{
type: 'category',
boundaryGap: false,
data: xAxisData,
}],
yAxis: [{ type: 'value' }],
series: [
{
name: '线上销售',
type: 'line',
smooth: true,
showSymbol: false,
areaStyle: {
opacity: 0.8,
color: {
type: 'linear',
x: 0, y: 0, x2: 0, y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(59, 130, 246, 0.8)' },
{ offset: 1, color: 'rgba(59, 130, 246, 0.1)' }
]
}
},
data: onlineSales
},
// ... 线下销售配置类似,颜色为绿色 (rgba(16, 185, 129))
]
}), [isDark]);
return (
<div className="bg-white dark:bg-zinc-900 p-6 rounded-2xl shadow-sm border border-gray-100 dark:border-zinc-800 flex flex-col h-full">
<h3 className="text-lg font-semibold text-gray-800 dark:text-zinc-100 mb-4">{title}</h3>
<div className="flex-1 min-h-[300px]">
<ReactECharts option={option} style={{ height: '100%', width: '100%' }} />
</div>
</div>
);
}
提示: 我们使用了
useMemo来缓存 option 配置,避免 React 重渲染时造成 ECharts 实例不必要的重绘。
3. 降维打击:构建 3D 数据星系 (Three.js)
传统的 2D 柱状图太普通了。在 AI Data Agent 平台中,为了向客户展示我们深厚的技术实力,我们引入一个由 Three.js 驱动的 3D 交互式数据图表。
新建文件 frontend/src/components/charts/DataGalaxy3D.tsx:
tsx
"use client";
import React, { useRef, useState } from 'react';
import { Canvas, useFrame } from '@react-three/fiber';
import { OrbitControls, Text, Float } from '@react-three/drei';
import * as THREE from 'three';
// 单个 3D 交互柱子组件
function Bar({ position, height, color, label }: any) {
const meshRef = useRef<THREE.Mesh>(null);
const [hovered, setHover] = useState(false);
// 使用 useFrame 实现平滑的悬浮放大动画 (类似 requestAnimationFrame)
useFrame(() => {
if (meshRef.current) {
const targetScaleY = hovered ? 1.1 : 1;
meshRef.current.scale.y = THREE.MathUtils.lerp(meshRef.current.scale.y, targetScaleY, 0.1);
}
});
return (
<group position={position}>
{/* 3D 柱子本体 */}
<mesh
ref={meshRef}
position={[0, height / 2, 0]}
onPointerOver={() => setHover(true)}
onPointerOut={() => setHover(false)}
castShadow receiveShadow
>
<boxGeometry args={[0.8, height, 0.8]} />
<meshStandardMaterial color={hovered ? '#ffffff' : color} roughness={0.2} metalness={0.8} />
</mesh>
{/* 底部 3D 文字标签 */}
<Text position={[0, -0.5, 0.6]} rotation={[-Math.PI / 2, 0, 0]} fontSize={0.4} color="#888888" anchorX="center">
{label}
</Text>
{/* 悬浮时显示的顶部浮动数值 */}
{hovered && (
<Float speed={5} rotationIntensity={0} floatIntensity={0.5}>
<Text position={[0, height + 0.8, 0]} fontSize={0.5} color="#ffffff" anchorX="center">
{height.toFixed(1)}
</Text>
</Float>
)}
</group>
);
}
export default function DataGalaxy3D() {
const data = [
{ label: 'Q1', value: 4.2, color: '#3B82F6' },
{ label: 'Q2', value: 6.8, color: '#10B981' },
{ label: 'Q3', value: 3.5, color: '#F59E0B' },
{ label: 'Q4', value: 8.4, color: '#EF4444' },
];
return (
<div className="bg-[#18181B] p-6 rounded-2xl shadow-sm border border-zinc-800 flex flex-col h-full relative overflow-hidden">
<div className="absolute top-6 left-6 z-10">
<h3 className="text-lg font-semibold text-zinc-100">数据星系 (3D 视图)</h3>
<p className="text-xs text-zinc-400 mt-1">拖拽以旋转视角,悬浮查看数据</p>
</div>
{/* Canvas 是 Three.js 的渲染入口 */}
<div className="flex-1 min-h-[300px] w-full h-full cursor-grab active:cursor-grabbing">
<Canvas shadows camera={{ position: [0, 5, 12], fov: 45 }}>
<color attach="background" args={['#18181B']} />
<ambientLight intensity={0.5} />
<directionalLight position={[10, 10, 5]} intensity={1} castShadow />
<group position={[-3, -2, 0]}>
{data.map((item, index) => (
<Bar key={item.label} position={[index * 2, 0, 0]} height={item.value} color={item.color} label={item.label} />
))}
{/* 底座 */}
<mesh position={[3, -0.2, 0]} receiveShadow>
<boxGeometry args={[9, 0.4, 3]} />
<meshStandardMaterial color="#27272A" />
</mesh>
</group>
{/* 允许用户拖拽旋转视角的控制器 */}
<OrbitControls enablePan={false} minPolarAngle={Math.PI / 4} maxPolarAngle={Math.PI / 2.2} />
</Canvas>
</div>
</div>
);
}
4. 将图表集成到 Dashboard
最后,我们回到上一节编写的 frontend/src/app/dashboard/page.tsx,将这两个组件放置在指标卡片下方。
tsx
// frontend/src/app/dashboard/page.tsx
import AdvancedSalesChart from '@/components/charts/AdvancedSalesChart';
import DataGalaxy3D from '@/components/charts/DataGalaxy3D';
// ... (其他引入保持不变)
export default async function DashboardPage() {
return (
<div className="space-y-8">
{/* 1. 顶部指标卡片区域... */}
{/* 2. 数据可视化区域:2D ECharts 与 3D Three.js */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 h-[450px]">
{/* 左侧:2D 复杂图表 (ECharts) */}
<AdvancedSalesChart />
{/* 右侧:3D 数据星系 (Three.js / React Three Fiber) */}
<DataGalaxy3D />
</div>
{/* 3. 业务功能操作区 (上传、任务监听与 AI 对话)... */}
</div>
);
}
现在打开你的浏览器,你会看到一个极具专业感和未来感的 Dashboard!左侧是平滑渐变的 ECharts 折线图,右侧是可以通过鼠标拖拽旋转、悬浮高亮互动的 3D 数据柱状图。你的 AI Agent 数据中台在视觉上已经遥遥领先了!