Update style improvements and minor fixes
This commit is contained in:
@@ -12,6 +12,27 @@
|
||||
import React from 'react';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ReferenceLine, ResponsiveContainer } from 'recharts';
|
||||
|
||||
// Chart color scheme
|
||||
const CHART_COLORS = {
|
||||
// d-Amphetamine profiles
|
||||
idealDamph: '#2563eb', // blue-600 (primary, solid, bold)
|
||||
deviatedDamph: '#f59e0b', // amber-500 (warning, dashed)
|
||||
correctedDamph: '#10b981', // emerald-500 (success, dash-dot)
|
||||
|
||||
// Lisdexamfetamine profiles
|
||||
idealLdx: '#7c3aed', // violet-600 (primary, dashed)
|
||||
deviatedLdx: '#f97316', // orange-500 (warning, dashed)
|
||||
correctedLdx: '#059669', // emerald-600 (success, dash-dot)
|
||||
|
||||
// Reference lines
|
||||
therapeuticMin: '#22c55e', // green-500
|
||||
therapeuticMax: '#ef4444', // red-500
|
||||
dayDivider: '#9ca3af', // gray-400
|
||||
|
||||
// Tooltip cursor
|
||||
cursor: '#6b7280' // gray-500
|
||||
} as const;
|
||||
|
||||
const SimulationChart = ({
|
||||
idealProfile,
|
||||
deviatedProfile,
|
||||
@@ -46,11 +67,47 @@ const SimulationChart = ({
|
||||
return [domainMin, domainMax];
|
||||
}, [yAxisMin, yAxisMax]);
|
||||
|
||||
// Merge all profiles into a single dataset for proper tooltip synchronization
|
||||
const mergedData = React.useMemo(() => {
|
||||
const dataMap = new Map();
|
||||
|
||||
// Add ideal profile data
|
||||
idealProfile?.forEach((point: any) => {
|
||||
dataMap.set(point.timeHours, {
|
||||
timeHours: point.timeHours,
|
||||
idealDamph: point.damph,
|
||||
idealLdx: point.ldx
|
||||
});
|
||||
});
|
||||
|
||||
// Add deviated profile data
|
||||
deviatedProfile?.forEach((point: any) => {
|
||||
const existing = dataMap.get(point.timeHours) || { timeHours: point.timeHours };
|
||||
dataMap.set(point.timeHours, {
|
||||
...existing,
|
||||
deviatedDamph: point.damph,
|
||||
deviatedLdx: point.ldx
|
||||
});
|
||||
});
|
||||
|
||||
// Add corrected profile data
|
||||
correctedProfile?.forEach((point: any) => {
|
||||
const existing = dataMap.get(point.timeHours) || { timeHours: point.timeHours };
|
||||
dataMap.set(point.timeHours, {
|
||||
...existing,
|
||||
correctedDamph: point.damph,
|
||||
correctedLdx: point.ldx
|
||||
});
|
||||
});
|
||||
|
||||
return Array.from(dataMap.values()).sort((a, b) => a.timeHours - b.timeHours);
|
||||
}, [idealProfile, deviatedProfile, correctedProfile]);
|
||||
|
||||
return (
|
||||
<div className="flex-grow w-full overflow-x-auto">
|
||||
<div className="flex-grow w-full overflow-x-auto overflow-y-hidden">
|
||||
<div style={{ width: `${chartWidthPercentage}%`, height: '100%', minWidth: '100%' }}>
|
||||
<ResponsiveContainer width="100%" height="100%">
|
||||
<LineChart margin={{ top: 20, right: 20, left: 0, bottom: 5 }}>
|
||||
<LineChart data={mergedData} margin={{ top: 20, right: 20, left: 0, bottom: 5 }}>
|
||||
<CartesianGrid strokeDasharray="3 3" />
|
||||
<XAxis
|
||||
dataKey="timeHours"
|
||||
@@ -76,14 +133,18 @@ const SimulationChart = ({
|
||||
<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}`}
|
||||
wrapperStyle={{ pointerEvents: 'none', zIndex: 200 }}
|
||||
allowEscapeViewBox={{ x: false, y: false }}
|
||||
cursor={{ stroke: CHART_COLORS.cursor, strokeWidth: 1, strokeDasharray: '1 1' }}
|
||||
position={{ y: 0 }}
|
||||
/>
|
||||
<Legend verticalAlign="top" height={36} />
|
||||
<Legend verticalAlign="top" align="left" height={36} wrapperStyle={{ zIndex: 100, marginLeft: 60 }} />
|
||||
|
||||
{(chartView === 'damph' || chartView === 'both') && (
|
||||
<ReferenceLine
|
||||
y={parseFloat(therapeuticRange.min) || 0}
|
||||
label={{ value: t.min, position: 'insideTopLeft' }}
|
||||
stroke="green"
|
||||
stroke={CHART_COLORS.therapeuticMin}
|
||||
strokeDasharray="3 3"
|
||||
xAxisId="hours"
|
||||
/>
|
||||
@@ -92,7 +153,7 @@ const SimulationChart = ({
|
||||
<ReferenceLine
|
||||
y={parseFloat(therapeuticRange.max) || 0}
|
||||
label={{ value: t.max, position: 'insideTopLeft' }}
|
||||
stroke="red"
|
||||
stroke={CHART_COLORS.therapeuticMax}
|
||||
strokeDasharray="3 3"
|
||||
xAxisId="hours"
|
||||
/>
|
||||
@@ -103,7 +164,7 @@ const SimulationChart = ({
|
||||
<ReferenceLine
|
||||
key={day}
|
||||
x={day * 24}
|
||||
stroke="#999"
|
||||
stroke={CHART_COLORS.dayDivider}
|
||||
strokeDasharray="5 5"
|
||||
xAxisId="hours"
|
||||
/>
|
||||
@@ -113,80 +174,80 @@ const SimulationChart = ({
|
||||
{(chartView === 'damph' || chartView === 'both') && (
|
||||
<Line
|
||||
type="monotone"
|
||||
data={idealProfile}
|
||||
dataKey="damph"
|
||||
dataKey="idealDamph"
|
||||
name={`${t.dAmphetamine} (Ideal)`}
|
||||
stroke="#3b82f6"
|
||||
stroke={CHART_COLORS.idealDamph}
|
||||
strokeWidth={2.5}
|
||||
dot={false}
|
||||
xAxisId="hours"
|
||||
connectNulls
|
||||
/>
|
||||
)}
|
||||
{(chartView === 'ldx' || chartView === 'both') && (
|
||||
<Line
|
||||
type="monotone"
|
||||
data={idealProfile}
|
||||
dataKey="ldx"
|
||||
dataKey="idealLdx"
|
||||
name={`${t.lisdexamfetamine} (Ideal)`}
|
||||
stroke="#8b5cf6"
|
||||
stroke={CHART_COLORS.idealLdx}
|
||||
strokeWidth={2}
|
||||
dot={false}
|
||||
strokeDasharray="3 3"
|
||||
xAxisId="hours"
|
||||
connectNulls
|
||||
/>
|
||||
)}
|
||||
|
||||
{deviatedProfile && (chartView === 'damph' || chartView === 'both') && (
|
||||
<Line
|
||||
type="monotone"
|
||||
data={deviatedProfile}
|
||||
dataKey="damph"
|
||||
dataKey="deviatedDamph"
|
||||
name={`${t.dAmphetamine} (Deviation)`}
|
||||
stroke="#f59e0b"
|
||||
stroke={CHART_COLORS.deviatedDamph}
|
||||
strokeWidth={2}
|
||||
strokeDasharray="5 5"
|
||||
dot={false}
|
||||
xAxisId="hours"
|
||||
connectNulls
|
||||
/>
|
||||
)}
|
||||
{deviatedProfile && (chartView === 'ldx' || chartView === 'both') && (
|
||||
<Line
|
||||
type="monotone"
|
||||
data={deviatedProfile}
|
||||
dataKey="ldx"
|
||||
dataKey="deviatedLdx"
|
||||
name={`${t.lisdexamfetamine} (Deviation)`}
|
||||
stroke="#f97316"
|
||||
stroke={CHART_COLORS.deviatedLdx}
|
||||
strokeWidth={1.5}
|
||||
strokeDasharray="5 5"
|
||||
dot={false}
|
||||
xAxisId="hours"
|
||||
connectNulls
|
||||
/>
|
||||
)}
|
||||
|
||||
{correctedProfile && (chartView === 'damph' || chartView === 'both') && (
|
||||
<Line
|
||||
type="monotone"
|
||||
data={correctedProfile}
|
||||
dataKey="damph"
|
||||
dataKey="correctedDamph"
|
||||
name={`${t.dAmphetamine} (Correction)`}
|
||||
stroke="#10b981"
|
||||
stroke={CHART_COLORS.correctedDamph}
|
||||
strokeWidth={2.5}
|
||||
strokeDasharray="3 7"
|
||||
dot={false}
|
||||
xAxisId="hours"
|
||||
connectNulls
|
||||
/>
|
||||
)}
|
||||
{correctedProfile && (chartView === 'ldx' || chartView === 'both') && (
|
||||
<Line
|
||||
type="monotone"
|
||||
data={correctedProfile}
|
||||
dataKey="ldx"
|
||||
dataKey="correctedLdx"
|
||||
name={`${t.lisdexamfetamine} (Correction)`}
|
||||
stroke="#059669"
|
||||
stroke={CHART_COLORS.correctedLdx}
|
||||
strokeWidth={2}
|
||||
strokeDasharray="3 7"
|
||||
dot={false}
|
||||
xAxisId="hours"
|
||||
connectNulls
|
||||
/>
|
||||
)}
|
||||
</LineChart>
|
||||
|
||||
Reference in New Issue
Block a user