Files
MOPC-Portal/src/components/charts/score-distribution.tsx

64 lines
1.7 KiB
TypeScript
Raw Normal View History

'use client'
import { ResponsiveBar } from '@nivo/bar'
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { nivoTheme, scoreGradient } from './chart-theme'
interface ScoreDistributionProps {
data: { score: number; count: number }[]
averageScore: number
totalScores: number
}
export function ScoreDistributionChart({
data,
averageScore,
totalScores,
}: ScoreDistributionProps) {
const chartData = data.map((d) => ({
score: String(d.score),
count: d.count,
}))
return (
<Card>
<CardHeader>
<CardTitle className="flex items-center justify-between">
<span>Score Distribution</span>
<span className="text-sm font-normal text-muted-foreground">
Avg: {averageScore.toFixed(2)} ({totalScores} scores)
</span>
</CardTitle>
</CardHeader>
<CardContent>
<div style={{ height: '300px' }}>
<ResponsiveBar
data={chartData}
keys={['count']}
indexBy="score"
theme={nivoTheme}
colors={(bar) => scoreGradient(Number(bar.indexValue))}
borderRadius={4}
enableLabel={true}
labelSkipHeight={12}
labelTextColor="#ffffff"
axisBottom={{
legend: 'Score',
legendPosition: 'middle',
legendOffset: 36,
}}
axisLeft={{
legend: 'Count',
legendPosition: 'middle',
legendOffset: -40,
}}
margin={{ top: 20, right: 20, bottom: 50, left: 50 }}
padding={0.2}
animate={true}
/>
</div>
</CardContent>
</Card>
)
}