Files
rxminder/components/ui/BarChart.tsx
William Valentin e48adbcb00 Initial commit: Complete NodeJS-native setup
- Migrated from Python pre-commit to NodeJS-native solution
- Reorganized documentation structure
- Set up Husky + lint-staged for efficient pre-commit hooks
- Fixed Dockerfile healthcheck issue
- Added comprehensive documentation index
2025-09-06 01:42:48 -07:00

113 lines
3.3 KiB
TypeScript

import React from 'react';
import { DailyStat } from '../../types';
interface BarChartProps {
data: DailyStat[];
}
const BarChart: React.FC<BarChartProps> = ({ data }) => {
const chartHeight = 150;
const barWidth = 30;
const barMargin = 15;
const chartWidth = data.length * (barWidth + barMargin);
const getDayLabel = (dateString: string) => {
const date = new Date(dateString);
const userTimezoneOffset = date.getTimezoneOffset() * 60000;
const adjustedDate = new Date(date.getTime() + userTimezoneOffset);
return adjustedDate.toLocaleDateString('en-US', { weekday: 'short' });
};
return (
<div className='w-full overflow-x-auto pb-4'>
<svg
viewBox={`0 0 ${chartWidth} ${chartHeight + 40}`}
width='100%'
height='190'
aria-labelledby='chart-title'
role='img'
>
<title id='chart-title'>Weekly Medication Adherence Chart</title>
{/* Y-Axis Labels */}
<g className='text-xs fill-current text-slate-500 dark:text-slate-400'>
<text x='-5' y='15' textAnchor='end'>
100%
</text>
<text x='-5' y={chartHeight / 2 + 5} textAnchor='end'>
50%
</text>
<text x='-5' y={chartHeight + 5} textAnchor='end'>
0%
</text>
</g>
{/* Y-Axis Grid Lines */}
<line
x1='0'
y1='10'
x2={chartWidth}
y2='10'
className='stroke-current text-slate-200 dark:text-slate-600'
strokeDasharray='2,2'
/>
<line
x1='0'
y1={chartHeight / 2 + 2.5}
x2={chartWidth}
y2={chartHeight / 2 + 2.5}
className='stroke-current text-slate-200 dark:text-slate-600'
strokeDasharray='2,2'
/>
<line
x1='0'
y1={chartHeight}
x2={chartWidth}
y2={chartHeight}
className='stroke-current text-slate-300 dark:text-slate-500'
/>
{data.map((item, index) => {
const x = index * (barWidth + barMargin);
const barHeight = (item.adherence / 100) * (chartHeight - 10);
const y = chartHeight - barHeight;
const barColorClass =
item.adherence >= 90
? 'fill-current text-green-500 dark:text-green-400'
: item.adherence >= 70
? 'fill-current text-amber-500 dark:text-amber-400'
: 'fill-current text-red-500 dark:text-red-400';
return (
<g key={item.date}>
<rect
x={x}
y={y}
width={barWidth}
height={barHeight}
rx='4'
className={barColorClass}
>
<title>
{getDayLabel(item.date)}: {item.adherence}% adherence
</title>
</rect>
<text
x={x + barWidth / 2}
y={chartHeight + 20}
textAnchor='middle'
className='text-xs fill-current text-slate-600 dark:text-slate-300 font-medium'
>
{getDayLabel(item.date)}
</text>
</g>
);
})}
</svg>
</div>
);
};
export default BarChart;