diff --git a/src/individus.ts b/src/individus.ts index d89c3e4..99e65a3 100644 --- a/src/individus.ts +++ b/src/individus.ts @@ -1,10 +1,14 @@ import './style.css'; import { generate } from "./individual"; import Chart from "chart.js/auto"; +import ChartDataLabels from "chartjs-plugin-datalabels"; import { jStat } from "jstat"; - +import { MatrixController, MatrixElement } from 'chartjs-chart-matrix'; 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[]) { return { "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", data: { labels: ageClasses.map(a => `${a}-${a+2}`), @@ -58,6 +67,7 @@ new Chart(ctx, { responsive: true, plugins: { title: { display: true, text: "Distribution des âges par sexe" }, + datalabels: false }, scales: { 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 (31–60)", "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 } + } +});