| 1 | "use client" |
| 2 | |
| 3 | import { useCommonChart } from "./common-context" |
| 4 | import { cn } |
| 5 | import { rgb } |
| 6 | |
| 7 | /** Series/slice legend. With `isClickable`, each entry toggles its selection. |
| 8 | * Works in every chart family via the shared common context. */ |
| 9 | export function Legend({ |
| 10 | isClickable = false, |
| 11 | align = "right" |
| 12 | }: { |
| 13 | isClickable?: boolean |
| 14 | align?: " |
| 15 | }) { |
| 16 | const chart = |
| 17 | |
| 18 | return ( |
| 19 | <div |
| 20 | className={cn( |
| 21 | "pointer-events-none absolute inset-x-0 top-0 flex flex-wrap gap-3 px-1", |
| 22 | align === "right" |
| 23 | align === "center" |
| 24 | align === "left" |
| 25 | )} |
| 26 | > |
| 27 | {chart.names.map |
| 28 | const seed = |
| 29 | const emphasis = |
| 30 | const dimmed = |
| 31 | return ( |
| 32 | <button |
| 33 | key={name} |
| 34 | type="button" |
| 35 | disabled={!isClickable} |
| 36 | onClick={() => |
| 37 | chart.selectDataKey(chart |
| 38 | } |
| 39 | // Hovering an entry spotlights its series so overlapping layers |
| 40 | // (e.g. two meshed radar polygons) can be told apart at a glance. |
| 41 | onPointerEnter={() => |
| 42 | onPointerLeave={() => |
| 43 | onFocus={() => |
| 44 | onBlur={() => |
| 45 | className={cn( |
| 46 | "flex items-center gap-1.5 font-mono text-[11px] text-muted-foreground transition-opacity", |
| 47 | isClickable && |
| 48 | "pointer-events-auto cursor-pointer hover:text-foreground", |
| 49 | dimmed && "opacity-40" |
| 50 | )} |
| 51 | > |
| 52 | <span |
| 53 | className="size-2 rounded-[1px]" |
| 54 | style={{ backgroundColor: |
| 55 | /> |
| 56 | {chart.labelOf(name |
| 57 | </button> |
| 58 | ) |
| 59 | })} |
| 60 | </div> |
| 61 | ) |
| 62 | } |
| 63 | |
| 64 | Legend.chartLayer = " |