mirror of
https://github.com/gauvainboiche/ketapk.git
synced 2026-09-02 11:13:11 +02:00
feat: Comments translation to EN
This commit is contained in:
+2
-2
@@ -69,7 +69,7 @@ function refreshChartTheme() {
|
||||
pkChart.options.scales.x.grid.color = gridColor;
|
||||
pkChart.options.plugins.legend.labels.color = legendColor;
|
||||
|
||||
// Les couleurs de texte des zones cliniques dépendent aussi du thème (cf. chartManager.js)
|
||||
// The clinical zone text colors also depend on the theme (see chartManager.js)
|
||||
updateChartAnnotations(pkChart, currentMode, pkChart.options.scales.y.max);
|
||||
pkChart.update();
|
||||
}
|
||||
@@ -189,7 +189,7 @@ function updateSimulation() {
|
||||
const weight = parseFloat(weightInput?.value) || 70;
|
||||
const unit = document.getElementById('infusionUnitSelect')?.value || 'mg_kg_h';
|
||||
|
||||
// Avertissement de poids (30-120 kg)
|
||||
// Weight warning (30-120 kg)
|
||||
const weightWarning = document.getElementById('weightWarning');
|
||||
if (weightWarning) {
|
||||
if (weight < 30 || weight > 120) {
|
||||
|
||||
@@ -8,7 +8,7 @@ export function initCalculatorUI() {
|
||||
if (!modal || !btnOpen || !btnClose) return;
|
||||
|
||||
btnOpen.addEventListener('click', () => {
|
||||
// Utilise patientWeight à la place d'inputWeight
|
||||
// Uses patientWeight instead of inputWeight
|
||||
const mainWeight = document.getElementById('patientWeight')?.value || 70;
|
||||
const calcWeightInput = document.getElementById('calcWeight');
|
||||
if (calcWeightInput) calcWeightInput.value = mainWeight;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { CLINICAL_THRESHOLDS } from './pkCore.js';
|
||||
import { t } from './i18n.js';
|
||||
|
||||
// Les couleurs de zone sont volontairement fixes (indépendantes du thème d'interface) :
|
||||
// elles reproduisent le dégradé de référence de l'outil KetaPK original. Seul le texte
|
||||
// (zone.textHex) est choisi pour rester lisible sur cette couleur de fond opaque.
|
||||
// The zone colors are deliberately fixed (independent of the interface theme):
|
||||
// they reproduce the reference gradient of the original KetaPK tool. Only the text
|
||||
// (zone.textHex) is chosen to remain readable on this opaque background color.
|
||||
export function updateChartAnnotations(chart, mode, currentYMax) {
|
||||
const thresholds = CLINICAL_THRESHOLDS[mode];
|
||||
const annotations = {};
|
||||
@@ -36,14 +36,14 @@ export function updateChartAnnotations(chart, mode, currentYMax) {
|
||||
export function adjustChartYScale(chart, mode, datasets) {
|
||||
let highestValue = 0;
|
||||
|
||||
// Recherche de la valeur maximale atteinte parmi tous les modèles affichés
|
||||
// Find the maximum value reached among all displayed models
|
||||
datasets.forEach(ds => {
|
||||
ds.data.forEach(val => {
|
||||
if (val > highestValue) highestValue = val;
|
||||
});
|
||||
});
|
||||
|
||||
// Ajustement dynamique à 110 % de la valeur pic (ou plancher à 50 ng/mL si vide)
|
||||
// Dynamic adjustment to 110% of the peak value (or floor at 50 ng/mL if empty)
|
||||
let targetYMax = highestValue > 0 ? Math.ceil(highestValue * 1.1) : 50;
|
||||
|
||||
chart.options.scales.y.max = targetYMax;
|
||||
|
||||
@@ -28,7 +28,7 @@ export async function exportSimulationToCSV(simulationData, patientInfo) {
|
||||
|
||||
let csvContent = "\uFEFF";
|
||||
|
||||
// Métadonnées du rapport
|
||||
// Report metadata
|
||||
csvContent += `${t('csv.title')}\n`;
|
||||
if (patientInfo.name) {
|
||||
csvContent += `${t('patient.name_label') || 'Patient'}:,${patientInfo.name}\n`;
|
||||
@@ -36,10 +36,10 @@ export async function exportSimulationToCSV(simulationData, patientInfo) {
|
||||
csvContent += `${t('csv.weight')}:,${patientInfo.weight}\n`;
|
||||
csvContent += `${t('csv.unit')}:,${patientInfo.infusionUnit}\n`;
|
||||
|
||||
// Ligne de Traçabilité de Version
|
||||
// Version traceability line
|
||||
csvContent += `${t('csv.version') || 'Version'}:,v${APP_VERSION}\n\n`;
|
||||
|
||||
// En-têtes du tableau
|
||||
// Table headers
|
||||
const headers = [
|
||||
t('csv.col_time'),
|
||||
t('csv.col_bolus'),
|
||||
@@ -50,7 +50,7 @@ export async function exportSimulationToCSV(simulationData, patientInfo) {
|
||||
];
|
||||
csvContent += headers.join(",") + "\n";
|
||||
|
||||
// Lignes de données
|
||||
// Data rows
|
||||
simulationData.timeline.forEach((item, index) => {
|
||||
const dominoCp = (simulationData.domino && simulationData.domino[index]) ? Math.round(simulationData.domino[index].cp) : "N/A";
|
||||
const clementsCp = (simulationData.clements && simulationData.clements[index]) ? Math.round(simulationData.clements[index].cp) : "N/A";
|
||||
|
||||
@@ -4,7 +4,7 @@ export function generatePDFReport(pkChart, patient, mode) {
|
||||
const { jsPDF } = window.jspdf;
|
||||
const doc = new jsPDF('landscape', 'mm', 'a4');
|
||||
|
||||
// En-tête
|
||||
// Header
|
||||
doc.setFillColor(30, 41, 59);
|
||||
doc.rect(0, 0, 297, 25, 'F');
|
||||
|
||||
@@ -13,7 +13,7 @@ export function generatePDFReport(pkChart, patient, mode) {
|
||||
doc.setFont("helvetica", "bold");
|
||||
doc.text(t('pdf.title'), 14, 16);
|
||||
|
||||
// Informations Patient
|
||||
// Patient information
|
||||
doc.setTextColor(50, 50, 50);
|
||||
doc.setFontSize(10);
|
||||
doc.setFont("helvetica", "normal");
|
||||
@@ -25,11 +25,11 @@ export function generatePDFReport(pkChart, patient, mode) {
|
||||
doc.text(`${t('pdf.mode')}${mode}`, 14, 42);
|
||||
doc.text(t('pdf.patient_info', patient), 14, 49);
|
||||
|
||||
// Image du Graphique
|
||||
// Chart image
|
||||
const chartImage = pkChart.toBase64Image('image/jpeg', 1.0);
|
||||
doc.addImage(chartImage, 'JPEG', 14, 55, 268, 120);
|
||||
|
||||
// Pied de page
|
||||
// Footer
|
||||
doc.setFont("helvetica", "italic");
|
||||
doc.setFontSize(8);
|
||||
doc.setTextColor(150, 150, 150);
|
||||
|
||||
+15
-15
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* ============================================================================
|
||||
* KétaPK - Moteur Pharmacocinétique (PK/PD)
|
||||
* Modèles : Domino (1982), Clements (1981), Kamp (2020)
|
||||
* KétaPK - Pharmacokinetic Engine (PK/PD)
|
||||
* Models: Domino (1982), Clements (1981), Kamp (2020)
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Version unique de l'application (Centralisée)
|
||||
* Single application version (centralized)
|
||||
*/
|
||||
export const APP_VERSION = '0.19.0';
|
||||
|
||||
@@ -15,7 +15,7 @@ export const MODES = {
|
||||
RACEMIQUE: 'RACEMIQUE'
|
||||
};
|
||||
|
||||
// Modèles Multi-exponentiels
|
||||
// Multi-exponential models
|
||||
export const PK_MODELS = {
|
||||
DOMINO: {
|
||||
name: "Domino (1982)",
|
||||
@@ -43,7 +43,7 @@ export const PK_MODELS = {
|
||||
}
|
||||
};
|
||||
|
||||
// Zones d'effets cliniques et seuils (ng/mL)
|
||||
// Clinical effect zones and thresholds (ng/mL)
|
||||
export const CLINICAL_THRESHOLDS = {
|
||||
[MODES.ESKETAMINE]: {
|
||||
maxScale: 500,
|
||||
@@ -73,7 +73,7 @@ export const CLINICAL_THRESHOLDS = {
|
||||
}
|
||||
};
|
||||
|
||||
// Unités de perfusion supportées
|
||||
// Supported infusion units
|
||||
export const INFUSION_UNITS = {
|
||||
MG_KG_H: 'mg_kg_h', // mg/kg/h
|
||||
MCG_KG_MIN: 'mcg_kg_min',// µg/kg/min
|
||||
@@ -81,7 +81,7 @@ export const INFUSION_UNITS = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Calcule la dose en mg administrée sur un intervalle de 5 minutes
|
||||
* Calculates the dose in mg administered over a 5-minute interval
|
||||
*/
|
||||
export function calculate5MinInfusionDose(rate, unit, weight) {
|
||||
if (!rate || rate <= 0) return 0;
|
||||
@@ -99,7 +99,7 @@ export function calculate5MinInfusionDose(rate, unit, weight) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Calcul d'un bolus unique à l'instant t avec prise en compte de refDose
|
||||
* Calculation of a single bolus at time t, accounting for refDose
|
||||
*/
|
||||
export function calculateBolusCp(model, doseMg, weightKg, timeElapsedMin) {
|
||||
if (timeElapsedMin < 0 || weightKg <= 0 || !model.refDose) return 0;
|
||||
@@ -111,12 +111,12 @@ export function calculateBolusCp(model, doseMg, weightKg, timeElapsedMin) {
|
||||
const termB = B * Math.exp(-beta * timeElapsedMin);
|
||||
const termC = C * (gamma ? Math.exp(-gamma * timeElapsedMin) : 0);
|
||||
|
||||
// Division par refDose pour respecter la formule exacte de l'Excel
|
||||
// Division by refDose to match the exact Excel formula
|
||||
return (dosePerKg / refDose) * (termA + termB + termC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Propage la perfusion active sur la timeline (pas de 5 min)
|
||||
* Propagates the active infusion across the timeline (5-min steps)
|
||||
*/
|
||||
export function processTimelineEvents(timelineInputs, weightKg, infusionUnit) {
|
||||
let currentRate = 0;
|
||||
@@ -142,7 +142,7 @@ export function processTimelineEvents(timelineInputs, weightKg, infusionUnit) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convertit le débit de perfusion courant en mg/kg/min, quelle que soit l'unité saisie
|
||||
* Converts the current infusion rate to mg/kg/min, regardless of the input unit
|
||||
*/
|
||||
function infusionRateToMgKgPerMin(rate, unit, weightKg) {
|
||||
if (!rate || rate <= 0) return 0;
|
||||
@@ -160,8 +160,8 @@ function infusionRateToMgKgPerMin(rate, unit, weightKg) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Résolution exacte (méthode récursive discrétisée, cf. formule KétaPK) des bolus et
|
||||
* perfusions (à débit variable) sur la timeline, ng/mL arrondis à l'entier.
|
||||
* Exact resolution (discretized recursive method, cf. KétaPK formula) of boluses and
|
||||
* infusions (with variable rate) across the timeline, ng/mL rounded to the nearest integer.
|
||||
*/
|
||||
export function generateSimulationData({ model, weightKg, timelineInputs, infusionUnit = INFUSION_UNITS.MG_KG_H }) {
|
||||
const processedTimeline = processTimelineEvents(timelineInputs, weightKg, infusionUnit);
|
||||
@@ -191,7 +191,7 @@ export function generateSimulationData({ model, weightKg, timelineInputs, infusi
|
||||
if (!nextEvent) return;
|
||||
|
||||
const deltaT = nextEvent.time - event.time;
|
||||
// Excel applique le débit déclaré à la fin de l'intervalle (colonne d'arrivée), pas celui du départ
|
||||
// Excel applies the declared rate at the end of the interval (arrival column), not the starting one
|
||||
const Rn = infusionRateToMgKgPerMin(nextEvent.infusionRate, infusionUnit, weightKg) / refDose;
|
||||
|
||||
const Falpha = Math.exp(-alpha * deltaT);
|
||||
@@ -209,7 +209,7 @@ export function generateSimulationData({ model, weightKg, timelineInputs, infusi
|
||||
return cpResults;
|
||||
}
|
||||
|
||||
// Moteur de conversion de doses
|
||||
// Dose conversion engine
|
||||
export const CalculatorEngine = {
|
||||
mgToMgKg: (mg, weight) => (weight > 0 ? mg / weight : 0),
|
||||
mgKgToMg: (mgKg, weight) => mgKg * weight,
|
||||
|
||||
Reference in New Issue
Block a user