Line and Area Marks
Line and area marks materialize ordered backend-neutral paths. Lines connect values; areas close two edges or one density edge against a baseline.
Line marks
createLineMark({ id?, data?, stroke?, strokeWidth?, opacity?, curve?, closed? } = {})
const program = chart()
.createData({ values: cars })
.createLineMark({ stroke: "#7c3aed", opacity: 0.55 })
.encodeX({ field: "Year", fieldType: "temporal" })
.encodeY({ field: "Acceleration", aggregate: "mean" });
The first ID is "line", data defaults to current data, stroke width defaults
to 2, opacity defaults to 1, and curve defaults to "linear". A line begins
as an empty path collection because later grouping determines series
cardinality. Complete encodings materialize sorted commands; color and stroke
dash may regroup them.
For a direct quantitative line, encodeX and encodeY may be called in either
order. The first action stores valid incomplete semantic and scale state while
the path remains empty; the second completes the same final layer, resolved
scales, and graphics in both orders. Aggregate y lines are different: their
grain requires a compatible temporal x encoding and rejects a quantitative
partial that would change the meaning of the line.
When a line is layered immediately after a compatible encoded mark, omitted
data and positions are inferred. Compatible aggregate grain is inferred too,
so an aggregate trend over aggregate bars needs no repeated encodeX or
encodeY call:
const layered = chart()
.createData({ values: cars })
.createBarMark({ id: "bars" })
.encodeX({ field: "Year", fieldType: "temporal" })
.encodeY({ field: "Acceleration", aggregate: "mean" })
.createLineMark({ id: "trend", strokeWidth: 3 });
Both layers reference the same x/y scales. The bar owns its bandwidth while
line vertices use the shared bar centers. Incompatible bin, stack, or offset
policies are not transferred. Pass data explicitly to assemble an independent
line with explicit encodings and scale IDs.
editLineMark({ target?, stroke?, strokeWidth?, opacity?, curve?, closed? })
program.editLineMark({
curve: "monotone",
stroke: "#7c3aed",
strokeWidth: 4,
opacity: 0.55
});
Supported curves are linear, step, step-before, step-after, basis,
cardinal, monotone, and natural. Smooth curves use cubic commands and
two-point series fall back to linear. Monotone paths require strictly increasing
or decreasing materialized x values; duplicate or non-monotonic x is rejected.
Materialization rejects any line or complete area that would expand beyond
10,000 backend-neutral path commands before allocating that command array.
A constant stroke conflicts with field-driven encodeColor. Appearance is
stored and reapplied whenever scale, Canvas, or grouping changes rebuild paths.
Polar lines and radar paths
Line marks also accept theta/radius positions. The two encoding actions may be called in either order; one channel remains valid semantic state but does not produce a path until both are present.
const radar = chart()
.createData({ values: rows })
.createLineMark({ closed: true, strokeWidth: 2.5 })
.encodeTheta({ field: "category", fieldType: "nominal" })
.encodeR({ field: "score", scale: { domain: [0, 1] } })
.encodeGroup({ field: "series" });
closed defaults to false. When true, every series ends with one closing
Z command; the first row is not duplicated. editLineMark({ closed })
switches an existing Polar line between open and closed. Polar lines currently
accept only curve: "linear"; other interpolation modes remain available to
Cartesian lines. Color, stroke dash, grouping, legends, scale edits, Canvas
resizing, filtering, selection, and highlighting all rebuild the same path
through the shared line materialization lifecycle.
Area marks
createAreaMark({ id?, data?, fill?, opacity?, stroke?, strokeWidth?, curve? } = {})
const area = chart()
.createData({ values: intervalRows })
.createAreaMark()
.encodeX({ field: "year", fieldType: "temporal" })
.encodeYRange({ lower: "lower", upper: "upper" });
Area fill defaults to "#4c78a8", opacity to 0.2, and curve to "linear".
An area becomes renderable with exactly one ranged orientation, a complete
density value/density pair, or aligned grouped x/y values whose y encoding uses
stack: "center". encodeGroup creates one closed path per nominal group
without creating a scale or legend. For a center-stacked area,
encodeColor({ field, layout: "center" }) can author the matching group and
center y policy atomically.
editAreaMark({ target?, fill?, opacity?, stroke?, strokeWidth?, curve? })
program.editAreaMark({
opacity: 0.35,
stroke: "#334155",
strokeWidth: 1.5,
curve: "cardinal"
});
stroke: false removes both outline and stored width. A width-only edit
requires an active outline. Constant fill cannot replace a field-driven color
encoding. Complete paths rematerialize immediately; incomplete paths retain the
configuration until their encodings become renderable.
Arc marks
createArcMark({ id?, data?, innerRadius?, padAngle?, fill?, opacity?, stroke?, strokeWidth? } = {})
const donut = chart()
.createCanvas({ width: 640, height: 500, margin: 55 })
.createData({ values: cars })
.createArcMark({ innerRadius: 0.56, padAngle: 1.5 })
.encodeTheta({ field: "Origin", aggregate: "count" })
.encodeColor({ field: "Origin", palette: "tableau10" });
innerRadius is a ratio from 0 inclusive to 1 exclusive. padAngle uses
degrees. Direct quantitative theta creates one proportional sector per positive
row. Count or weighted-sum categorical theta creates aggregated proportional
sectors. Categorical theta plus quantitative encodeR creates equal-angle
radial sectors; repeated rows in one angle band are drawn larger first so
smaller overlays remain visible. Arc graphics are ordinary closed path
commands, so renderers do not interpret Polar semantics.
editArcMark({ target?, innerRadius?, padAngle?, fill?, opacity?, stroke?, strokeWidth? })
Geometry and appearance edits rebuild complete sectors. An incomplete arc
retains the edited settings until both required encodings exist. Constant
fill cannot replace a field-driven color encoding. stroke: false disables
the outline and stored width; a later string stroke restores width 1.
Related
Position encodings · Polar line tutorial · Series encodings · Density · Error bands