# BarRaceChart

> Bar race: horizontal bars that grow, shrink and swap places as time moves through `frames`.

Source: https://ui.jcsoftdev.com/docs/components/bar-race-chart

Bar race: horizontal bars that grow, shrink and swap places as time moves
through `frames`. Play/pause, scrub with the slider, `topN` limits the rows.
Under `prefers-reduced-motion` the bars step from frame to frame.

## Import

```ts
import { BarRaceChart } from "@jcsoftdev/ui/charts";
```

Single-component entry points tree-shake to just this component: `@jcsoftdev/ui/charts/bar-chart`.

## Usage

```tsx
<BarRaceChart
  title="Citas por barbero esta semana"
  categories={barbers}
  series={[{ id: "citas", name: "Citas", data: appointmentsThisWeek }]}
  valueFormat="integer"
  orientation="vertical"
  stack="none"
  barRadius={6}
  height={300}
  dataLabels={false}
  grid
  tooltip
  loading={false}
  animate
  labels={spanishLabels}
/>
```

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `entities` * | `readonly BarRaceEntity[]` |  |  |
| `frames` * | `readonly RaceFrame[]` |  | One entry per moment; `values[i]` belongs to `entities[i]`. |
| `title` * | `string` |  | Accessible name of the chart. |
| `description` | `string` |  |  |
| `topN` | `number` | `6` | How many bars race at once (default 6). |
| `frameDuration` | `number` | `1400` | Milliseconds between two frames (default 1400). |
| `defaultPlaying` | `boolean` | `true` | Starts playing (default true; reduced motion starts paused). |
| `loop` | `boolean` | `true` | Starts over after the last frame (default true). |
| `valueFormat` | `ValueFormat` |  |  |
| `height` | `number \| "fill"` | `340` |  |
| `aspectRatio` | `number` |  |  |
| `loading` | `boolean` |  |  |
| `playLabel` | `string` | `"Play"` |  |
| `pauseLabel` | `string` | `"Pause"` |  |
| `momentLabel` | `string` | `"Moment"` | Accessible name of the moment slider. |
| `labels` | `Partial<ChartLabels>` |  |  |
| `className` | `string` |  |  |

`*` marks a required prop.

## Storybook stories

- [Default](/storybook/?path=/story/charts-barchart--default)
- [Grouped](/storybook/?path=/story/charts-barchart--grouped)
- [Stacked](/storybook/?path=/story/charts-barchart--stacked)
- [Stacked 100%](/storybook/?path=/story/charts-barchart--stacked-percent)
- [Horizontal (top services)](/storybook/?path=/story/charts-barchart--horizontal)
- [Horizontal Stacked](/storybook/?path=/story/charts-barchart--horizontal-stacked)
- [Negative Values](/storybook/?path=/story/charts-barchart--negative-values)
- [Annotation (weekly goal)](/storybook/?path=/story/charts-barchart--with-goal)
- [Data Labels](/storybook/?path=/story/charts-barchart--data-labels)
- [Custom Data Labels](/storybook/?path=/story/charts-barchart--custom-data-labels)
- [Distributed (a color per bar)](/storybook/?path=/story/charts-barchart--distributed)
- [Rotated Labels](/storybook/?path=/story/charts-barchart--rotated-labels)
- [Range column (shifts)](/storybook/?path=/story/charts-barchart--range-column)
- [Range bar (service duration)](/storybook/?path=/story/charts-barchart--range-bar)
- [Grouped stacked (income vs costs)](/storybook/?path=/story/charts-barchart--grouped-stacked)
- [Group labels (quarters)](/storybook/?path=/story/charts-barchart--group-labels)
- [Reversed value axis](/storybook/?path=/story/charts-barchart--reversed)
- [Patterns (color-blind friendly)](/storybook/?path=/story/charts-barchart--patterned)
- [Patterned Stacked](/storybook/?path=/story/charts-barchart--patterned-stacked)
- [Drilldown](/storybook/?path=/story/charts-barchart--drilldown)
- [Race (animated re-sort)](/storybook/?path=/story/charts-barchart--race)
- [Loading](/storybook/?path=/story/charts-barchart--loading)
- [Empty](/storybook/?path=/story/charts-barchart--empty)
- [Fill Parent](/storybook/?path=/story/charts-barchart--fill-parent)
- [Narrow](/storybook/?path=/story/charts-barchart--narrow)

## Source

`packages/ui/src/charts/bar-chart/bar-race-chart.tsx`
