105 lines
2.6 KiB
TypeScript
105 lines
2.6 KiB
TypeScript
import { useMemo, useState } from 'react';
|
||
import { AgCharts } from 'ag-charts-react';
|
||
import type { AgCartesianChartOptions } from 'ag-charts-community';
|
||
|
||
const revenueData = [
|
||
{ month: '1月', revenue: 146, orders: 92, margin: 36 },
|
||
{ month: '2月', revenue: 158, orders: 101, margin: 39 },
|
||
{ month: '3月', revenue: 171, orders: 117, margin: 43 },
|
||
{ month: '4月', revenue: 185, orders: 126, margin: 45 },
|
||
{ month: '5月', revenue: 193, orders: 133, margin: 47 },
|
||
{ month: '6月', revenue: 221, orders: 148, margin: 52 },
|
||
];
|
||
|
||
function App() {
|
||
const [chartType, setChartType] = useState<'bar' | 'line'>('bar');
|
||
|
||
const chartOptions = useMemo<AgCartesianChartOptions>(
|
||
() => ({
|
||
title: {
|
||
text: '业务趋势',
|
||
},
|
||
subtitle: {
|
||
text: '收入、订单与毛利表现',
|
||
},
|
||
data: revenueData,
|
||
series: [
|
||
{
|
||
type: chartType,
|
||
xKey: 'month',
|
||
yKey: 'revenue',
|
||
yName: '收入',
|
||
fill: '#2563eb',
|
||
stroke: '#2563eb',
|
||
},
|
||
{
|
||
type: chartType,
|
||
xKey: 'month',
|
||
yKey: 'orders',
|
||
yName: '订单',
|
||
fill: '#059669',
|
||
stroke: '#059669',
|
||
},
|
||
{
|
||
type: chartType,
|
||
xKey: 'month',
|
||
yKey: 'margin',
|
||
yName: '毛利',
|
||
fill: '#d97706',
|
||
stroke: '#d97706',
|
||
},
|
||
],
|
||
axes: {
|
||
x: {
|
||
type: 'category',
|
||
position: 'bottom',
|
||
},
|
||
y: {
|
||
type: 'number',
|
||
position: 'left',
|
||
title: {
|
||
text: '数值',
|
||
},
|
||
},
|
||
},
|
||
legend: {
|
||
position: 'bottom',
|
||
},
|
||
}),
|
||
[chartType],
|
||
);
|
||
|
||
return (
|
||
<main className="app-shell">
|
||
<section className="toolbar" aria-label="图表设置">
|
||
<div>
|
||
<h1>AG Chart Service</h1>
|
||
<p>React 单页图表服务,无路由。</p>
|
||
</div>
|
||
<div className="segmented-control" aria-label="切换图表类型">
|
||
<button
|
||
className={chartType === 'bar' ? 'active' : ''}
|
||
type="button"
|
||
onClick={() => setChartType('bar')}
|
||
>
|
||
柱状
|
||
</button>
|
||
<button
|
||
className={chartType === 'line' ? 'active' : ''}
|
||
type="button"
|
||
onClick={() => setChartType('line')}
|
||
>
|
||
折线
|
||
</button>
|
||
</div>
|
||
</section>
|
||
|
||
<section className="chart-panel" aria-label="业务趋势图表">
|
||
<AgCharts options={chartOptions} />
|
||
</section>
|
||
</main>
|
||
);
|
||
}
|
||
|
||
export default App;
|