Skip to content

Chart API

A Ranger API. There is no npm package yet. The examples on this page call the compiled classes in the browser. The standalone live page is the same API with Ranger and JavaScript tabs.

Build a Vega-Lite chart by calling methods. The runtime draws the specification this API writes.

Generated from the Ranger sources that declare the surface — gallery/vela/src/VlChart.rgr — so this page cannot describe a method that is not there.

Import "VlChart.rgr"

A dataset, a view, and marks. Nothing here draws: toSpec() hands the specification to Vela.

One row, built field by field. row() hands one back already attached to the dataset, so nothing has to be pushed anywhere by the caller.

Call Gives What it is for
row.num(field value) VlDataRow
row.whole(field value) VlDataRow
row.str(field value) VlDataRow
row.flag(field value) VlDataRow
row.json(field value) VlDataRow
row.back() VlDataset

A named table. Rows are JSON objects — the same values the parser produces for "data": \{"values": […]\} — so a dataset built here and one read off disk are the same thing to everything downstream.

Call Gives What it is for
VlDataset.create() VlDataset
dataset.row() VlDataRow
dataset.addRow(row) VlDataset
dataset.fromValues(values) VlDataset Rows as they came out of the JSON parser: a dataset can be a selection from a grid, a file somebody read, or a literal.
dataset.numbers(field values) VlDataset Column-wise filling, for a caller that holds arrays rather than records — a spreadsheet column, a series of measurements.
dataset.strings(field values) VlDataset
dataset.rowAt(index) VlJson
dataset.count() int
dataset.hasField(field) boolean
dataset.fieldType(field) string What kind of thing a column holds, in Vega-Lite’s vocabulary.
VlDataset.looksLikeDate(text) boolean “2016-01-01”, “2016-01-01T12:00:00Z”, “2016-01”.
dataset.toValues() VlJson

Rows as they came out of the JSON parser: a dataset can be a selection from a grid, a file somebody read, or a literal.

Column-wise filling, for a caller that holds arrays rather than records — a spreadsheet column, a series of measurements. Row i of every column is the same row.

What kind of thing a column holds, in Vega-Lite’s vocabulary. Numbers are a quantity, an ISO date is an instant, everything else is a name. Read from the rows rather than declared, because the rows are already here — and a column that is empty answers nothing, so the caller can tell “no such column” from “a column of names”.

“2016-01-01”, “2016-01-01T12:00:00Z”, “2016-01”. Four digits, a dash and a digit is enough to tell a date from a name and is what the data written by every tool in this repository looks like. Anything else is a name: a chart that read “Q1 2016” as an instant would put every quarter on the same tick and say nothing about it.

One mark and the channels it reads. Every setter answers the mark, so a mark is written as one sentence:

chart.bar().x("region").y("sales").aggregate("sum")

aggregate, bin, title and the rest apply to the channel most recently named — the cursor — which is what makes that sentence read in the order it is thought. on("y") moves the cursor back to a channel already set.

