Files
Pat-Manager/src/components/Analysis/TrendChart.jsx
2026-03-23 20:49:30 +01:00

60 lines
2.5 KiB
JavaScript

import React from 'react';
export default function TrendChart({ trendSeries = [] }) {
if (trendSeries.length < 2) {
return (
<div className="rounded-2xl border border-dashed border-gray-300 dark:border-gray-700 bg-white/70 dark:bg-gray-900/70 p-4 text-sm text-gray-600 dark:text-gray-300">
Für den Trend werden mindestens 2 Assessments benötigt.
</div>
);
}
const width = 760;
const height = 280;
const left = 50;
const right = 20;
const top = 16;
const bottom = 52;
const values = trendSeries.map((entry) => entry.totalPoints);
const minValue = Math.min(...values);
const maxValue = Math.max(...values);
const range = maxValue - minValue || 1;
const innerWidth = width - left - right;
const innerHeight = height - top - bottom;
const points = trendSeries.map((entry, index) => {
const x = left + (index / (trendSeries.length - 1)) * innerWidth;
const normalized = (entry.totalPoints - minValue) / range;
const y = top + innerHeight - normalized * innerHeight;
return { ...entry, x, y };
});
const path = points.map((point, index) => `${index === 0 ? 'M' : 'L'}${point.x},${point.y}`).join(' ');
return (
<div className="rounded-2xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 p-4 shadow-sm">
<h3 className="text-sm font-semibold text-gray-800 dark:text-gray-100 mb-3">Trend (Gesamtpunkte)</h3>
<svg viewBox={`0 0 ${width} ${height}`} className="w-full h-auto" role="img" aria-label="Trenddiagramm">
<line x1={left} y1={top} x2={left} y2={top + innerHeight} className="stroke-gray-300 dark:stroke-gray-700" strokeWidth="1" />
<line x1={left} y1={top + innerHeight} x2={left + innerWidth} y2={top + innerHeight} className="stroke-gray-300 dark:stroke-gray-700" strokeWidth="1" />
<path d={path} fill="none" className="stroke-indigo-500" strokeWidth="3" strokeLinecap="round" />
{points.map((point) => (
<g key={point.assessmentId}>
<circle cx={point.x} cy={point.y} r="4" className="fill-indigo-500" />
<text x={point.x} y={point.y - 10} textAnchor="middle" className="fill-gray-700 dark:fill-gray-200" style={{ fontSize: 11, fontWeight: 600 }}>
{point.totalPoints}
</text>
<text x={point.x} y={height - 18} textAnchor="middle" className="fill-gray-500 dark:fill-gray-400" style={{ fontSize: 10 }}>
{point.label}
</text>
</g>
))}
</svg>
</div>
);
}