Loading...
Loading...
Build data visualization and analytics dashboards. Use when creating charts, KPI displays, metrics dashboards, or data visualization components. Triggers on analytics, dashboard, charts, metrics, KPI, data visualization, Recharts.
npx skill4agent add hoodini/ai-agents-skills analytics-metricsnpm install rechartsimport {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
Legend,
ResponsiveContainer,
} from 'recharts';
const data = [
{ month: 'Jan', revenue: 4000, users: 2400 },
{ month: 'Feb', revenue: 3000, users: 1398 },
{ month: 'Mar', revenue: 2000, users: 9800 },
{ month: 'Apr', revenue: 2780, users: 3908 },
];
function RevenueChart() {
return (
<ResponsiveContainer width="100%" height={400}>
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="month" />
<YAxis />
<Tooltip />
<Legend />
<Line
type="monotone"
dataKey="revenue"
stroke="#3b82f6"
strokeWidth={2}
/>
<Line
type="monotone"
dataKey="users"
stroke="#10b981"
strokeWidth={2}
/>
</LineChart>
</ResponsiveContainer>
);
}import { BarChart, Bar, XAxis, YAxis, Tooltip, ResponsiveContainer } from 'recharts';
function SalesChart({ data }) {
return (
<ResponsiveContainer width="100%" height={300}>
<BarChart data={data}>
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Bar dataKey="sales" fill="#3b82f6" radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
);
}interface KPICardProps {
title: string;
value: string | number;
change: number;
trend: 'up' | 'down';
icon?: React.ReactNode;
}
function KPICard({ title, value, change, trend, icon }: KPICardProps) {
const isPositive = trend === 'up';
return (
<div className="bg-white rounded-lg p-6 shadow-sm border">
<div className="flex items-center justify-between">
<p className="text-sm font-medium text-gray-500">{title}</p>
{icon && <div className="text-gray-400">{icon}</div>}
</div>
<div className="mt-2">
<p className="text-3xl font-semibold text-gray-900">{value}</p>
<div className="mt-2 flex items-center">
<span
className={`text-sm font-medium ${
isPositive ? 'text-green-600' : 'text-red-600'
}`}
>
{isPositive ? '↑' : '↓'} {Math.abs(change)}%
</span>
<span className="ml-2 text-sm text-gray-500">vs last period</span>
</div>
</div>
</div>
);
}function Dashboard() {
return (
<div className="p-6 space-y-6">
{/* KPI Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<KPICard
title="Total Revenue"
value="$45,231"
change={12.5}
trend="up"
/>
<KPICard
title="Active Users"
value="2,345"
change={8.2}
trend="up"
/>
<KPICard
title="Conversion Rate"
value="3.2%"
change={-2.1}
trend="down"
/>
<KPICard
title="Avg. Order Value"
value="$142"
change={5.4}
trend="up"
/>
</div>
{/* Charts Grid */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="bg-white rounded-lg p-6 shadow-sm border">
<h3 className="text-lg font-medium mb-4">Revenue Over Time</h3>
<RevenueChart />
</div>
<div className="bg-white rounded-lg p-6 shadow-sm border">
<h3 className="text-lg font-medium mb-4">Sales by Category</h3>
<SalesChart data={salesData} />
</div>
</div>
</div>
);
}import { PieChart, Pie, Cell, Tooltip, Legend, ResponsiveContainer } from 'recharts';
const COLORS = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444'];
function DistributionChart({ data }) {
return (
<ResponsiveContainer width="100%" height={300}>
<PieChart>
<Pie
data={data}
cx="50%"
cy="50%"
innerRadius={60}
outerRadius={100}
dataKey="value"
label
>
{data.map((_, index) => (
<Cell key={index} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<Tooltip />
<Legend />
</PieChart>
</ResponsiveContainer>
);
}export function formatNumber(value: number): string {
if (value >= 1_000_000) {
return `${(value / 1_000_000).toFixed(1)}M`;
}
if (value >= 1_000) {
return `${(value / 1_000).toFixed(1)}K`;
}
return value.toLocaleString();
}
export function formatCurrency(value: number, currency = 'USD'): string {
return new Intl.NumberFormat('en-US', {
style: 'currency',
currency,
minimumFractionDigits: 0,
maximumFractionDigits: 0,
}).format(value);
}
export function formatPercent(value: number): string {
return `${value >= 0 ? '+' : ''}${value.toFixed(1)}%`;
}