diff --git a/src/App.jsx b/src/App.jsx index fce2a15..0247334 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -257,7 +257,7 @@ function App() { aria-label="控制面板" > {/* 标题信息 */} -
+
@@ -328,7 +328,7 @@ function App() { /> )} -
+

{ @@ -54,7 +56,11 @@ const ChartWrapper = ({ data, options, chartId, onRegisterChart, onSyncHover }) }, [onSyncHover, chartId]); return ( -
+
); @@ -196,8 +202,10 @@ export default function ChartContainer({ pointHoverBackgroundColor: color, pointHoverBorderColor: color, pointHoverBorderWidth: 1, - animation: false, - animations: { colors: false, x: false, y: false }, + animation: { + duration: 500, + easing: 'easeOutQuart' + }, }; }) }); @@ -253,12 +261,19 @@ export default function ChartContainer({ const chartOptions = useMemo(() => ({ responsive: true, maintainAspectRatio: false, - animation: { duration: 0 }, - animations: { colors: false, x: false, y: false }, - hover: { animationDuration: 0 }, - responsiveAnimationDuration: 0, + animation: { + duration: 500, + easing: 'easeOutQuart' + }, interaction: { mode: 'index', intersect: false }, plugins: { + decimation: { + enabled: parsedData.some(file => + Object.values(file.metricsData || {}).some(arr => arr.length > 1000) + ), + algorithm: 'lttb', + samples: 1000 + }, zoom: { pan: { enabled: true, @@ -308,7 +323,6 @@ export default function ChartContainer({ tooltip: { mode: 'index', intersect: false, - animation: false, backgroundColor: 'rgba(15, 23, 42, 0.92)', titleColor: '#f1f5f9', bodyColor: '#cbd5e1', @@ -370,7 +384,7 @@ export default function ChartContainer({ } }, elements: { point: { radius: 0 } } - }), [xRange, onXRangeChange]); + }), [xRange, onXRangeChange, parsedData]); const createComparisonChartData = (item1, item2, title) => { const comparisonData = getComparisonData(item1.data, item2.data, compareMode); @@ -392,8 +406,10 @@ export default function ChartContainer({ pointHoverBackgroundColor: '#dc2626', pointHoverBorderColor: '#dc2626', pointHoverBorderWidth: 1, - animation: false, - animations: { colors: false, x: false, y: false }, + animation: { + duration: 500, + easing: 'easeOutQuart' + }, }, ]; if (baseline > 0 && (compareMode === 'relative' || compareMode === 'absolute')) { @@ -415,8 +431,10 @@ export default function ChartContainer({ pointHoverBackgroundColor: '#10b981', pointHoverBorderColor: '#10b981', pointHoverBorderWidth: 1, - animation: false, - animations: { colors: false, x: false, y: false }, + animation: { + duration: 500, + easing: 'easeOutQuart' + }, }); } return { datasets }; @@ -424,7 +442,7 @@ export default function ChartContainer({ if (parsedData.length === 0) { return ( -
+

📊 暂无数据

📁 请上传日志文件开始分析

@@ -451,7 +469,7 @@ export default function ChartContainer({ if (metrics.length === 0) { return ( -
+

🎯 请选择要显示的图表

@@ -523,7 +541,7 @@ export default function ChartContainer({ {comparisonChart} {stats && ( -
+

{key} 差值统计

Mean Difference: {stats.meanNormal.toFixed(6)}

diff --git a/src/components/ComparisonControls.jsx b/src/components/ComparisonControls.jsx index e2661ee..aa93409 100644 --- a/src/components/ComparisonControls.jsx +++ b/src/components/ComparisonControls.jsx @@ -12,7 +12,7 @@ export function ComparisonControls({ ]; return ( -
+
-
e.stopPropagation()} >
diff --git a/src/components/FileList.jsx b/src/components/FileList.jsx index 37fb183..7286201 100644 --- a/src/components/FileList.jsx +++ b/src/components/FileList.jsx @@ -4,7 +4,7 @@ import { FileText, X, Settings } from 'lucide-react'; export function FileList({ files, onFileRemove, onFileToggle, onFileConfig }) { if (files.length === 0) { return ( -
+

+

+

+
diff --git a/src/components/__tests__/ChartContainer.test.jsx b/src/components/__tests__/ChartContainer.test.jsx index bb7039d..a992796 100644 --- a/src/components/__tests__/ChartContainer.test.jsx +++ b/src/components/__tests__/ChartContainer.test.jsx @@ -20,7 +20,8 @@ vi.mock('chart.js', () => { LineElement: {}, Title: {}, Tooltip: {}, - Legend: {} + Legend: {}, + Decimation: {} }; }); diff --git a/src/index.css b/src/index.css index 3d38cda..86c9dca 100644 --- a/src/index.css +++ b/src/index.css @@ -247,6 +247,28 @@ input[type="checkbox"]:focus { } } +/* 通用元素入场动画 */ +@keyframes fadeSlideIn { + from { + opacity: 0; + transform: translateY(8px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +.fade-slide-in { + animation: fadeSlideIn 0.4s ease-out; +} + +@media (prefers-reduced-motion: reduce) { + .fade-slide-in { + animation: none !important; + } +} + /* 渐变文字动画 */ @keyframes gradientShift { 0%, 100% {