This commit is contained in:
2025-10-18 06:54:53 +02:00
parent 03c8429db4
commit 4e61fccf48

View File

@@ -1,10 +1,14 @@
import './style.css'; import './style.css';
import { generate } from "./individual"; import { generate } from "./individual";
import Chart from "chart.js/auto"; import Chart from "chart.js/auto";
import ChartDataLabels from "chartjs-plugin-datalabels";
import { jStat } from "jstat"; import { jStat } from "jstat";
import { MatrixController, MatrixElement } from 'chartjs-chart-matrix';
const individus = generate(1000); const individus = generate(1000);
// Fonction utilitaire pour afficher les pourcentages
const percentage = (value: number, total: number) => ((value / total) * 100).toFixed(1) + "%";
function formatStats(ages: number[]) { function formatStats(ages: number[]) {
return { return {
"total": ages.length, "total": ages.length,
@@ -35,9 +39,14 @@ function histogramData(ages: number[]) {
); );
} }
const ctx = document.getElementById("ageChart") as HTMLCanvasElement; Chart.register(ChartDataLabels,MatrixController, MatrixElement);
new Chart(ctx, { Chart.defaults.set('plugins.datalabels', {
color: "#fff",
font: { weight: "bold" }
});
new Chart(document.getElementById("ageChart") as HTMLCanvasElement, {
type: "bar", type: "bar",
data: { data: {
labels: ageClasses.map(a => `${a}-${a+2}`), labels: ageClasses.map(a => `${a}-${a+2}`),
@@ -58,6 +67,7 @@ new Chart(ctx, {
responsive: true, responsive: true,
plugins: { plugins: {
title: { display: true, text: "Distribution des âges par sexe" }, title: { display: true, text: "Distribution des âges par sexe" },
datalabels: false
}, },
scales: { scales: {
x: { stacked: false }, x: { stacked: false },
@@ -65,3 +75,157 @@ new Chart(ctx, {
}, },
}, },
}); });
const hommes = individus.filter(i => i.sexe === "M").length;
const femmes = individus.length - hommes;
new Chart(document.getElementById("genreChart") as HTMLCanvasElement, {
type: "doughnut",
data: {
labels: ["Hommes", "Femmes"],
datasets: [{
data: [hommes, femmes],
backgroundColor: ["#4A90E2", "#FF69B4"],
}],
},
options: {
plugins: { legend: { position: "bottom" },
datalabels: {
formatter: (value, context) => {
const total = context.chart.data.datasets[0].data.reduce((a: number, b: number) => a + b, 0);
return percentage(value, total);
}
}
},
},
});
const jeunes = individus.filter(i => i.age <= 30).length;
const adultes = individus.filter(i => i.age > 30 && i.age <= 60).length;
const seniors = individus.filter(i => i.age > 60).length;
new Chart(document.getElementById("classeChart") as HTMLCanvasElement, {
type: "doughnut",
data: {
labels: ["Jeunes (≤30)", "Adultes (3160)", "Seniors (>60)"],
datasets: [{
data: [jeunes, adultes, seniors],
backgroundColor: ["#81C784", "#FFD54F", "#E57373"],
}],
},
options: {
plugins: { legend: { position: "bottom" } },
},
});
new Chart(document.getElementById("wealthChart") as HTMLCanvasElement, {
type: "doughnut",
data: {
labels: ["15000", "25000", "37000", "55000"],
datasets: [{
data: [
individus.filter(i => i.richesse == 0).length,
individus.filter(i => i.richesse == 1).length,
individus.filter(i => i.richesse == 2).length,
individus.filter(i => i.richesse == 3).length,
],
backgroundColor: ["#FFE0B2",
"#FFB74D",
"#FF8A65",
"#E64A19" ],
}],
},
options: {
plugins: { legend: { position: "bottom" } },
},
});
new Chart(document.getElementById("educationChart") as HTMLCanvasElement, {
type: "doughnut",
data: {
labels: ["Bac", "+2", "+3", "+5"],
datasets: [{
data: [ individus.filter(i => i.etudes == 0).length,
individus.filter(i => i.etudes == 1).length,
individus.filter(i => i.etudes == 2).length,
individus.filter(i => i.etudes == 3).length,],
backgroundColor: ["#81C784", "#FFD54F", "#E57373"],
}],
},
options: {
plugins: { legend: { position: "bottom" } },
},
});
new Chart(document.getElementById('heatmapChart') as HTMLCanvasElement, {
type: 'matrix',
data: {
labels: individus.map((_, i) => `Individu ${i + 1}`),
datasets: [{
label: 'Activités',
data: individus.map((individu, i) => [
{ x: 0, y: i, v: individu.sport },
{ x: 1, y: i, v: individu.musique },
{ x: 2, y: i, v: individu.lecture }
]).flat(),
backgroundColor: ({ v }) => {
const r = Math.floor(255 - v * 100);
const g = Math.floor(255 - v * 50);
const b = Math.floor(255);
return `rgb(${r}, ${g}, ${b})`;
},
borderWidth: 1,
borderColor: 'rgba(255, 255, 255, 0.6)',
width: ({ chart }) => (chart.chartArea?.width ?? 0) / 3 - 1,
height: ({ chart }) => (chart.chartArea?.height ?? 0) / individus.length - 1
}]
},
options: {
responsive: true,
scales: {
x: {
type: 'category',
labels: ['Sport', 'Musique', 'Lecture'],
offset: true
},
y: {
type: 'category',
labels: individus.map((_, i) => `Individu ${i + 1}`),
offset: true
}
},
plugins: {
legend: { display: false },
tooltip: {
callbacks: {
label: ({ raw }) => `Valeur : ${raw.v.toFixed(2)}`
}
}
}
}
});
new Chart(document.getElementById("radarChart") as HTMLCanvasElement, {
type: "radar",
data: {
labels: ["Etudes", "Richesse", "Sport", "Musique", "Lecture"],
datasets: [{
label: "Valeurs moyennes",
data: [
individus[10].etudes / 3,
individus[10].richesse / 3,
individus[10].sport,
individus[10].musique,
individus[10].lecture
],
backgroundColor: "rgba(54,162,235,0.2)",
borderColor: "rgba(54,162,235,1)",
pointBackgroundColor: "rgba(54,162,235,1)"
}]
},
options: {
scales: { r: { min: 0, max: 1, ticks: { stepSize: 0.1 } } },
plugins: { legend: { position: "top" }, datalabels: false }
}
});