Call Gives What it is for
mark.note(message) void
mark.channel(name field) VlChartMark — channels ———————————————————— Every one of these names a COLUMN.
mark.x(field) VlChartMark
mark.y(field) VlChartMark
mark.x2(field) VlChartMark
mark.y2(field) VlChartMark
mark.color(field) VlChartMark
mark.fill(field) VlChartMark
mark.stroke(field) VlChartMark
mark.size(field) VlChartMark
mark.shape(field) VlChartMark
mark.opacity(field) VlChartMark
mark.theta(field) VlChartMark
mark.radius(field) VlChartMark
mark.detail(field) VlChartMark
mark.text(field) VlChartMark
mark.order(field) VlChartMark
mark.column(field) VlChartMark
mark.row(field) VlChartMark
mark.xOffset(field) VlChartMark What separates the bars of a grouped bar chart, in the direction the category axis runs.
mark.yOffset(field) VlChartMark
mark.count(channel) VlChartMark A count has no column to read: it is one number per group.
mark.valueNumber(channel value) VlChartMark A channel set to a constant rather than to a column.
mark.valueString(channel value) VlChartMark
mark.encodeJson(channel definition) VlChartMark The whole channel, written out, for whatever this API does not cover.
mark.on(channel) VlChartMark — the channel most recently named ———————————––
mark.cursorChannel() VlJson
mark.setOnCursor(key value) VlChartMark
mark.aggregate(op) VlChartMark
mark.bin() VlChartMark
mark.maxBins(count) VlChartMark How many bins at most.
mark.timeUnit(unit) VlChartMark
mark.type(kind) VlChartMark quantitative | nominal | ordinal | temporal, when the data cannot say — a column of years is numbers and is usually a category.
mark.title(label) VlChartMark
mark.format(pattern) VlChartMark
mark.stack(how) VlChartMark “zero” | “normalize” | “center”, or nothing stacked at all.
mark.noStack() VlChartMark
mark.sortBy(field) VlChartMark The order a discrete scale runs in.
mark.keepOrder() VlChartMark
mark.scaleJson(scale) VlChartMark
mark.scaleType(kind) VlChartMark
mark.scheme(name) VlChartMark
mark.noLegend() VlChartMark
mark.noAxis() VlChartMark
mark.axisOrient(side) VlChartMark Which side of the plot this channel’s axis stands on — “left”, “right”, “top”, “bottom”.
mark.axisJson(axis) VlChartMark
mark.propNumber(key value) VlChartMark — properties of the mark itself —————————————
mark.propString(key value) VlChartMark
mark.propFlag(key value) VlChartMark
mark.filled(value) VlChartMark
mark.markSize(value) VlChartMark
mark.markColor(value) VlChartMark
mark.markOpacity(value) VlChartMark
mark.interpolate(kind) VlChartMark “monotone”, “step-after”, “basis” … — how a line joins its points.
mark.withPoints(value) VlChartMark A line that shows the points it was drawn through.
mark.innerRadius(value) VlChartMark
mark.cornerRadius(value) VlChartMark
mark.tooltip(value) VlChartMark tooltip(true) shows every column the mark encodes.
mark.tooltipField(field) VlChartMark
mark.tooltipFields(fields) VlChartMark
mark.thickness(value) VlChartMark How thick a tick is drawn, across its band.
mark.strokeWidth(value) VlChartMark
mark.orient(value) VlChartMark “horizontal” | “vertical” — which way a tick lies, or which way a bar that has only one position channel runs.
mark.extent(value) VlChartMark What an interval is computed from: “stderr” | “stdev” | “ci” | “iqr”.
mark.chart() VlChart Back to the chart, when the next thing to say is about the view.

— channels ———————————————————— Every one of these names a COLUMN. A constant goes through valueNumber / valueString, and the two are kept apart on purpose: .color("red") meaning a column called red and .color("#c00") meaning paint it red cannot both be true, and the version that guesses is the one that draws a chart nobody asked for.

What separates the bars of a grouped bar chart, in the direction the category axis runs.

The whole channel, written out, for whatever this API does not cover. Vega-Lite is larger than any fluent surface over it, and an escape hatch that lands in the same specification is better than a wrapper that has to grow a method before anyone can draw anything.

How many bins at most. bin and maxbins are the two forms the compiler carries; a bin written any other way is refused BY NAME when it is compiled, which is where a refusal belongs — this layer would have to keep its own list of what the layer below supports, and a list like that is wrong the first time the layer below grows.

quantitative | nominal | ordinal | temporal, when the data cannot say — a column of years is numbers and is usually a category.

The order a discrete scale runs in. sortBy names a column; keepOrder is the one every spreadsheet wants — the order the rows arrived in, rather than alphabetical.

Which side of the plot this channel’s axis stands on — “left”, “right”, “top”, “bottom”. A Pareto chart’s cumulative line is measured up the right-hand side, which is the whole point of drawing it there.

tooltip(true) shows every column the mark encodes. The two below say which columns instead: one field, or a list of them in the order they should be read. A tooltip is also what the mark’s description says, so what a reader is shown by pointing and what they are told by listening stay the same sentence.

How thick a tick is drawn, across its band. A hi-lo-open-close chart’s open and close are ticks, and a two-pixel one is what makes them read as marks rather than as hairlines.

“horizontal” | “vertical” — which way a tick lies, or which way a bar that has only one position channel runs.

