# Iso Stacked Bars

A stacked bar chart drawn in isometric 3D. Each category has a tall bar in the back row and a short bar in the front row, so output and losses sit side by side on one floor plate. Each box shades its top, left and right faces from the series color and adds a fine texture. Hover a segment to see its value, or hover a legend item to highlight that series in every bar. The bars grow up from the floor when the chart scrolls into view.

<demo-iso-stacked-bars>



</demo-iso-stacked-bars>

## Installation

```bash
npx shadcn-vue@latest add "https://nxui.geoql.in/r/iso-stacked-bars.json"
```

## Usage

```vue
<script setup lang="ts">
  import IsoStackedBars from '~/components/ui/iso-stacked-bars/IsoStackedBars.vue';
  import type {
    IsoStackedBarsDatum,
    IsoStackedBarsSeries,
  } from '~/components/ui/iso-stacked-bars/types';

  const series: IsoStackedBarsSeries[] = [
    { key: 'housing', label: 'Housing', color: '#3ee0d8', row: 'back' },
    { key: 'bracket', label: 'Bracket', color: '#f5d03b', row: 'back' },
    { key: 'rework', label: 'Rework', color: '#f590b4', row: 'front' },
    { key: 'scrap', label: 'Scrap', color: '#f2742b', row: 'front' },
  ];

  const data: IsoStackedBarsDatum[] = [
    {
      label: 'Sep 22',
      values: { housing: 590, bracket: 2520, rework: 184, scrap: 46 },
    },
    {
      label: 'Sep 23',
      values: { housing: 600, bracket: 2490, rework: 46, scrap: 118 },
    },
  ];
</script>

<template>
  <IsoStackedBars
    title="Output & Scrap"
    subtitle="units per day · by product"
    note="scrap 2.4 %"
    :series="series"
    :data="data"
  />
</template>
```

Series stack in the order you give them, bottom first. Each row has its own scale: the tallest back bar fills the full height, and the tallest front bar fills `front-scale` of it.

## Props

<table>
<thead>
  <tr>
    <th>
      Prop
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Default
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        series
      </code>
    </td>
    
    <td>
      <code>
        IsoStackedBarsSeries[]
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Series in stacking order. See the series options below.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        data
      </code>
    </td>
    
    <td>
      <code>
        IsoStackedBarsDatum[]
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      One entry per category: <code>
        { label, values: { [seriesKey]: n } }
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        title
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Card title.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        subtitle
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Muted line under the title.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        total
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      —
    </td>
    
    <td>
      Headline number. Defaults to the sum of all back-row values.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        unit
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        'units'
      </code>
    </td>
    
    <td>
      Unit after the headline. Also used for back-row totals.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        note
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Orange accent text on the right of the headline.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        front-scale
      </code>
    </td>
    
    <td>
      <code>
        number
      </code>
    </td>
    
    <td>
      <code>
        0.5
      </code>
    </td>
    
    <td>
      Height of the tallest front bar relative to the tallest back bar.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        animate
      </code>
    </td>
    
    <td>
      <code>
        boolean
      </code>
    </td>
    
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Grow the bars from the floor when the chart comes into view.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        aria-label
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      title
    </td>
    
    <td>
      Accessible name of the chart.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        class
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      <code>
        ''
      </code>
    </td>
    
    <td>
      Extra classes for the root element.
    </td>
  </tr>
</tbody>
</table>

## Series options

<table>
<thead>
  <tr>
    <th>
      Option
    </th>
    
    <th>
      Type
    </th>
    
    <th>
      Description
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        key
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Field in each datum's <code>
        values
      </code>
      
      .
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        label
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Legend and tooltip label.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        color
      </code>
    </td>
    
    <td>
      <code>
        string
      </code>
    </td>
    
    <td>
      Any CSS color. The faces are shaded from it.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        row
      </code>
    </td>
    
    <td>
      <code>
        'back' | 'front'
      </code>
    </td>
    
    <td>
      Row the series stacks in.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        texture
      </code>
    </td>
    
    <td>
      <code>
        'stripes' | 'dots' | 'grid' | 'none'
      </code>
    </td>
    
    <td>
      Fine texture on the faces. Defaults to <code>
        'stripes'
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

## Accessibility

- Every bar is focusable and has an `aria-label` with its category and all its segment values.
- The bars use a roving tab stop. Left and Right move between categories, Up and Down switch rows, and Home and End jump to the ends.
- A focused bar shows its total in the tooltip, which is announced through `aria-live`.
- Legend items are buttons. Hover or focus one to highlight its series; click to pin the highlight (`aria-pressed`).
- With reduced motion the bars render at full height without the grow animation.
