tt / src /components /Charts.jsx
Mohassin's picture
fkk
8153b56
Raw
History Blame Contribute Delete
9.27 kB
import {
BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend,
LineChart, Line, PieChart, Pie, Cell, AreaChart, Area,
} from "recharts";
const GRID_COLOR = "hsl(210,30%,88%)";
const PALETTES = {
ocean: ["#0ea5e9", "#38bdf8", "#7dd3fc", "#0284c7", "#0369a1", "#bae6fd", "#075985", "#e0f2fe", "#0c4a6e", "#67e8f9"],
sunset: ["#f97316", "#fb923c", "#fdba74", "#ea580c", "#c2410c", "#fed7aa", "#9a3412", "#ffedd5", "#f59e0b", "#fbbf24"],
forest: ["#10b981", "#34d399", "#6ee7b7", "#059669", "#047857", "#a7f3d0", "#065f46", "#d1fae5", "#14b8a6", "#2dd4bf"],
berry: ["#8b5cf6", "#a78bfa", "#c4b5fd", "#7c3aed", "#6d28d9", "#ddd6fe", "#5b21b6", "#ede9fe", "#a855f7", "#c084fc"],
coral: ["#f43f5e", "#fb7185", "#fda4af", "#e11d48", "#be123c", "#fecdd3", "#9f1239", "#ffe4e6", "#ef4444", "#f87171"],
teal: ["#14b8a6", "#2dd4bf", "#5eead4", "#0d9488", "#0f766e", "#99f6e4", "#115e59", "#ccfbf1", "#06b6d4", "#22d3ee"],
};
const formatDownloads = (value) => {
if (value >= 1e9) return `${(value / 1e9).toFixed(1)}B`;
if (value >= 1e6) return `${(value / 1e6).toFixed(0)}M`;
if (value >= 1e3) return `${(value / 1e3).toFixed(0)}K`;
return value.toString();
};
const tooltipStyle = (bg, border) => ({
backgroundColor: bg,
border: `1px solid ${border}`,
borderRadius: "8px",
boxShadow: "0 4px 12px rgba(0,0,0,0.08)",
fontSize: "12px",
});
const topExtensionsData = [
{ name: "Python", downloads: 191868922 },
{ name: "Pylance", downloads: 159723850 },
{ name: "Jupyter", downloads: 97904194 },
{ name: "Python Debugger", downloads: 97177985 },
{ name: "C/C++", downloads: 90573086 },
{ name: "Jupyter Keymap", downloads: 77742068 },
{ name: "Live Server", downloads: 70873297 },
{ name: "Prettier", downloads: 62779089 },
{ name: "GitHub Copilot", downloads: 58940446 },
{ name: "IntelliCode", downloads: 59951008 },
];
export const TopExtensionsChart = () => (
<ResponsiveContainer width="100%" height={400}>
<BarChart data={topExtensionsData} layout="vertical" margin={{ left: 100, right: 30 }}>
<CartesianGrid strokeDasharray="3 3" stroke={GRID_COLOR} />
<XAxis type="number" tickFormatter={formatDownloads} fontSize={12} stroke="#64748b" />
<YAxis type="category" dataKey="name" fontSize={11} width={95} stroke="#64748b" />
<Tooltip formatter={(value) => [formatDownloads(value), "Downloads"]} contentStyle={tooltipStyle("#f0f9ff", "#bae6fd")} />
<Bar dataKey="downloads" radius={[0, 6, 6, 0]}>
{topExtensionsData.map((_, i) => (
<Cell key={i} fill={PALETTES.ocean[i % PALETTES.ocean.length]} />
))}
</Bar>
</BarChart>
</ResponsiveContainer>
);
const trendData = [
{ year: 2015, count: 259 },
{ year: 2016, count: 814 },
{ year: 2017, count: 1236 },
{ year: 2018, count: 1285 },
{ year: 2019, count: 1400 },
{ year: 2020, count: 1441 },
{ year: 2021, count: 1199 },
{ year: 2022, count: 815 },
{ year: 2023, count: 628 },
{ year: 2024, count: 330 },
{ year: 2025, count: 131 },
];
export const TrendChart = () => (
<ResponsiveContainer width="100%" height={350}>
<AreaChart data={trendData} margin={{ left: 10, right: 30 }}>
<defs>
<linearGradient id="sunsetGrad" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor="#f97316" stopOpacity={0.3} />
<stop offset="95%" stopColor="#f97316" stopOpacity={0.02} />
</linearGradient>
</defs>
<CartesianGrid strokeDasharray="3 3" stroke={GRID_COLOR} />
<XAxis dataKey="year" fontSize={12} stroke="#64748b" />
<YAxis fontSize={12} stroke="#64748b" />
<Tooltip contentStyle={tooltipStyle("#fff7ed", "#fed7aa")} />
<Area type="monotone" dataKey="count" stroke="#f97316" strokeWidth={2.5} fill="url(#sunsetGrad)" dot={{ r: 5, fill: "#f97316", strokeWidth: 2, stroke: "#ffedd5" }} activeDot={{ r: 7, fill: "#ea580c" }} name="Extensions Released" />
</AreaChart>
</ResponsiveContainer>
);
const categoryData = [
{ name: "Programming Languages", value: 3200 },
{ name: "Snippets", value: 1800 },
{ name: "Linters", value: 1100 },
{ name: "Debuggers", value: 950 },
{ name: "Themes", value: 870 },
{ name: "Formatters", value: 620 },
{ name: "Extension Packs", value: 480 },
{ name: "Data Science", value: 410 },
{ name: "Machine Learning", value: 350 },
{ name: "Testing", value: 290 },
{ name: "Education", value: 210 },
{ name: "AI/Chat", value: 180 },
];
export const CategoryDistributionChart = () => (
<ResponsiveContainer width="100%" height={420}>
<BarChart data={categoryData} layout="vertical" margin={{ left: 130, right: 30 }}>
<CartesianGrid strokeDasharray="3 3" stroke={GRID_COLOR} />
<XAxis type="number" fontSize={12} stroke="#64748b" />
<YAxis type="category" dataKey="name" fontSize={11} width={125} stroke="#64748b" />
<Tooltip contentStyle={tooltipStyle("#ecfdf5", "#a7f3d0")} />
<Bar dataKey="value" radius={[0, 6, 6, 0]} name="Extensions">
{categoryData.map((_, i) => (
<Cell key={i} fill={PALETTES.forest[i % PALETTES.forest.length]} />
))}
</Bar>
</BarChart>
</ResponsiveContainer>
);
const publisherData = [
{ name: "Microsoft", downloads: 1069993609 },
{ name: "Ritwick Dey", downloads: 70873297 },
{ name: "Prettier", downloads: 62779089 },
{ name: "GitHub", downloads: 58940446 },
];
export const TopPublishersChart = () => (
<ResponsiveContainer width="100%" height={320}>
<PieChart>
<Pie data={publisherData} cx="50%" cy="50%" outerRadius={110} innerRadius={50} dataKey="downloads" nameKey="name" label={({ name, percent }) => `${name} ${(percent * 100).toFixed(1)}%`} fontSize={12} stroke="#faf5ff" strokeWidth={3}>
{publisherData.map((_, i) => (
<Cell key={i} fill={PALETTES.berry[i]} />
))}
</Pie>
<Tooltip formatter={(value) => [formatDownloads(value), "Downloads"]} contentStyle={tooltipStyle("#faf5ff", "#ddd6fe")} />
<Legend />
</PieChart>
</ResponsiveContainer>
);
const aiData = [
{ name: "Non-AI", value: 8200 },
{ name: "AI-Powered", value: 1338 },
];
export const AiVsNonAiChart = () => (
<ResponsiveContainer width="100%" height={320}>
<PieChart>
<Pie data={aiData} cx="50%" cy="50%" outerRadius={100} innerRadius={55} dataKey="value" nameKey="name" label={({ name, percent }) => `${name} ${(percent * 100).toFixed(1)}%`} fontSize={12} stroke="#fff1f2" strokeWidth={3}>
<Cell fill="#f43f5e" />
<Cell fill="#fda4af" />
</Pie>
<Tooltip contentStyle={tooltipStyle("#fff1f2", "#fecdd3")} />
<Legend />
</PieChart>
</ResponsiveContainer>
);
const reviewData = [
{ name: "Python", reviews: 1250 },
{ name: "C/C++", reviews: 980 },
{ name: "Live Server", reviews: 870 },
{ name: "Prettier", reviews: 760 },
{ name: "GitHub Copilot", reviews: 720 },
{ name: "Pylance", reviews: 650 },
{ name: "IntelliCode", reviews: 580 },
{ name: "Jupyter", reviews: 520 },
];
export const HighestReviewsChart = () => (
<ResponsiveContainer width="100%" height={350}>
<BarChart data={reviewData} layout="vertical" margin={{ left: 100, right: 30 }}>
<CartesianGrid strokeDasharray="3 3" stroke={GRID_COLOR} />
<XAxis type="number" fontSize={12} stroke="#64748b" />
<YAxis type="category" dataKey="name" fontSize={11} width={95} stroke="#64748b" />
<Tooltip contentStyle={tooltipStyle("#f0fdfa", "#99f6e4")} />
<Bar dataKey="reviews" radius={[0, 6, 6, 0]} name="Reviews">
{reviewData.map((_, i) => (
<Cell key={i} fill={PALETTES.teal[i % PALETTES.teal.length]} />
))}
</Bar>
</BarChart>
</ResponsiveContainer>
);
const scatterData = [
{ name: "Python", downloads: 191, reviews: 1250 },
{ name: "Pylance", downloads: 159, reviews: 650 },
{ name: "Jupyter", downloads: 97, reviews: 520 },
{ name: "C/C++", downloads: 90, reviews: 980 },
{ name: "Live Server", downloads: 70, reviews: 870 },
{ name: "Prettier", downloads: 62, reviews: 760 },
{ name: "GitHub Copilot", downloads: 58, reviews: 720 },
{ name: "IntelliCode", downloads: 59, reviews: 580 },
];
export const DownloadsVsReviewsChart = () => (
<ResponsiveContainer width="100%" height={350}>
<BarChart data={scatterData} margin={{ left: 20, right: 20 }}>
<CartesianGrid strokeDasharray="3 3" stroke={GRID_COLOR} />
<XAxis dataKey="name" fontSize={11} angle={-20} textAnchor="end" height={60} stroke="#64748b" />
<YAxis yAxisId="left" orientation="left" fontSize={12} stroke="#64748b" label={{ value: "Downloads (M)", angle: -90, position: "insideLeft", style: { fontSize: 11, fill: "#64748b" } }} />
<YAxis yAxisId="right" orientation="right" fontSize={12} stroke="#64748b" label={{ value: "Reviews", angle: 90, position: "insideRight", style: { fontSize: 11, fill: "#64748b" } }} />
<Tooltip contentStyle={tooltipStyle("#f8fafc", "#e2e8f0")} />
<Legend />
<Bar yAxisId="left" dataKey="downloads" fill="#6366f1" name="Downloads (M)" radius={[4, 4, 0, 0]} />
<Bar yAxisId="right" dataKey="reviews" fill="#f59e0b" name="Reviews" radius={[4, 4, 0, 0]} />
</BarChart>
</ResponsiveContainer>
);