Axes
At a glance
| Action | Shortest call | Inference/defaults | Result |
|---|---|---|---|
createAxes |
createAxes() |
Stored coordinate family, position scales, titles | Complete x/y, theta/radius, or Parallel dimension axes |
editXAxis |
editXAxis({ line: { lineWidth: 2 } }) |
Existing x-axis components | Selected x-axis components rematerialized |
editYAxis |
editYAxis({ position: "right" }) |
Existing y-axis components | Existing y-axis components moved together |
removeXAxis / removeYAxis |
removeXAxis() |
Existing complete axis | Semantic, graphic, and stored axis state removed |
createAxes(options?)
Creates complete axes for encoded Cartesian x/y, Polar theta/radius, or Parallel dimension channels. This is the recommended axis action for ordinary chart authoring.
program.createAxes({
y: { ticksAndLabels: { count: 6 } }
});
| Option | Type | Default |
|---|---|---|
coordinate |
{ id?, type? } |
unique coordinate used by x/y layers |
x |
axis options or false |
create when x is encoded |
y |
axis options or false |
create when y is encoded |
theta |
Polar axis options or false |
create when theta is encoded |
radius |
Polar axis options or false |
create when radius is encoded |
coordinate.type accepts "auto", "cartesian", "polar", or "parallel" as a stored
type assertion.
Each x/y axis option supports:
| Option | Value |
|---|---|
scale |
scale ID; inferred when one scale is used on the channel |
position |
x: "bottom" or "top"; y: "left" or "right" |
line |
{ color?, lineWidth? } |
ticksAndLabels |
{ count?, values?, ticks?, labels? } |
title |
title options including text, at, offset, and font styling |
Use either count or exact data-space values for ticks. Ambiguous coordinates
or scales must be selected explicitly. createAxes reads stored coordinates;
it never creates or repairs them.
Linear scales create numeric nice ticks. Time scales choose a UTC calendar
interval near the requested count and format labels automatically. Automatic
formatting starts from the domain span, then raises precision only when two
distinct resolved ticks would otherwise share a label. For example, a
1970–1982 domain produces 1970, 1972, …, 1982, while sub-month ticks
include the day needed to distinguish them. Explicit time values are finite
timestamps.
A band or point x scale uses its complete domain as the default tick and label
values. Each value is placed at the shared band or point center and formatted
with String(value). Explicit ticksAndLabels.values may select a domain
subset in the requested order. Discrete axes reject count so categories are
not silently omitted. Reversed ranges and Canvas rematerialization preserve
the stored category values.
For a binned histogram x encoding, omitted tick options use the inferred bin
boundaries. This keeps the axis aligned with every rect edge. Explicit
ticksAndLabels.count or ticksAndLabels.values takes precedence. Count y
axes use numeric nice ticks and infer titles such as count(Displacement).
Titles are inferred from the unique encoding consuming each scale. Aggregate
encodings include their operation, so mean on Acceleration becomes
mean(Acceleration). Pass title.text when inference is ambiguous or a custom
label is desired.
The default edges remain bottom for x and left for y. A complete axis forwards an explicit edge to its line, ticks, labels, and title:
program.createAxes({
x: {
position: "top",
ticksAndLabels: { labels: { format: ".1f" } }
},
y: { position: "right" }
});
Top ticks point upward and right ticks point right. Labels and titles are placed outward from the selected edge. The Canvas margin must already be large enough; guide creation does not resize it.
Numeric label formats are .0f, .1f, .2f, .0%, .1%, and .2e.
UTC time formats are %Y, %Y-%m, and %Y-%m-%d. Numeric formats require a
linear scale, time formats require a time scale, and ordinal labels use
"auto". The existing { decimals: nonNegativeInteger } form remains
available for linear labels. Explicit formats remain exact and may intentionally
produce repeated display strings.
The selected coordinate ID is stored on each semantic axis. Canvas size and margin edits explicitly rematerialize positional scales and every connected axis component.
The trace preserves its decomposition:
createAxes
├─ createXAxis (when selected)
└─ createYAxis (when selected)
For a Polar coordinate, the same aggregate becomes:
createAxes
├─ createThetaAxis
└─ createRadialAxis
createThetaAxis() creates the outer circular baseline, outward ticks,
perimeter labels, and an inferred title. createRadialAxis() creates one
center-to-edge baseline; its angle defaults to 90 degrees (right). Both
support ticksAndLabels: { count?, values?, ticks?, labels? } and title style.
Set title: false on either Polar axis to omit that title at creation.
The radial title defaults to position: "inside" at the baseline midpoint.
Use title: { position: "outside" } to place it beyond the radial endpoint;
offset is measured from the midpoint normal when inside and from the endpoint
when outside.
For a Parallel coordinate, createAxes() delegates to an internal wrapped
dimension-axis action. It creates one ordinary baseline, tick/label set, and
title for each stored dimension. Channel-specific x/y/theta/radius options do
not apply; revise dimension mapping with encodeParallelCoordinates and
individual mappings with editScale.
For individual lines, ticks, labels, and titles, see Advanced axis components.
Editing a complete axis
Use editXAxis() or editYAxis() when several components of one existing
axis should change together:
program
.editXAxis({
line: { color: "#334155", lineWidth: 2 },
ticksAndLabels: {
count: 6,
ticks: { length: 7 },
labels: { color: "#475569", fontSize: 11 }
},
title: { text: "Engine displacement" }
})
.editYAxis({ position: "right" });
The complete edit facade does not create an axis or change its scale and
coordinate binding. It delegates to the existing line, tick, label, grouped
tick/label, and title edit actions. Omitted component objects remain unchanged.
Changing position updates every existing component on that axis, including
components omitted from the call.
Use editThetaAxis() for grouped theta component edits. Use
editRadialAxis({ angle: 180 }) to move the radial line, ticks, labels, and
title together. Focused editThetaAxisLine/Ticks/Labels/Title and matching
editRadialAxis* actions change one visible component without raw graphic IDs.
editRadialAxisTitle({ position: "inside" | "outside" }) switches only the
radial title placement while preserving its text and style.
Removing an axis
removeXAxis(), removeYAxis(), removeThetaAxis(), and
removeRadialAxis() remove the complete axis: line, ticks,
labels, title, semantic guide state, and stored materialization settings. Marks,
scales, coordinates, and the opposite axis remain.
const withoutXAxis = program.removeXAxis();
const selected = program.removeYAxis({ scale: "y", coordinate: "main" });
Optional selectors must match the existing resource. A missing or mismatched axis throws before anything changes.
| Option | Meaning |
|---|---|
position |
x: "bottom"/"top"; y: "left"/"right" |
line |
{ color?, lineWidth? } |
ticks |
{ count?, values?, length?, color?, lineWidth? } |
labels |
{ count?, values?, offset?, format?, color?, fontSize?, fontFamily?, fontWeight? } |
ticksAndLabels |
{ count?, values?, ticks?, labels? } |
title |
{ text?, at?, offset?, rotation?, color?, fontSize?, fontFamily?, fontWeight? } |
Axis label and title weights follow the shared Canvas font-weight policy.
Use either ticksAndLabels or the independent ticks/labels options in one
call. The action validates the entire request before editing any component, so
an invalid later component cannot leave a partial result.
Errors and limitations
Ambiguous scale or coordinate candidates require explicit IDs. Each channel has one semantic axis, so parallel duplicate axes cannot be created.