File size: 1,479 Bytes
1576c24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { TOPIC_LABELS } from '../utils/topicLabels.js'

const TOPIC_COLORS = {
  algebra:      '#10B981',
  geometry:     '#FBBF24',
  statistics:   '#FB7185',
  combinatorics:'#10B981',
}

function barColor(accuracy) {
  if (accuracy >= 0.7) return '#10B981'
  if (accuracy >= 0.5) return '#FBBF24'
  return '#FB7185'
}

/**
 * Vertical bar chart showing per-topic accuracy.
 * Bars are colored green/amber/red based on accuracy thresholds.
 *
 * @example
 * <TopicBreakdownChart topicBreakdown={{
 *   algebra: { accuracy: 0.8 },
 *   geometry: { accuracy: 0.5 },
 * }} />
 */
export default function TopicBreakdownChart({ topicBreakdown }) {
  const entries = Object.entries(topicBreakdown)
  const maxAcc = Math.max(...entries.map(([, tb]) => tb.accuracy), 0.01)

  return (
    <div className="flex items-end gap-5 h-[120px] px-1">
      {entries.map(([topic, tb]) => {
        const color = TOPIC_COLORS[topic] ?? barColor(tb.accuracy)
        const heightPct = (tb.accuracy / maxAcc) * 100
        return (
          <div key={topic} className="flex flex-col items-center gap-1.5 flex-1 h-full justify-end">
            <div
              className="w-full rounded-t-[4px] transition-all"
              style={{ height: `${heightPct}%`, background: color }}
            />
            <span className="font-sans text-[0.625rem] text-faint text-center">
              {TOPIC_LABELS[topic] ?? topic}
            </span>
          </div>
        )
      })}
    </div>
  )
}