图表缩放

This commit is contained in:
feie9456 2025-11-16 09:50:21 +08:00
parent d1647d3114
commit ba50f46946
5 changed files with 4921 additions and 15 deletions

View File

@ -13,8 +13,8 @@ const geistMono = Geist_Mono({
}); });
export const metadata: Metadata = { export const metadata: Metadata = {
title: "Create Next App", title: "ESP32 微弱压力数据采集系统",
description: "Generated by create next app", description: "用于采集和分析微弱压力数据的系统,基于 ESP32 平台构建。",
}; };
export default function RootLayout({ export default function RootLayout({
@ -23,7 +23,7 @@ export default function RootLayout({
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
return ( return (
<html lang="en"> <html lang="zh-CN">
<body <body
className={`${geistSans.variable} ${geistMono.variable} antialiased`} className={`${geistSans.variable} ${geistMono.variable} antialiased`}
> >

View File

@ -11,9 +11,10 @@ import {
Tooltip, Tooltip,
Legend, Legend,
} from 'chart.js' } from 'chart.js'
import zoomPlugin from 'chartjs-plugin-zoom'
import { Line, Bar, Scatter } from 'react-chartjs-2' import { Line, Bar, Scatter } from 'react-chartjs-2'
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Tooltip, Legend) ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, BarElement, Tooltip, Legend, zoomPlugin)
type Detail = { type Detail = {
id: string id: string
@ -88,7 +89,6 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
const dataToUse = enableEma ? smoothedCode : (rec?.code || []) const dataToUse = enableEma ? smoothedCode : (rec?.code || [])
return buildHistogram(dataToUse, 30) return buildHistogram(dataToUse, 30)
}, [rec, enableEma, smoothedCode]) }, [rec, enableEma, smoothedCode])
const forceHistogram = useMemo(() => buildHistogram(forceSeries || [], 30), [forceSeries])
return ( return (
<div className="min-h-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-zinc-100"> <div className="min-h-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-zinc-100">
@ -180,6 +180,7 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
<span className="w-12 text-right">{emaAlpha.toFixed(2)}</span> <span className="w-12 text-right">{emaAlpha.toFixed(2)}</span>
</label> </label>
)} )}
<span className="hidden text-xs text-zinc-500 sm:inline"> Ctrl+ </span>
</div> </div>
</div> </div>
<Line <Line
@ -215,7 +216,17 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
options={{ options={{
responsive: true, responsive: true,
interaction: { mode: 'index', intersect: false }, interaction: { mode: 'index', intersect: false },
plugins: { legend: { position: 'top' as const } }, plugins: {
legend: { position: 'top' as const },
zoom: {
pan: { enabled: true, mode: 'x' as const },
zoom: {
wheel: { enabled: true, modifierKey: 'ctrl' as const },
pinch: { enabled: true },
mode: 'x' as const,
},
},
},
scales: { scales: {
x: { title: { display: true, text: '时间 (ms)' } }, x: { title: { display: true, text: '时间 (ms)' } },
yCode: { type: 'linear' as const, position: 'left' as const, title: { display: true, text: '码值' } }, yCode: { type: 'linear' as const, position: 'left' as const, title: { display: true, text: '码值' } },
@ -240,7 +251,19 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
}, },
], ],
}} }}
options={{ scales: { x: { title: { display: true, text: '码值' } }, y: { title: { display: true, text: '数量' } } } }} options={{
plugins: {
zoom: {
pan: { enabled: true, mode: 'x' as const },
zoom: {
wheel: { enabled: true, modifierKey: 'ctrl' as const },
pinch: { enabled: true },
mode: 'x' as const,
},
},
},
scales: { x: { title: { display: true, text: '码值' } }, y: { title: { display: true, text: '数量' } } },
}}
/> />
</div> </div>
<div className="rounded-lg border p-4 dark:border-zinc-800"> <div className="rounded-lg border p-4 dark:border-zinc-800">
@ -261,7 +284,17 @@ export default function Page({ params }: { params: Promise<{ id: string }> }) {
x: { title: { display: true, text: '码值' } }, x: { title: { display: true, text: '码值' } },
y: { title: { display: true, text: '力值 (mN)' } }, y: { title: { display: true, text: '力值 (mN)' } },
}, },
plugins: { legend: { display: false } }, plugins: {
legend: { display: false },
zoom: {
pan: { enabled: true, mode: 'x' as const },
zoom: {
wheel: { enabled: true, modifierKey: 'ctrl' as const },
pinch: { enabled: true },
mode: 'x' as const,
},
},
},
}} }}
/> />
) : ( ) : (

View File

@ -2,6 +2,7 @@ import type { NextConfig } from "next";
const nextConfig: NextConfig = { const nextConfig: NextConfig = {
/* config options here */ /* config options here */
}; };
export default nextConfig; export default nextConfig;

4871
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -11,14 +11,15 @@
"prisma:migrate": "prisma migrate dev --name init" "prisma:migrate": "prisma migrate dev --name init"
}, },
"dependencies": { "dependencies": {
"@prisma/client": "^5",
"chart.js": "^4",
"chartjs-plugin-zoom": "^2.2.0",
"nanoid": "^5",
"next": "16.0.3", "next": "16.0.3",
"react": "19.2.0", "react": "19.2.0",
"react-chartjs-2": "^5",
"react-dom": "19.2.0", "react-dom": "19.2.0",
"@prisma/client": "^5", "zod": "^3"
"nanoid": "^5",
"zod": "^3",
"chart.js": "^4",
"react-chartjs-2": "^5"
}, },
"devDependencies": { "devDependencies": {
"@tailwindcss/postcss": "^4", "@tailwindcss/postcss": "^4",
@ -27,8 +28,8 @@
"@types/react-dom": "^19", "@types/react-dom": "^19",
"eslint": "^9", "eslint": "^9",
"eslint-config-next": "16.0.3", "eslint-config-next": "16.0.3",
"prisma": "^5",
"tailwindcss": "^4", "tailwindcss": "^4",
"typescript": "^5", "typescript": "^5"
"prisma": "^5"
} }
} }