Spaces:
Running
Running
| // Tiny dependency-free horizontal bar for inline charts (leaderboard species view, | |
| // cross-model analysis, data page). Value in [0,1] by default; optional min–max | |
| // whisker overlaid on the bar. Purely presentational, theme-aware via CSS vars. | |
| interface BarRowProps { | |
| label: string | |
| value: number | null | |
| min?: number | null | |
| max?: number | null | |
| /** domain max (default 1) */ | |
| domain?: number | |
| /** bar fill color CSS var name, e.g. 'var(--accent)' */ | |
| color?: string | |
| /** show the numeric value at the end */ | |
| showValue?: boolean | |
| /** right-side annotation (e.g. species name) */ | |
| note?: string | |
| labelWidth?: number | |
| /** format the numeric value (default: 3 decimals) */ | |
| format?: (v: number) => string | |
| } | |
| export default function BarRow({ | |
| label, | |
| value, | |
| min, | |
| max, | |
| domain = 1, | |
| color = 'var(--accent)', | |
| showValue = true, | |
| note, | |
| labelWidth = 150, | |
| format = (v) => v.toFixed(3), | |
| }: BarRowProps) { | |
| const pct = value == null ? 0 : Math.max(0, Math.min(100, (value / domain) * 100)) | |
| const hasWhisker = min != null && max != null && max > min | |
| return ( | |
| <div className="bar-row"> | |
| <div className="bar-label" style={{ width: labelWidth }} title={label}> | |
| {label} | |
| </div> | |
| <div className="bar-track"> | |
| {value != null && <div className="bar-fill" style={{ width: `${pct}%`, background: color }} />} | |
| {hasWhisker && ( | |
| <div | |
| className="bar-whisker" | |
| style={{ left: `${(min! / domain) * 100}%`, width: `${((max! - min!) / domain) * 100}%` }} | |
| title={`range ${min!.toFixed(3)}–${max!.toFixed(3)}`} | |
| /> | |
| )} | |
| </div> | |
| {showValue && ( | |
| <div className="bar-value"> | |
| {value == null ? 'n/a' : format(value)} | |
| {note && <span className="bar-note"> {note}</span>} | |
| </div> | |
| )} | |
| </div> | |
| ) | |
| } | |