Update migrated js to ts and shadcn

This commit is contained in:
2025-11-26 20:00:39 +00:00
parent d5938046a2
commit 551ba9fd62
51 changed files with 1702 additions and 937 deletions

View File

@@ -0,0 +1,186 @@
import React from 'react';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ReferenceLine, ResponsiveContainer } from 'recharts';
const SimulationChart = ({
idealProfile,
deviatedProfile,
correctedProfile,
chartView,
showDayTimeOnXAxis,
therapeuticRange,
simulationDays,
displayedDays,
yAxisMin,
yAxisMax,
t
}: any) => {
const totalHours = (parseInt(simulationDays, 10) || 3) * 24;
// Generate ticks for continuous time axis (every 6 hours)
const chartTicks = React.useMemo(() => {
const ticks = [];
for (let i = 0; i <= totalHours; i += 6) {
ticks.push(i);
}
return ticks;
}, [totalHours]);
const chartWidthPercentage = Math.max(100, (totalHours / ( (parseInt(displayedDays, 10) || 2) * 25)) * 100);
const chartDomain = React.useMemo(() => {
const numMin = parseFloat(yAxisMin);
const numMax = parseFloat(yAxisMax);
const domainMin = !isNaN(numMin) ? numMin : 'auto';
const domainMax = !isNaN(numMax) ? numMax : 'auto';
return [domainMin, domainMax];
}, [yAxisMin, yAxisMax]);
return (
<div className="flex-grow w-full overflow-x-auto">
<div style={{ width: `${chartWidthPercentage}%`, height: '100%', minWidth: '100%' }}>
<ResponsiveContainer width="100%" height="100%">
<LineChart margin={{ top: 20, right: 20, left: 0, bottom: 5 }}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="timeHours"
type="number"
domain={[0, totalHours]}
ticks={chartTicks}
tickFormatter={(h) => {
if (showDayTimeOnXAxis) {
// Show 24h repeating format (0-23h)
return `${h % 24}${t.hour}`;
} else {
// Show continuous time (0, 6, 12, 18, 24, 30, 36, ...)
return `${h}${t.hour}`;
}
}}
xAxisId="hours"
/>
<YAxis
label={{ value: t.concentration, angle: -90, position: 'insideLeft', offset: -10 }}
domain={chartDomain as any}
allowDecimals={false}
/>
<Tooltip
formatter={(value: any, name) => [`${typeof value === 'number' ? value.toFixed(1) : value} ${t.ngml}`, name]}
labelFormatter={(label) => `${t.hour.replace('h', 'Hour')}: ${label}${t.hour}`}
/>
<Legend verticalAlign="top" height={36} />
{(chartView === 'damph' || chartView === 'both') && (
<ReferenceLine
y={parseFloat(therapeuticRange.min) || 0}
label={{ value: t.min, position: 'insideTopLeft' }}
stroke="green"
strokeDasharray="3 3"
xAxisId="hours"
/>
)}
{(chartView === 'damph' || chartView === 'both') && (
<ReferenceLine
y={parseFloat(therapeuticRange.max) || 0}
label={{ value: t.max, position: 'insideTopLeft' }}
stroke="red"
strokeDasharray="3 3"
xAxisId="hours"
/>
)}
{[...Array(parseInt(simulationDays, 10) || 0).keys()].map(day => (
day > 0 && (
<ReferenceLine
key={day}
x={day * 24}
stroke="#999"
strokeDasharray="5 5"
xAxisId="hours"
/>
)
))}
{(chartView === 'damph' || chartView === 'both') && (
<Line
type="monotone"
data={idealProfile}
dataKey="damph"
name={`${t.dAmphetamine} (Ideal)`}
stroke="#3b82f6"
strokeWidth={2.5}
dot={false}
xAxisId="hours"
/>
)}
{(chartView === 'ldx' || chartView === 'both') && (
<Line
type="monotone"
data={idealProfile}
dataKey="ldx"
name={`${t.lisdexamfetamine} (Ideal)`}
stroke="#8b5cf6"
strokeWidth={2}
dot={false}
strokeDasharray="3 3"
xAxisId="hours"
/>
)}
{deviatedProfile && (chartView === 'damph' || chartView === 'both') && (
<Line
type="monotone"
data={deviatedProfile}
dataKey="damph"
name={`${t.dAmphetamine} (Deviation)`}
stroke="#f59e0b"
strokeWidth={2}
strokeDasharray="5 5"
dot={false}
xAxisId="hours"
/>
)}
{deviatedProfile && (chartView === 'ldx' || chartView === 'both') && (
<Line
type="monotone"
data={deviatedProfile}
dataKey="ldx"
name={`${t.lisdexamfetamine} (Deviation)`}
stroke="#f97316"
strokeWidth={1.5}
strokeDasharray="5 5"
dot={false}
xAxisId="hours"
/>
)}
{correctedProfile && (chartView === 'damph' || chartView === 'both') && (
<Line
type="monotone"
data={correctedProfile}
dataKey="damph"
name={`${t.dAmphetamine} (Correction)`}
stroke="#10b981"
strokeWidth={2.5}
strokeDasharray="3 7"
dot={false}
xAxisId="hours"
/>
)}
{correctedProfile && (chartView === 'ldx' || chartView === 'both') && (
<Line
type="monotone"
data={correctedProfile}
dataKey="ldx"
name={`${t.lisdexamfetamine} (Correction)`}
stroke="#059669"
strokeWidth={2}
strokeDasharray="3 7"
dot={false}
xAxisId="hours"
/>
)}
</LineChart>
</ResponsiveContainer>
</div>
</div>
);
};export default SimulationChart;