Skip to main content
Compendium / Metrics & Telemetry / Charts / Horizontal Bar Mini
#684

Horizontal Bar Mini

Horizontal bar mini chart — ranking categories by a single metric, labels in-line.

STABLE DE
#chart #real-content #dark-mode-tested #responsive
Live
// ranked · top 5 HBARS
spec-001
84
spec-002
71
spec-003
62
spec-004
48
spec-005
31
Spec

Intent

When the categories are named (teams, specs, pillars), horizontal bars beat vertical ones — the label has room to breathe and the eye scans down a list naturally.

Acceptance Criteria

  • [ ] One horizontal bar per category, labelled inline
  • [ ] Bars scaled to the longest in the set
  • [ ] Tabular-nums value at the bar end
  • [ ] Negative: does NOT sort the categories visually

Constraints

  • Pure CSS, no SVG required
  • Theme-aware via tokens
// hbar-mini.astro
---
import type { CompendiumMeta } from '../../../data/types';

export const meta: CompendiumMeta = {
  id: 684,
  slug: 'hbar-mini',
  name: 'Horizontal Bar Mini',
  category: 'metrics-telemetry',
  subcategory: 'charts',
  pillar: 'de',
  description: 'Horizontal bar mini chart — ranking categories by a single metric, labels in-line.',
  spec: `## Intent
When the categories are named (teams, specs, pillars), horizontal bars beat vertical ones — the label has room to breathe and the eye scans down a list naturally.

## Acceptance Criteria
- [ ] One horizontal bar per category, labelled inline
- [ ] Bars scaled to the longest in the set
- [ ] Tabular-nums value at the bar end
- [ ] Negative: does NOT sort the categories visually

## Constraints
- Pure CSS, no SVG required
- Theme-aware via tokens`,
  tags: ['chart', 'real-content', 'dark-mode-tested', 'responsive'],
  status: 'stable',
  health: { ics: 88, a11y: 'aa', themed: true, animated: false },
};

const rows = [
  { label: 'spec-001', value: 84 },
  { label: 'spec-002', value: 71 },
  { label: 'spec-003', value: 62 },
  { label: 'spec-004', value: 48 },
  { label: 'spec-005', value: 31 },
];
const max = Math.max(...rows.map((r) => r.value));
---

<div data-this-component class="w-full bg-paper text-black border-4 border-black overflow-hidden">
  <header class="flex items-baseline justify-between px-3 py-2 border-b-2 border-black">
    <span class="font-mono text-[10px] uppercase tracking-widest opacity-60">// ranked · top 5</span>
    <span class="font-mono text-[10px] uppercase tracking-widest">HBARS</span>
  </header>
  <div class="p-3 space-y-1.5">
    {rows.map((r) => (
      <div class="grid grid-cols-[72px_1fr_36px] items-center gap-2">
        <span class="font-mono text-[10px] uppercase tracking-widest opacity-80 truncate">{r.label}</span>
        <div class="relative h-3 border-2 border-black bg-paper">
          <div class="absolute inset-y-0 start-0 bg-de" style={`width: ${(r.value / max) * 100}%`}></div>
        </div>
        <span class="font-black text-[11px] tabular-nums text-end">{r.value}</span>
      </div>
    ))}
  </div>
</div>