Call Gives What it is for
VlChart.create(data) VlChart
chart.mark(markType) VlChartMark — marks —————————————————————
chart.bar() VlChartMark
chart.line() VlChartMark
chart.area() VlChartMark
chart.point() VlChartMark
chart.circle() VlChartMark
chart.square() VlChartMark
chart.tick() VlChartMark
chart.rule() VlChartMark
chart.rect() VlChartMark
chart.arc() VlChartMark
chart.label() VlChartMark
chart.boxplot() VlChartMark
chart.errorbar() VlChartMark The two composite marks: an interval computed from the rows rather than read off them.
chart.errorband() VlChartMark
chart.trail() VlChartMark A line whose width says something: a trail thickens with its size.
chart.image() VlChartMark
chart.geoshape() VlChartMark A map: the shapes come from the data and the projection places them.
chart.latest() VlChartMark The mark added last, for a caller that built one and let go of it.
chart.channel(name field) VlChart — channels shared by every mark —————————————
chart.x(field) VlChart
chart.y(field) VlChart
chart.color(field) VlChart
chart.detail(field) VlChart
chart.encodeJson(channel definition) VlChart
chart.on(channel) VlChart
chart.setOnCursor(key value) VlChart
chart.type(kind) VlChart
chart.title(label) VlChart
chart.timeUnit(unit) VlChart
chart.keepOrder() VlChart
chart.size(width height) VlChart — the view itself —————————————————–
chart.width(value) VlChart
chart.height(value) VlChart
chart.heading(text) VlChart
chart.background(colour) VlChart
chart.propJson(key value) VlChart
chart.configJson(config) VlChart
chart.filter(expression) VlChart — transforms ––––––––––––––––––––––––––––– Only the two the compiler carries.
chart.calculate(expression as) VlChart
chart.transformJson(transform) VlChart
chart.independent(channel) VlChart Two marks measuring different things up the same side of the plot must not share a scale: chart.independent("y") is what makes a Pareto chart — bars against a count, a line against a running percentage — rather than two series averaged into one axis neither of them asked for.
chart.error(message) void Said once.
VlChart.copyOf(v) VlJson — emitting the specification —————————————— A deep copy, because a view’s channel is inherited by every mark and each copy then has its own type filled in.
chart.mergedEncoding(m) VlJson The view’s channels, then the mark’s own on top of them.
chart.resolveTypes(encoding) void What a channel is, when the channel did not say.
chart.inferType(ch) string
VlChart.markValue(m) VlJson A mark with no properties of its own is written as the string it is — "mark": "bar" — because that is what a person writes and what every golden file in this repository holds.
chart.toSpec() VlJson The whole thing: a Vega-Lite specification, ready for VlCompile.
chart.toText() string

The two composite marks: an interval computed from the rows rather than read off them. extent decides what the interval IS — “stderr” (the default), “stdev”, “ci” or “iqr”.

The mark added last, for a caller that built one and let go of it. A chart with no marks answers a mark that belongs to nothing rather than quietly adding one: a point nobody asked for would draw.

— transforms ––––––––––––––––––––––––––––– Only the two the compiler carries. Anything else is refused by name at compile time rather than dropped here, which is the same answer arriving from the layer that knows.

Two marks measuring different things up the same side of the plot must not share a scale: chart.independent("y") is what makes a Pareto chart — bars against a count, a line against a running percentage — rather than two series averaged into one axis neither of them asked for.

Said once. toSpec may be called more than once — a caller that writes the specification out and then hands it on calls it twice — and the same missing column reported twice reads as two mistakes.

— emitting the specification —————————————— A deep copy, because a view’s channel is inherited by every mark and each copy then has its own type filled in. Sharing one object would make two layers the same object, and a change to one of them a change to both.

What a channel is, when the channel did not say. This is the whole of the Observable Plot ergonomics: a caller writes .x("date") and the data decides whether that is an instant or a name.

A mark with no properties of its own is written as the string it is — "mark": "bar" — because that is what a person writes and what every golden file in this repository holds.

The two programs below call this API in the page. chart is a compiled VlChart. Edit the JavaScript and press Run. The drawing is the SVG this runtime produced.

chart.bar — sales by regionCtrl+Enter runs. The drawing is the SVG this runtime produced.Open in the playground
chart.area and chart.line — one encoding, two marksCtrl+Enter runs. The drawing is the SVG this runtime produced.Open in the playground

The examples the doc blocks above name.

These are ordinary functions: they are compiled and type-checked with the rest of the file, so a signature change breaks the build rather than the documentation. They are left OUT of the emitted code — -keep-examples puts them back — and each doc comment carries the body rendered in its own target’s syntax, so a Kotlin reader is shown Kotlin.

Call Gives What it is for
VlChartExamples.datasetExample() void
VlChartExamples.chartQuickExample() void
VlChartExamples.markSentenceExample() void
VlChartExamples.sharedChannelExample() void

Licence: AGPL-3.0-or-later. This page quotes the comments in those files.

Licence: AGPL-3.0-or-later · commit f323fd4 · Ranger language documentation (MIT)