month on the x-axis, revenue on the y-axis, and give each product its own color. The strings are column keys.
Built-in aesthetics
The built-in aesthetics:
Not every geom reads every aesthetic:
size means something to geom.point() and nothing to geom.line(). Each geom lists the aesthetics it reads. lineType takes only a text column; a numeric one fails to compile. A custom geom can declare position channels of its own, such as a candlestick’s open / high / low / close, and the engine scales them like the built-in ones.
What splits data into groups
Grouping follows one rule:- If
groupis mapped, it is the only thing that groups. - Otherwise, every mapped visual aesthetic that points at a text column —
color,size,alpha,strokeWidth,lineType— groups, one group per unique combination. A lonelineType: 'scenario'mapping splits one line into several, with no color involved.
x or y is left out too, since position already splits the data by it.
color and group differ in what else they do. color splits and also paints: a hue per value, with a legend. group only splits. Use group for one line per value in a single color.
Variables and constants
An aesthetic can be bound to a variable (a column, read per row) or a constant (one literal value applied to every observation):'revenue'— string shorthand for a variable mapping.{ variable: 'revenue' }— the explicit variable form.{ value: 'red' }— a constant. The value still flows through the aesthetic’s scale, so{ value: 'Pro' }oncolorgets whatever color the scale assigns toPro.
Where a mapping lives
A mapping can sit at two levels: Spec-level — shared by every layer. Set it withcreateSpec({ ... }):
aes option. This is how combos give each layer a different y:
yScaleType: 'secondary' on the layer that belongs to the right-hand axis. Without it the layer is placed against the primary domain, which draws a plausible but wrong chart. The scale.ySecondary() above is optional: the engine infers one as soon as a layer asks for it. Declaring it lets you give that axis its own options.
A layer’s
aes option is named mapping in the serialized spec: geom.line({ aes: { y: 'profit' } })
becomes { "type": "layer", "geom": "line", "mapping": { "y": "profit" } }. This matters when you
hand-write the JSON.Every mapped position needs a scale
Mapping a column tox or y is half the job. You must also declare the scale that turns the values into positions. scale.x() and scale.y() are never created automatically.
Next
- Scales — turn mapped values into positions and colors
- Geoms & layers — which aesthetics each geom reads

