feat: Diagram integration/Nb Resistant
parent
4dba306763
commit
b0272d3733
21
src/index.ts
21
src/index.ts
|
@ -8,13 +8,15 @@ import { computeELStats } from "./statistiques/v1/computeELStats";
|
|||
import { computeStatsPenales } from "./statistiques/v2/penales/computeStatsPenales";
|
||||
import { statsPenalesDesc } from "./statistiques/v2/penales/StatsPenales";
|
||||
import { computeStatsGenerales } from "./statistiques/v2/generales/computeStatsGenerales";
|
||||
import { statsGeneralesDesc } from "./statistiques/v2/generales/StatsGenerales";
|
||||
import { computeStatsSociales } from "./statistiques/v2/sociales/computeStatsSociales";
|
||||
import { statsSocialesDesc } from "./statistiques/v2/sociales/StatsSociales";
|
||||
import { checkDbSchemas } from "./notion/fetch/schemaCheck/checkDbSchemas";
|
||||
import { computeSequencEvtPenalSankeyData } from "./statistiques/v2/penales/computeSankeyData";
|
||||
import { sankeyDataToMermaidDiagram } from "./statistiques/v2/sankey/sankeyDataToMermaidDiagram";
|
||||
import { formatDate } from "date-fns";
|
||||
import { computeStatsGeneralesMensuelles } from "./statistiques/v2/generales/computeStatsGeneralesMensuelles";
|
||||
import { mermaidDiagramStatsGeneralesMensuelles } from "./statistiques/v2/generales/mermaidDiagramStatsGeneralesMensuelles";
|
||||
import { publishStatsGenerales } from "./notion/publish/v2/publishStatsGenerales";
|
||||
|
||||
type ProcessOptions = {
|
||||
dryRun: boolean;
|
||||
|
@ -75,13 +77,20 @@ function buildProcessOptions(): ProcessOptions {
|
|||
const elStats = computeELStats(familles, currentDate);
|
||||
|
||||
const statsGenerales = computeStatsGenerales(familles);
|
||||
|
||||
const statsPenales = computeStatsPenales(familles);
|
||||
const statsSociales = computeStatsSociales(familles);
|
||||
|
||||
const statsGeneralesMensuelles = computeStatsGeneralesMensuelles(familles);
|
||||
const mermaidDiagramStatsGeneralesMensuellesCode =
|
||||
mermaidDiagramStatsGeneralesMensuelles(statsGeneralesMensuelles);
|
||||
writeFileSync(
|
||||
"./el-stats-penal-sankey-diagram.txt",
|
||||
sankeyDataToMermaidDiagram(computeSequencEvtPenalSankeyData(familles))
|
||||
);
|
||||
writeFileSync(
|
||||
"./el-stats-stats-generales-mensuel.txt",
|
||||
mermaidDiagramStatsGeneralesMensuellesCode
|
||||
);
|
||||
if (options.dryRun) {
|
||||
console.log(
|
||||
"Dry run => Skip Publishing. Stats are dumped in file el-stats-xxx.json"
|
||||
|
@ -95,6 +104,7 @@ function buildProcessOptions(): ProcessOptions {
|
|||
generales: statsGenerales,
|
||||
penales: statsPenales,
|
||||
sociales: statsSociales,
|
||||
StatsGeneralesMensuelles: statsGeneralesMensuelles,
|
||||
},
|
||||
null,
|
||||
" "
|
||||
|
@ -109,12 +119,11 @@ function buildProcessOptions(): ProcessOptions {
|
|||
Dernière mise à jour le ${formatDate(currentDate, "dd/MM/yyyy à HH:mm")}
|
||||
|
||||
`;
|
||||
await publishStatsToPage(
|
||||
await publishStatsGenerales(
|
||||
notionClient,
|
||||
"313751fb-daed-4b33-992f-c86d7ac2de37",
|
||||
header,
|
||||
statsGeneralesDesc,
|
||||
statsGenerales
|
||||
statsGenerales,
|
||||
mermaidDiagramStatsGeneralesMensuellesCode
|
||||
);
|
||||
await publishStatsToPage(
|
||||
notionClient,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
import { BlockObjectRequest } from "@notionhq/client/build/src/api-endpoints";
|
||||
|
||||
export type BulletedListItemBlockObjectRequest = Extract<
|
||||
BlockObjectRequest,
|
||||
{ bulleted_list_item: object }
|
||||
>;
|
|
@ -0,0 +1,4 @@
|
|||
import { BulletedListItemBlockObjectRequest } from "./BulletedListItemBlockObjectRequest";
|
||||
|
||||
export type BulletedListItemChildren =
|
||||
BulletedListItemBlockObjectRequest["bulleted_list_item"]["children"];
|
|
@ -0,0 +1,6 @@
|
|||
import { BlockObjectRequest } from "@notionhq/client/build/src/api-endpoints";
|
||||
|
||||
export type ParagraphBlockObjectRequest = Extract<
|
||||
BlockObjectRequest,
|
||||
{ paragraph: unknown }
|
||||
>;
|
|
@ -0,0 +1,22 @@
|
|||
import { BlockObjectRequest } from "@notionhq/client/build/src/api-endpoints";
|
||||
|
||||
export function createMermaidCodeBlock(code: string): CodeBlockObjectRequest {
|
||||
return {
|
||||
code: {
|
||||
language: "mermaid",
|
||||
rich_text: [
|
||||
{
|
||||
type: "text",
|
||||
text: {
|
||||
content: code,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export type CodeBlockObjectRequest = Extract<
|
||||
BlockObjectRequest,
|
||||
{ code: unknown }
|
||||
>;
|
|
@ -0,0 +1,17 @@
|
|||
import { ParagraphBlockObjectRequest } from "./ParagraphBlockObjectRequest";
|
||||
|
||||
export function createParagraphBlock(
|
||||
content: string
|
||||
): ParagraphBlockObjectRequest {
|
||||
return {
|
||||
paragraph: {
|
||||
rich_text: [
|
||||
{
|
||||
text: {
|
||||
content: content,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
import { BlockObjectRequest } from "@notionhq/client/build/src/api-endpoints";
|
||||
import {
|
||||
isStatGroupDesc,
|
||||
StatDesc,
|
||||
StatGroupDesc,
|
||||
StatsType,
|
||||
} from "../../../statistiques/v2/desc/StatsDesc";
|
||||
import { formatValue } from "../../../format/formatValue";
|
||||
import { createStatListItemBlock } from "./createStatListItemBlock";
|
||||
import { BulletedListItemBlockObjectRequest } from "../blocks/BulletedListItemBlockObjectRequest";
|
||||
import { BulletedListItemChildren } from "../blocks/BulletedListItemChildren";
|
||||
|
||||
export function createStatGroupListItemBlock<D extends StatGroupDesc>(
|
||||
descriptor: D,
|
||||
|
@ -28,14 +28,6 @@ export function createStatGroupListItemBlock<D extends StatGroupDesc>(
|
|||
};
|
||||
}
|
||||
|
||||
export type BulletedListItemBlockObjectRequest = Extract<
|
||||
BlockObjectRequest,
|
||||
{ bulleted_list_item: object }
|
||||
>;
|
||||
|
||||
export type BulletedListItemChildren =
|
||||
BulletedListItemBlockObjectRequest["bulleted_list_item"]["children"];
|
||||
|
||||
export function createStatGroupChildrenListItemBlock<D extends StatGroupDesc>(
|
||||
descriptor: D,
|
||||
stats: StatsType<D>
|
||||
|
@ -52,21 +44,3 @@ export function createStatGroupChildrenListItemBlock<D extends StatGroupDesc>(
|
|||
: createStatListItemBlock(childStatDesc, childStatValue as number);
|
||||
});
|
||||
}
|
||||
|
||||
function createStatListItemBlock(
|
||||
descriptor: StatDesc,
|
||||
statValue: number
|
||||
): BulletedListItemBlockObjectRequest {
|
||||
return {
|
||||
bulleted_list_item: {
|
||||
rich_text: [
|
||||
{
|
||||
text: {
|
||||
content:
|
||||
descriptor.label + ": " + formatValue(statValue, descriptor),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import { formatValue } from "../../../format/formatValue";
|
||||
import { StatDesc } from "../../../statistiques/v2/desc/StatsDesc";
|
||||
import { BulletedListItemBlockObjectRequest } from "../blocks/BulletedListItemBlockObjectRequest";
|
||||
|
||||
export function createStatListItemBlock(
|
||||
descriptor: StatDesc,
|
||||
statValue: number
|
||||
): BulletedListItemBlockObjectRequest {
|
||||
return {
|
||||
bulleted_list_item: {
|
||||
rich_text: [
|
||||
{
|
||||
text: {
|
||||
content:
|
||||
descriptor.label + ": " + formatValue(statValue, descriptor),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
import { Client } from "@notionhq/client";
|
||||
import { createMermaidCodeBlock } from "../blocks/createMermaidCodeBlock";
|
||||
import { createParagraphBlock } from "../blocks/createParagraphBlock";
|
||||
import { createStatGroupChildrenListItemBlock } from "./createStatGroupListItemBlock";
|
||||
import { updatePageContent } from "./updatePageContent";
|
||||
import {
|
||||
StatsGenerales,
|
||||
statsGeneralesDesc,
|
||||
} from "../../../statistiques/v2/generales/StatsGenerales";
|
||||
|
||||
export async function publishStatsGenerales(
|
||||
notionClient: Client,
|
||||
header: string,
|
||||
statsGenerales: StatsGenerales,
|
||||
mermaidDiagramStatsGeneralesMensuelles: string
|
||||
) {
|
||||
const headerBlock = createParagraphBlock(header);
|
||||
const statsBlocks = createStatGroupChildrenListItemBlock(
|
||||
statsGeneralesDesc,
|
||||
statsGenerales
|
||||
);
|
||||
|
||||
const diagramBlock = createMermaidCodeBlock(
|
||||
mermaidDiagramStatsGeneralesMensuelles
|
||||
);
|
||||
|
||||
const blocks = [headerBlock, ...statsBlocks, diagramBlock];
|
||||
await updatePageContent(
|
||||
notionClient,
|
||||
"313751fb-daed-4b33-992f-c86d7ac2de37",
|
||||
blocks
|
||||
);
|
||||
}
|
|
@ -5,7 +5,7 @@ import {
|
|||
} from "../../../statistiques/v2/desc/StatsDesc";
|
||||
import { createStatGroupChildrenListItemBlock } from "./createStatGroupListItemBlock";
|
||||
import { updatePageContent } from "./updatePageContent";
|
||||
import { BlockObjectRequest } from "@notionhq/client/build/src/api-endpoints";
|
||||
import { createParagraphBlock } from "../blocks/createParagraphBlock";
|
||||
|
||||
export async function publishStatsToPage<D extends StatGroupDesc>(
|
||||
notionClient: Client,
|
||||
|
@ -22,22 +22,3 @@ export async function publishStatsToPage<D extends StatGroupDesc>(
|
|||
...statsBlocks,
|
||||
]);
|
||||
}
|
||||
|
||||
type ParagraphBlockObjectRequest = Extract<
|
||||
BlockObjectRequest,
|
||||
{ paragraph: unknown }
|
||||
>;
|
||||
|
||||
function createParagraphBlock(content: string): ParagraphBlockObjectRequest {
|
||||
return {
|
||||
paragraph: {
|
||||
rich_text: [
|
||||
{
|
||||
text: {
|
||||
content: content,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { getMonth, getYear, setMonth, setYear } from "date-fns";
|
||||
import { IdentifiedPeriod } from "../../period/IdentifiedPeriod";
|
||||
import { generateConsecutiveIdentifiedPeriods } from "../../period/generateConsecutiveIdentifiedPeriods";
|
||||
import { IdentifiedPeriod } from "./IdentifiedPeriod";
|
||||
import { generateConsecutiveIdentifiedPeriods } from "./generateConsecutiveIdentifiedPeriods";
|
||||
|
||||
export function generateELMonths(): IdentifiedPeriod[] {
|
||||
const months = generateConsecutiveIdentifiedPeriods({
|
|
@ -1,6 +1,6 @@
|
|||
import { addYears } from "date-fns/fp";
|
||||
import { IdentifiedPeriod } from "../../period/IdentifiedPeriod";
|
||||
import { generateConsecutiveIdentifiedPeriods } from "../../period/generateConsecutiveIdentifiedPeriods";
|
||||
import { IdentifiedPeriod } from "./IdentifiedPeriod";
|
||||
import { generateConsecutiveIdentifiedPeriods } from "./generateConsecutiveIdentifiedPeriods";
|
||||
|
||||
export function generateELYears(): IdentifiedPeriod[] {
|
||||
return generateConsecutiveIdentifiedPeriods({
|
|
@ -2,8 +2,8 @@ import { Famille } from "../../data/Famille";
|
|||
import { computeELPeriodStats } from "./computeELPeriodStats";
|
||||
import { computeELStatsAtDate } from "./computeELStatsAtDate";
|
||||
import { ELStats } from "./ELStats";
|
||||
import { generateELMonths } from "./generateELMonths";
|
||||
import { generateELYears } from "./generateELYears";
|
||||
import { generateELMonths } from "../../period/generateELMonths";
|
||||
import { generateELYears } from "../../period/generateELYears";
|
||||
|
||||
export function computeELStats(
|
||||
families: Famille[],
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
import { Famille, isExResistant, isResistant } from "../../../data/Famille";
|
||||
import { generateELMonths } from "../../../period/generateELMonths";
|
||||
import { isPeriodContaining } from "../../../period/isPeriodContaining";
|
||||
import { Period } from "../../../period/Period";
|
||||
|
||||
export type StatsGeneralesMensuelles = {
|
||||
[month: string]: StatsGeneralesMensuelle;
|
||||
};
|
||||
|
||||
export type StatsGeneralesMensuelle = {
|
||||
nbEntrees: number;
|
||||
nbSorties: number;
|
||||
nbEntreesNet: number;
|
||||
nbFamillesResistantes: number;
|
||||
nbFamillesExResistantes: number;
|
||||
};
|
||||
|
||||
export function computeStatsGeneralesMensuelles(
|
||||
familles: Famille[]
|
||||
): StatsGeneralesMensuelles {
|
||||
const months = generateELMonths();
|
||||
return Object.fromEntries(
|
||||
months.map((period) => {
|
||||
const nbEntrees = nbEntreeSurPeriode(familles, period);
|
||||
const nbSorties = nbSortieSurPeriode(familles, period);
|
||||
const statsMensuelle: StatsGeneralesMensuelle = {
|
||||
nbEntrees: nbEntrees,
|
||||
nbSorties: nbSorties,
|
||||
nbEntreesNet: nbEntrees - nbSorties,
|
||||
nbFamillesResistantes: nbFamillesResistanteAFinPeriode(
|
||||
familles,
|
||||
period
|
||||
),
|
||||
|
||||
nbFamillesExResistantes: nbFamillesExResistanteAFinPeriode(
|
||||
familles,
|
||||
period
|
||||
),
|
||||
};
|
||||
return [period.id, statsMensuelle];
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function nbEntreeSurPeriode(familles: Famille[], period: Period): number {
|
||||
return familles.filter(
|
||||
(f) =>
|
||||
(isResistant(f) || isExResistant(f)) &&
|
||||
f.Integration &&
|
||||
isPeriodContaining(period, f.Integration)
|
||||
).length;
|
||||
}
|
||||
|
||||
function nbSortieSurPeriode(familles: Famille[], period: Period): number {
|
||||
return familles.filter(
|
||||
(f) =>
|
||||
(isResistant(f) || isExResistant(f)) &&
|
||||
f.Sortie &&
|
||||
isPeriodContaining(period, f.Sortie)
|
||||
).length;
|
||||
}
|
||||
|
||||
function nbFamillesResistanteAFinPeriode(
|
||||
familles: Famille[],
|
||||
period: Period
|
||||
): number {
|
||||
return familles.filter(
|
||||
(f) =>
|
||||
(isResistant(f) || isExResistant(f)) &&
|
||||
f.Integration &&
|
||||
f.Integration < period.end &&
|
||||
(!f.Sortie || f.Sortie > period.end)
|
||||
).length;
|
||||
}
|
||||
|
||||
function nbFamillesExResistanteAFinPeriode(
|
||||
familles: Famille[],
|
||||
period: Period
|
||||
): number {
|
||||
return familles.filter(
|
||||
(f) =>
|
||||
(isResistant(f) || isExResistant(f)) &&
|
||||
f.Integration &&
|
||||
f.Integration < period.end &&
|
||||
f.Sortie &&
|
||||
f.Sortie < period.end
|
||||
).length;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
import { StatsGeneralesMensuelles } from "./computeStatsGeneralesMensuelles";
|
||||
|
||||
export function mermaidDiagramStatsGeneralesMensuelles(
|
||||
statsGeneralesMensuelle: StatsGeneralesMensuelles
|
||||
): string {
|
||||
const statsEntries = Object.entries(statsGeneralesMensuelle);
|
||||
const entriesToDisplay = statsEntries.slice(
|
||||
statsEntries.length - 15,
|
||||
statsEntries.length
|
||||
);
|
||||
const periods = entriesToDisplay.map(([p]) => {
|
||||
const comp = p.split("-");
|
||||
// Reformat month as MM/yy
|
||||
return `"${comp[1]}/${comp[0].substring(2, 4)}"`;
|
||||
});
|
||||
return `---
|
||||
config:
|
||||
themeVariables:
|
||||
xyChart:
|
||||
plotColorPalette: "#1E88E5, #EEEEEE, #C8E6C9, #EF9A9A"
|
||||
---
|
||||
xychart-beta
|
||||
title "Familles: Résist.(bleu), Ex-Résist (gris), Entrées (vert), Sorties (rouge)"
|
||||
x-axis "Mois" [${periods}]
|
||||
y-axis "Nb Familles" 0 --> 110
|
||||
line [${entriesToDisplay.map(([, s]) => s.nbFamillesResistantes)}]
|
||||
line [${entriesToDisplay.map(([, s]) => s.nbFamillesExResistantes)}]
|
||||
line [${entriesToDisplay.map(([, s]) => s.nbEntrees)}]
|
||||
line [${entriesToDisplay.map(([, s]) => s.nbSorties)}]
|
||||
`;
|
||||
}
|
Loading…
Reference in New Issue