Graphe pyramide des ages

This commit is contained in:
2025-10-17 20:44:32 +02:00
parent 0d1ebd1020
commit 43ded8e883
5 changed files with 74 additions and 55 deletions

View File

@@ -1,5 +1,9 @@
import { jStat } from "jstat";
/**
* @param tableau
* @returns un élémént pris au hasard dans le tableau
*/
function randomChoice(ens:Array<any>) {
return ens[Math.floor(Math.random() * ens.length)];
}
@@ -9,17 +13,18 @@ function choiceAge() {
if (r < 0.35) {
const age = jStat.normal.sample(25, 4);
return Math.min(30, Math.max(18, Math.round(age)));
return Math.min(40, Math.max(18, Math.round(age)));
}
if (r < 0.75) {
const age = jStat.normal.sample(40, 6);
const age = jStat.normal.sample(46, 6);
return Math.min(60, Math.max(31, Math.round(age)));
}
const age = jStat.normal.sample(66, 5);
return Math.min(78, Math.max(61, Math.round(age)));
const age = jStat.normal.sample(62, 5);
return Math.min(78, Math.max(55, Math.round(age)));
}
function randomFirstName(sex:string, age:number) {
const pool = [
[
@@ -27,10 +32,11 @@ function randomFirstName(sex:string, age:number) {
"Tom","Medhi","Evan","Sacha","Rayan","Mathis","Enzo","Théo","Isaac","Liam"
],
[ "Julien","Maxime","Alexandre","Pierre","Antoine","Romain","Jérémy","Kevin","Nicolas","Benjamin",
"Florian","Vincent","Michaël","Samuel","Baptiste","Yann","Cédric","Quentin","Thomas","Adrien"
"Florian","Vincent","Michaël","Samuel","Baptiste","Yann","Cédric","Quentin","Thomas","Adrien",
"Emmanuel", "Marc", "Sébastien", "Olivier", "Laurent"
],
[ "Jean","Michel","Christian","Philippe","Daniel","Patrick","Bernard","Alain","Jacques","Guy",
"Louis","André","Roger","Maurice","Robert","Henri","Marc","Gérard","Serge","Raymond"
"Louis","André","Roger","Maurice","Robert","Henri","François","Gérard","Serge","Raymond", "Didier"
]
],
[
@@ -38,7 +44,8 @@ function randomFirstName(sex:string, age:number) {
"Camille","Nina","Darya","Léna","Louise","Inès","Julia","Samia","Clara","Maya"
],
[ "Marine","Laura","Céline","Charlotte","Elodie","Marion","Sophie","Julie","Amélie","Amandine",
"Valérie","Aurélie","Isabelle","Caroline","Sonia","Laurence","Cécile","Stéphanie","Sandrine","Emilie"
"Valérie","Aurélie","Isabelle","Caroline","Sonia","Laurence","Cécile","Stéphanie","Sandrine","Emilie",
"Hélène", "Myriam", "Murielle"
],
[ "Marie","Monique","Françoise","Denise","Nicole","Pierrette","Madeleine","Colette","Agnès","Simone",
"Geneviève","Jacqueline","Jeanne","Yvonne","Raymonde","Thérèse","Lucienne","Gisèle","Marguerite","Suzanne"
@@ -46,14 +53,16 @@ function randomFirstName(sex:string, age:number) {
]
];
let a = 2;
const ageGroups = [
{ max: 30, index: 0 },
{ max: 50, index: 1 },
{ max: Infinity, index: 2 }
];
if (age <= 30)
a = 0;
else if (age <= 50)
a = 1;
const p = ageGroups.find(g => age <= g.max)?.index ?? 2;
const s = sex === 'M' ? 0 : 1;
return randomChoice(pool[sex == 'M' ? 0 : 1][a]);
return randomChoice(pool[s][p]);
}
function randomSex(age:number) {

View File

@@ -1,16 +1,33 @@
// src/main.ts
import './style.css';
import { generate } from "./individual";
import Chart from "chart.js/auto";
import { jStat } from "jstat";
const individus = generate(1000);
console.log(individus);
function formatStats(ages: number[]) {
return {
"total": ages.length,
"mean": jStat.mean(ages).toFixed(1),
"median": jStat.median(ages).toFixed(1),
"ecart": jStat.stdev(ages).toFixed(1),
"min": Math.min(...ages),
"max": Math.max(...ages)
};
}
const Ages:number[] = individus.map(i => i.age);
// Séparer les âges par sexe
const agesH = individus.filter(i => i.sexe === "M").map(i => i.age);
const agesF = individus.filter(i => i.sexe === "F").map(i => i.age);
const AgesH = individus.filter(i => i.sexe === "M").map(i => i.age);
const AgesF = individus.filter(i => i.sexe === "F").map(i => i.age);
const stats = formatStats(Ages);
for (const [key, value] of Object.entries(stats)) {
document.getElementById(key)!.innerText = value.toString();
}
// Construire des classes d'âge
const ageClasses = Array.from({ length: 13 }, (_, i) => i * 5 + 18); // [10,20,30,...,70]
const ageClasses = Array.from({ length: 20 }, (_, i) => i * 3 + 18);
function histogramData(ages: number[]) {
return ageClasses.map((a, idx) =>
@@ -23,16 +40,16 @@ const ctx = document.getElementById("ageChart") as HTMLCanvasElement;
new Chart(ctx, {
type: "bar",
data: {
labels: ageClasses.map(a => `${a}-${a+9}`),
labels: ageClasses.map(a => `${a}-${a+2}`),
datasets: [
{
label: "Hommes",
data: histogramData(agesH),
data: histogramData(AgesH),
backgroundColor: "rgba(54, 162, 235, 0.6)",
},
{
label: "Femmes",
data: histogramData(agesF),
data: histogramData(AgesF),
backgroundColor: "rgba(255, 99, 132, 0.6)",
}
],

View File

@@ -1,4 +1,4 @@
import './style.css'
import './style.css';
import Graph from "graphology";
import Sigma from "sigma";
import forceAtlas2 from "graphology-layout-forceatlas2";

View File

@@ -13,6 +13,14 @@
-moz-osx-font-smoothing: grayscale;
}
.strong {
font-weight: 700;
}
.number {
text-align: right;
}
a {
font-weight: 500;
color: #646cff;
@@ -22,18 +30,6 @@ a:hover {
color: #535bf2;
}
body {
margin: 0;
display: flex;
place-items: center;
min-width: 320px;
min-height: 100vh;
}
h1 {
font-size: 3.2em;
line-height: 1.1;
}
#app {
width: 100vw;
@@ -41,26 +37,6 @@ h1 {
background: white
}
.logo {
height: 6em;
padding: 1.5em;
will-change: filter;
transition: filter 300ms;
}
.logo:hover {
filter: drop-shadow(0 0 2em #646cffaa);
}
.logo.vanilla:hover {
filter: drop-shadow(0 0 2em #3178c6aa);
}
.card {
padding: 2em;
}
.read-the-docs {
color: #888;
}
button {
border-radius: 8px;