158 lines
5.1 KiB
TypeScript
158 lines
5.1 KiB
TypeScript
|
|
import {
|
|
LineChart,
|
|
Line,
|
|
XAxis,
|
|
YAxis,
|
|
CartesianGrid,
|
|
Tooltip,
|
|
Legend,
|
|
ResponsiveContainer,
|
|
BarChart,
|
|
Bar,
|
|
PieChart,
|
|
Pie,
|
|
Cell
|
|
} from 'recharts';
|
|
|
|
// Sample data for charts
|
|
const lineData = [
|
|
{ name: 'Day 1', users: 400, sessions: 240, avg: 320 },
|
|
{ name: 'Day 2', users: 300, sessions: 139, avg: 220 },
|
|
{ name: 'Day 3', users: 200, sessions: 980, avg: 590 },
|
|
{ name: 'Day 4', users: 278, sessions: 390, avg: 334 },
|
|
{ name: 'Day 5', users: 189, sessions: 480, avg: 335 },
|
|
{ name: 'Day 6', users: 239, sessions: 380, avg: 310 },
|
|
{ name: 'Day 7', users: 349, sessions: 430, avg: 390 },
|
|
];
|
|
|
|
const barData = [
|
|
{ name: 'Product A', positive: 400, negative: 240, neutral: 320 },
|
|
{ name: 'Product B', positive: 300, negative: 139, neutral: 220 },
|
|
{ name: 'Product C', positive: 200, negative: 180, neutral: 190 },
|
|
{ name: 'Product D', positive: 278, negative: 190, neutral: 234 },
|
|
];
|
|
|
|
const pieData = [
|
|
{ name: 'Millennials', value: 400 },
|
|
{ name: 'Gen Z', value: 300 },
|
|
{ name: 'Gen X', value: 200 },
|
|
{ name: 'Boomers', value: 100 },
|
|
];
|
|
|
|
const COLORS = ['#0088FE', '#00C49F', '#FFBB28', '#FF8042'];
|
|
|
|
interface LineChartProps {
|
|
title?: string;
|
|
subtitle?: string;
|
|
height?: number;
|
|
}
|
|
|
|
export function LineChartComponent({ title, subtitle, height = 300 }: LineChartProps) {
|
|
return (
|
|
<div className="glass-panel rounded-xl p-4">
|
|
{title && <h3 className="text-base font-medium mb-1">{title}</h3>}
|
|
{subtitle && <p className="text-xs text-muted-foreground mb-4">{subtitle}</p>}
|
|
<div style={{ width: '100%', height }}>
|
|
<ResponsiveContainer>
|
|
<LineChart
|
|
data={lineData}
|
|
margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
|
|
>
|
|
<CartesianGrid strokeDasharray="3 3" stroke="#f5f5f5" />
|
|
<XAxis dataKey="name" stroke="#888888" fontSize={12} />
|
|
<YAxis stroke="#888888" fontSize={12} />
|
|
<Tooltip
|
|
contentStyle={{
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
border: '1px solid #f0f0f0',
|
|
borderRadius: '6px',
|
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)'
|
|
}}
|
|
/>
|
|
<Legend />
|
|
<Line type="monotone" dataKey="users" stroke="#3B82F6" activeDot={{ r: 8 }} strokeWidth={2} />
|
|
<Line type="monotone" dataKey="sessions" stroke="#10B981" strokeWidth={2} />
|
|
</LineChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function BarChartComponent({ title, subtitle, height = 300 }: LineChartProps) {
|
|
return (
|
|
<div className="glass-panel rounded-xl p-4">
|
|
{title && <h3 className="text-base font-medium mb-1">{title}</h3>}
|
|
{subtitle && <p className="text-xs text-muted-foreground mb-4">{subtitle}</p>}
|
|
<div style={{ width: '100%', height }}>
|
|
<ResponsiveContainer>
|
|
<BarChart
|
|
data={barData}
|
|
margin={{ top: 5, right: 30, left: 20, bottom: 5 }}
|
|
>
|
|
<CartesianGrid strokeDasharray="3 3" stroke="#f5f5f5" />
|
|
<XAxis dataKey="name" stroke="#888888" fontSize={12} />
|
|
<YAxis stroke="#888888" fontSize={12} />
|
|
<Tooltip
|
|
contentStyle={{
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
border: '1px solid #f0f0f0',
|
|
borderRadius: '6px',
|
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)'
|
|
}}
|
|
/>
|
|
<Legend />
|
|
<Bar dataKey="positive" fill="#10B981" radius={[4, 4, 0, 0]} />
|
|
<Bar dataKey="negative" fill="#EF4444" radius={[4, 4, 0, 0]} />
|
|
<Bar dataKey="neutral" fill="#6B7280" radius={[4, 4, 0, 0]} />
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function PieChartComponent({ title, subtitle, height = 300 }: LineChartProps) {
|
|
return (
|
|
<div className="glass-panel rounded-xl p-4">
|
|
{title && <h3 className="text-base font-medium mb-1">{title}</h3>}
|
|
{subtitle && <p className="text-xs text-muted-foreground mb-4">{subtitle}</p>}
|
|
<div style={{ width: '100%', height }}>
|
|
<ResponsiveContainer>
|
|
<PieChart>
|
|
<Pie
|
|
data={pieData}
|
|
cx="50%"
|
|
cy="50%"
|
|
innerRadius={60}
|
|
outerRadius={80}
|
|
fill="#8884d8"
|
|
paddingAngle={5}
|
|
dataKey="value"
|
|
label={({ name, percent }) => `${name} ${(percent * 100).toFixed(0)}%`}
|
|
>
|
|
{pieData.map((entry, index) => (
|
|
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
|
|
))}
|
|
</Pie>
|
|
<Tooltip
|
|
contentStyle={{
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
border: '1px solid #f0f0f0',
|
|
borderRadius: '6px',
|
|
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.08)'
|
|
}}
|
|
/>
|
|
</PieChart>
|
|
</ResponsiveContainer>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default {
|
|
LineChart: LineChartComponent,
|
|
BarChart: BarChartComponent,
|
|
PieChart: PieChartComponent
|
|
};
|