npm package: @statistikzh/dataviz-utils
Description: Dataviz utils for Astro, lit and d3
Latest version: 0.0.10

# Dataviz Utils

`@statistikzh/dataviz-utils` is a set of utilities and helpers for creating and publishing data visualisation apps on the zh.ch website. It includes an Astro integration, a full-page layout component, reusable UI components, Lit utilities, chart web components, color schemes, and locale-aware d3 formatters.

## Installation

```bash
npm install @statistikzh/dataviz-utils
```

Add the integration to your `astro.config.*`:

```js
import { defineConfig } from "astro/config";
import { dataviz } from "@statistikzh/dataviz-utils/astro";

export default defineConfig({
  integrations: [dataviz()],
});
```

Create a `.env` file (required for production builds):

```
APP_IDENTIFIER=my-app
```

## Peer dependencies

| Package               | Version                          |
| :-------------------- | :------------------------------- |
| `astro`               | `^4.0.0 \|\| ^5.0.0 \|\| ^6.0.0` |
| `d3`                  | `^7.9.0`                         |
| `@statistikzh/leu`    | `^0.24.1`                        |
| `@statistikzh/charts` | `^0.6.0`                         |
| `lit`                 | `^3.3.0`                         |
| `nanostores`          | `^1.1.0`                         |

## What the Astro integration does

When you add the integration to your Astro config, calling `dataviz()` sets up the following automatically:

- **Fonts** — Provides the Inter font family (Black & Regular weights) so it is available in every app without manual setup.
- **CSS processing** — Enables vendor prefixing, minification, and modern CSS features like custom media queries out of the box.
- **Production URLs** — In production, resolves all asset URLs to absolute paths based on `APP_IDENTIFIER` (required env variable) so the app works correctly when embedded on a different domain (`https://www.web.statistik.zh.ch/dataviz/apps/<APP_IDENTIFIER>/`).
- **Embed mode** — Strips the `<!DOCTYPE html>` declaration from responses when `context.locals.embed` is `true`, allowing the app to be served as an embeddable HTML fragment.

## Embed mode

The integration ships a middleware that strips the `<!DOCTYPE html>` declaration from HTML responses when `Astro.locals.embed` is `true`. This turns a full page into an embeddable HTML fragment that can be injected into another site.

Set `Astro.locals.embed = true` in the frontmatter of any page that should be served as a fragment. These pages typically skip the `Layout` component and only render the markup needed for embedding:

```astro
---
import "@statistikzh/leu/theme.css";
Astro.locals.embed = true;
---

<div>
  <dataviz-app></dataviz-app>
</div>

<script>
  import "../../charts/dataviz-app.ts";
</script>
```

The resulting response will be plain HTML without `<!DOCTYPE html>`, ready to be embedded on another site.

## Exports

The package exposes the following entry points via its `exports` map:

### `@statistikzh/dataviz-utils/astro`

The Astro integration.

```ts
import { dataviz } from "@statistikzh/dataviz-utils/astro";
```

| Export    | Description                                                                                                                                                      |
| :-------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dataviz` | Astro integration function. Sets up fonts, CSS processing (autoprefixer, cssnano, custom media queries), production URL handling, and the embed-mode middleware. |

### `@statistikzh/dataviz-utils/astro/layout`

A full-page Astro layout.

```ts
import { Layout } from "@statistikzh/dataviz-utils/astro/layout";
```

| Export   | Description                                                                                                                                                                                                                                                                                         |
| :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Layout` | Full-page Astro layout component. Includes the LEU design-system theme (`@statistikzh/leu/theme.css`), a CSS reset, font loading, and a responsive 12-column grid with a branded header (Kanton Zürich logo), title and lead-text slots. Props: `title` (string, defaults to `"Data Viz Toolkit"`). |

### `@statistikzh/dataviz-utils/astro/components`

Reusable Astro UI components.

```ts
import { Cell, Richtext } from "@statistikzh/dataviz-utils/astro/components";
```

