# gPdf Chart v0.1 cookbook and style gallery

These files are complete `DocumentRequest` examples for
`POST /api/v1/pdf/render`. They intentionally use small data sets so a caller
can start with a few labels and values, then add only the controls that the
report needs.

Every positioned element uses canonical `layout.*` fields. The examples do not
use legacy top-level placement fields.

## Scenario matrix

| File | Kind | Preset / capability |
|------|------|---------------------|
| `01-dashboard-light-area-gradient.json` | Area | `dashboard_light`, explicit linear gradient |
| `02-business-light-combo-dual-axis.json` | Combo | `business_light`, Bar + Line, primary + secondary value axes |
| `03-executive-dark-line.json` | Line | `executive_dark`, monotone curves, end labels |
| `04-print-mono-pattern-bar.json` | Bar | `print_mono`, explicit diagonal pattern, redundant print encoding |
| `05-dashboard-light-pie.json` | Pie | Per-slice colours and outside label + percent data labels |
| `06-business-light-donut.json` | Donut | `business_light`, inner radius, slice padding |
| `07-line-same-kind-dual-axis.json` | Line | Same-kind dual value axes and independent formats |
| `08-percent-stacked-bar.json` | Bar | Percent stack, fixed `0..100` domain, percent labels |
| `09-normal-stacked-area.json` | Area | Positive and negative normal stack around zero |
| `10-donut-center-label-composition.json` | Donut | Coordinate Container composition for centre text with a category legend |
| `11-spark-line.json` | Line | Compact Spark composition with hidden axes, grid, legend, labels, and markers |
| `12-progress-circle-composition.json` | Donut | Progress Circle composition with visible legend and centre Text metric |
| `13-bullet-annotations.json` | Bar | Horizontal Bullet with translucent qualitative bands and a target line |
| `14-waterfall.json` | Waterfall | Delta, subtotal, total semantics and connector lines |
| `15-scatter-bubble.json` | Scatter / Bubble | Continuous X/Y axes, size encoding, and X/Y reference lines |
| `16-range-error-band.json` | Range | Centre forecast line plus translucent lower/upper error band |
| `17-heatmap.json` | Heatmap | Category/row axes, cell gap, and preset heat scale |
| `18-named-projection-p0-p2.json` | Waterfall / Scatter / Heatmap | Category, XY, and Heatmap Projection shapes over typed Datasets |

Together the gallery covers all ten native Chart kinds, all four presets,
Spark/Progress/Bullet compositions, Combo and same-kind dual axes, normal and
percent stacks, category/XY/Heatmap projections, reference annotations,
gradient and pattern fills, and monochrome printing.

## Minimal authoring rules

- Start with `type`, `kind`, `width`, `height`, and the kind-specific `data`
  shape.
- Bar, Line, Area, Combo, Pie, Donut, Waterfall, Range, and Heatmap use shared
  labels. Scatter uses `series[].points` and omits labels.
- Keep category-shaped `series.values` arrays the same length as
  `data.labels`; Range also aligns `lower_values` and `upper_values`.
- Keep Chart labels, series names, axis titles, number-format prefix/suffix,
  and `alt` as single-line plain strings.
- Combo series declare `kind`; other Cartesian series inherit the top-level
  kind when omitted.
- `value_axis` defaults to `primary`. Declaring or referencing `secondary`
  requires a complete dual-axis configuration with non-empty titles.
- Pie and Donut use exactly one non-negative, non-null series with a positive
  total.
- Waterfall uses exactly one series and optional `point_kinds` values
  `delta/subtotal/total`; subtotal values are null.
- Scatter accepts continuous `points[].x/y` and optional positive
  `points[].size`; size enables Bubble rendering.
- Heatmap treats `data.labels` as columns and each series as one named row.
- Reference lines and bands share a maximum of 32 annotations and are not
  available on Pie, Donut, or Heatmap.
- If a Pie or Donut hides its legend, visible direct labels must include each
  category name and use `overflow: "error"`.
- Use `data_labels.overflow: "hide"` for resilient batch generation and
  `"error"` when every label is contractually required.
- Use `print_mono` when colour cannot be the only series identifier.
- Add a concise `alt` that communicates the trend or comparison when producing
  PDF/UA. A linked Chart also needs a non-empty `link.alt` for its annotation.

## Validation and local rendering

Parse every example:

```bash
for file in doc/examples/chart-v0.1/*.json; do jq empty "$file"; done
```

Render one example with the repository's local render tool:

```bash
cargo run -p gpdf-server-render-tools --bin generate_pdf_from_case -- \
  doc/examples/chart-v0.1/02-business-light-combo-dual-axis.json \
  tests/output/chart-v0.1/02-business-light-combo-dual-axis.pdf
```

For visual acceptance, render every file at a fixed DPI and inspect the PDF and
PNG output. The PDF renderer and Preview/Layout WASM must consume the same
prepared chart geometry; a front end must not recalculate axes, ticks, stacks,
or label placement from the original values.

## Customisation boundary

The four presets provide safe defaults. Callers can override the palette,
background, text, grid, legend, data labels, series colour/stroke/fill/marker,
axes, number formats, curve, gaps, corner radius, and radial geometry. The JSON
contract does not expose tooltip, animation, JavaScript callback, or remote
data-loading behaviour.
