> ## Documentation Index
> Fetch the complete documentation index at: https://docs.graphy.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Halloween

export const GraphEmbed = ({src, story, aspectRatio, borderRadius = '14px', args}) => {
  const STORYBOOK_BASE_URL = typeof window !== 'undefined' && window.location.hostname === 'localhost' ? 'http://localhost:6006' : 'https://storybook-sdk.vercel.app';
  function buildArgsString(args) {
    if (!args) return '';
    const encodeValue = value => {
      if (value === null) return '!null';
      if (value === undefined) return '!undefined';
      if (typeof value === 'boolean') return `!${value}`;
      if (typeof value === 'number') return String(value);
      return encodeURIComponent(String(value));
    };
    const properties = Object.entries(args).map(([key, value]) => `${key}:${encodeValue(value)}`).join(';');
    return `&args=${properties}`;
  }
  const resolvedSrc = story ? `${STORYBOOK_BASE_URL}/iframe.html?id=${story}&viewMode=story&embed=1&globals=mode:readonly${buildArgsString(args)}` : src;
  const resolvedAspectRatio = aspectRatio ?? (story ? '16 / 9' : '10 / 6');
  return <iframe src={resolvedSrc} loading="lazy" allowfullscreen="true" style={{
    width: '100%',
    aspectRatio: resolvedAspectRatio,
    border: 'none',
    borderRadius,
    colorScheme: 'light'
  }} />;
};

Halloween draws graphs in a churchyard on a moonlit night: columns are headstones, candles or railing posts, a pie is a rose window lit by the moon, a line is a glowing trail with a ghost riding its head, and a scatter's readings are jack-o'-lanterns.

<Warning>
  Halloween ships as its own package, `@graphysdk/theme-halloween`, still on
  `0.x`. A minor release may change its look, so pin a caret range (`^0.1.0`) to
  take only patches. Tell us what works and what doesn't on
  [Discord](https://discord.gg/yGmYCjkSr).
</Warning>

<GraphEmbed story="themes-halloween--chart" args={{ chart: 'bar' }} aspectRatio="4 / 3" borderRadius="0" />

## Install

```bash theme={null}
npm install @graphysdk/theme-halloween
```

Its peer dependencies are `@graphysdk/react` and React 19. Pass the theme to `createGraphyKit` and import its fonts once:

```tsx theme={null}
import { createGraphyKit, GraphRenderer } from '@graphysdk/react';
import { halloween } from '@graphysdk/theme-halloween';
import '@graphysdk/theme-halloween/fonts.css';

const kit = createGraphyKit({ theme: halloween });
```

Every graph drawn through `kit.GraphProvider` takes the theme. The spec is written as usual and names no theme:

```tsx theme={null}
const spec = kit.pipe(
  kit.createSpec({ x: 'quarter', y: 'revenue', color: 'region' }),
  kit.geom.bar({ position: 'dodge' }),
  kit.scale.x(),
  kit.scale.y()
);

<kit.GraphProvider spec={spec} data={data}>
  <GraphRenderer />
</kit.GraphProvider>;
```

Without a kit, pass the theme to the provider instead: `<GraphProvider theme={halloween}>`.

The provider reads the theme once, when it mounts. To switch themes, remount the provider, for example with a React `key`.

## What the theme decides

| Part | What Halloween sets |
| - | - |
| Stylesheet | A night sky with a moon, bats, stars and a cobweb, a bone baseline, titles in Creepster, a goal line spun as spider silk, notes on paper tags |
| Grid | Faint rules for the values, none for the categories |
| Colors | Six churchyard stones for groups (marble, slate, sandstone, moss, rose and gray granite), and a ramp from embers up to candlelight |
| Geoms | Columns as headstones, candles or railing posts; slices as stained glass; lines as glowing trails; points as jack-o'-lanterns; areas as mist |
| Color scheme | Dark, whatever `colorScheme` the provider is given |

<GraphEmbed story="themes-halloween--chart" args={{ chart: 'line' }} aspectRatio="4 / 3" borderRadius="0" />

## Headstones, candles and railings

Every column in a graph is the same object, chosen once from the room the columns have: a headstone where they are broad, a wax candle where they are slender, and a wrought-iron railing post where they are packed close. One graph never mixes them, so a change of object never reads as a change of meaning.

Each object ends exactly at its value: the crown of a headstone's arch, the top of a candle's wax (only its wick and flame stand above), and the tip of a railing's spear. A stacked bar is a pile of carved courses and a horizontal bar a ledger slab, however close the columns are packed.

A pie, donut, rose or radial bar is a rose window. Each slice keeps its sector as a pane of stained glass in its group's color, and the stone tracery is centerd on the edges between panes. A lantern is centerd on its reading, not on its stem. A heatmap keeps the built-in tile, which reads by its colors and labels.

## Motion

In the intro, each column rises from below its foot, a line draws in from its first reading with a ghost riding its head, lanterns light up in turn, and a rose window's panes light one after another. A candle's flame keeps flickering while the graph is shown.

A graph drawn with `animation={false}`, or for a viewer who prefers reduced motion, is drawn in its final state at once, with no flicker.

## Changing the look of one graph

A spec's own `styles()`, scales and `config()` sit above the theme. This graph keeps the churchyard, draws its groups in pumpkin and plum, and scales its type up:

```tsx theme={null}
const customizedSpec = kit.pipe(
  spec,
  kit.scale.color.discrete({ range: ['#FF7A1A', '#A23C78'] }),
  kit.styles({ defaults: [kit.style.graph({ textScale: 1.5 })] })
);
```

The theme is drawn for a graph about 600 pixels wide. `textScale` scales its type for a larger or smaller one.

## With a geom package

Halloween repaints the built-in geoms only. A geom from a package, such as the [dumbbell](/sdk-next/graph-types/dumbbell), keeps its own shapes and is drawn in the theme's colors and type.

```tsx theme={null}
import { dumbbell } from '@graphysdk/geom-dumbbell';

const kit = createGraphyKit({ theme: halloween, plugins: [dumbbell] });
```

## Fonts

`fonts.css` loads three families from Google Fonts: Creepster for titles, Cinzel in weights 600 and 700 for the figures carved into headstones, and Nunito in weights 400, 600, 700 and 800 for everything else. To host the fonts yourself, leave the import out and load families named `Creepster`, `Cinzel` and `Nunito` before the first graph is drawn.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.