| Export     | Description                                                                                                                  |
| :--------- | :--------------------------------------------------------------------------------------------------------------------------- |
| `Cell`     | A grid-column wrapper. Places content in the centre columns of the 12-column grid. Props: `width` (`"default"` or `"wide"`). |
| `Richtext` | Applies LEU typographic styles to slotted HTML (headings `h2`–`h5`, paragraphs).                                             |

### `@statistikzh/dataviz-utils/astro/utils`

Astro-specific utility functions.

```ts
import { getAbsoluteURL } from "@statistikzh/dataviz-utils/astro/utils";
```

| Export           | Description                                                                                                                       |
| :--------------- | :-------------------------------------------------------------------------------------------------------------------------------- |
| `getAbsoluteURL` | Returns `SITE + BASE_URL` from the Astro env. Useful to prefix asset paths so they resolve to absolute URLs in production embeds. |

### `@statistikzh/dataviz-utils/lib`

Color schemes and locale-aware d3 formatters.

```ts
import {
  schemeCategory6,
  schemeCategory6Paired,
  schemeCategory12,
  format,
  formatPrefix,
  timeFormat,
  timeParse,
  utcFormat,
  utcParse,
} from "@statistikzh/dataviz-utils/lib";
```

| Export                  | Description                                                              |
| :---------------------- | :----------------------------------------------------------------------- |
| `schemeCategory6`       | 6-color categorical palette (hex strings).                               |
| `schemeCategory6Paired` | 12-color paired variant of the 6-color palette.                          |
| `schemeCategory12`      | 12-color categorical palette.                                            |
| `format`                | `d3-format` `format` function, pre-configured with the **de-CH** locale. |
| `formatPrefix`          | `d3-format` `formatPrefix` function (de-CH).                             |
| `timeFormat`            | `d3-time-format` `format` function (de-CH).                              |
| `timeParse`             | `d3-time-format` `parse` function (de-CH).                               |
| `utcFormat`             | `d3-time-format` `utcFormat` function (de-CH).                           |
| `utcParse`              | `d3-time-format` `utcParse` function (de-CH).                            |

### `@statistikzh/dataviz-utils/lit/*`

Lit utilities for building reactive web components.

```ts
import { memo } from "@statistikzh/dataviz-utils/lit/memo";
import { resize } from "@statistikzh/dataviz-utils/lit/resize-directive";
import { ResizeController } from "@statistikzh/dataviz-utils/lit/ResizeController";
```

| Export             | Description                                                                                                                                                             |
| :----------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `memo`             | A memoized Lit template helper. Accepts an array of dependencies (static values or nanostores) and a render function; only re-renders when a dependency changes.        |
| `resize`           | A Lit directive that observes the width of the host element via `ResizeObserver` and calls a callback with the current width whenever it changes.                       |
| `ResizeController` | A Lit reactive controller that observes the host element's size via `ResizeObserver` and invokes a callback with the content width. Automatically connects/disconnects. |

### `@statistikzh/dataviz-utils/charts/*`

Chart web components built with Lit, wrapping `@statistikzh/charts`.

```ts
import "@statistikzh/dataviz-utils/charts/bar-chart";
import "@statistikzh/dataviz-utils/charts/line-chart";
```

| Custom element        | Class             | Description                                                                                                                    |
| :-------------------- | :---------------- | :----------------------------------------------------------------------------------------------------------------------------- |
| `<zhstat-bar-chart>`  | `ZHStatBarChart`  | Bar chart web component. Properties: `data` (array of records) and `options` (`BarChartOptions` from `@statistikzh/charts`).   |
| `<zhstat-line-chart>` | `ZHStatLineChart` | Line chart web component. Properties: `data` (array of records) and `options` (`LineChartOptions` from `@statistikzh/charts`). |

## Commands

| Command       | Action                                                                                                       |
| :------------ | :----------------------------------------------------------------------------------------------------------- |
| `npm link`    | Registers this package locally. Run `npm link @statistikzh/dataviz-utils` in an Astro project to install it. |
| `npm publish` | Publishes to NPM. Requires being [logged in](https://docs.npmjs.com/cli/v8/commands/npm-adduser).            |