Published-release documentation · release compatibility

Program Composition

Blue point panel and orange replacement bar panel aligned in one horizontal dashboard
The stable main slot retains points while the detail slot shows its replacement bars.

Combine already-authored chart programs without merging their datasets, marks, scales, or guides. The result is another immutable ChartProgram whose parent Canvas contains concrete snapshots of its named children.

Arrange complete programs

Contextual fragment. Use an ES module with the imports, data, and prepared resource state described in this section. Resolve these names from setup in this fragment or section; alternatives branch from the same base.

import { hconcat, vconcat } from "ggaction";

const row = hconcat({
  id: "overview",
  programs: [
    { id: "main", program: scatterplot },
    { id: "detail", program: barChart }
  ],
  gap: 20,
  align: "center",
  padding: 16
});

const dashboard = vconcat({
  programs: [row, trendChart],
  gap: 18
});

This is a composition fragment: scatterplot, barChart, and trendChart must each be a complete program with one materialized Canvas. See the runnable repository example for complete child construction and Browser Canvas rendering.

The representative output deliberately keeps two different final grammars: the main slot contains a titled point chart on a blue panel, while the detail slot contains the titled orange bar chart installed by replaceCompositionChild. Distinct child backgrounds and the visible parent gap make the retained slot, replacement slot, and parent layout observable in the full image and its gallery thumbnail.

Both functions initially require at least two programs. A direct ChartProgram receives the deterministic slot name view-1, view-2, and so on. Use { id, program } when later code must replace a stable slot.

Option Default Effect
id "composition" Names the composition for deterministic graphic namespaces
programs required Ordered complete child programs or { id?, program } entries
gap 16 Non-negative distance between adjacent children
align "center" "start", "center", or "end" cross-axis placement
padding 0 on every side Non-negative scalar or partial four-side object

Automatic and explicit child sizes

The parent Canvas size is inferred from child dimensions, gap, and padding. For hconcat, children whose height was omitted in createCanvas expand to the largest child height. For vconcat, children whose width was omitted expand to the largest child width. A unit child rematerializes against that resolved size. A nested composition keeps its intrinsic child layout and align places its complete snapshot inside the larger cross-axis slot; the outer composition does not stretch inner facet cells, gaps, or guide geometry. An explicitly authored child width or height is never overwritten.

The parent background is white. Child Canvas backgrounds are preserved, and nested compositions keep independent clipping and coordinate scopes.

Compose Cartesian, Polar, and Parallel charts

A complete Cartesian, Polar, or Parallel chart can be a direct or nested concat child. The composition does not reinterpret theta, radius, x, y, scales, guides, or selections. It snapshots each finished child into one namespaced concrete graphic tree, so Canvas, SVG, PNG, and PDF renderers use the same result.

When a nested child changes, replace it in each ancestor explicitly:

Contextual fragment. Use an ES module with the imports, data, and prepared resource state described in this section. Caller-provided receivers: polarRow, dashboard. Resource selectors used here: target: "detail"; target: "polarRow". Resolve these names from setup in this fragment or section; alternatives branch from the same base.

const revisedPolarRow = polarRow.replaceCompositionChild({
  target: "detail",
  program: revisedPolarChart
});

const revisedDashboard = dashboard.replaceCompositionChild({
  target: "polarRow",
  program: revisedPolarRow
});

This preserves immutable earlier programs and makes the affected ancestor layout visible in the action trace. See the cross-feature dashboard source for a nested Polar replacement next to a Cartesian facet.

Repeat the current chart by a field

See Facets and Field Repetition for this contract and its examples.

Build a row and column facet grid

See Facets and Field Repetition for this contract and its examples.

Repeat a positional encoding across fields

See Facets and Field Repetition for this contract and its examples.

Edit the layout

See Editing Compositions for this contract and its examples.

Edit facet scale and guide policies

See Editing Compositions for this contract and its examples.

Replace the repeated source recipe

See Editing Compositions for this contract and its examples.

Replace one stable slot

See Editing Compositions for this contract and its examples.

Insert, remove, and reorder named concat children

See Editing Compositions for this contract and its examples.

State, trace, and action scope

children maps stable slot IDs to retained immutable programs. compositionSpec stores concat direction or facet intent together with order, gap, alignment, and padding. Grid state additionally records both ordered domains, cell coordinates, scalar pairs, and blank status; repeat state records the target, channel, and ordered fields. The parent graphicSpec stores the fully materialized, namespaced child Canvas tree; renderers read only that concrete state.

hconcat, vconcat, facet, facetGrid, and repeatCharts trace retained child use and concrete materialization. Named structural edits rematerialize from retained concat children. Layout edits and replacement rematerialize from the retained child programs. Facet source, scale, and guide edits rederive stable-ID children from the parent-retained unit state before replacing the parent snapshot. Ordinary data, mark, encoding, scale, and guide actions apply only to unit programs and reject a composition parent. Facet titles, facet-header edits and existing shared-legend editors/removal are explicit parent-owned exceptions. Edit a child first, then replace its slot when a concat dashboard needs a changed chart.

Documentation provenance

293 actions · sha256:e755591a2e5f5e2b494867583876e28020a478c5220b77bdc6ad469a6224891d