GraphProvider as the data prop. The spec names that table’s columns by key through its mapping. So one spec can draw many datasets, and one dataset can be drawn many ways.
Basic structure
Data is a table with declared columns and rows:columns array defines the shape; rows holds the values.
Referencing columns from a spec
A spec never holds data. It names the columns it needs in its mapping. The strings you pass tomapping (or the createSpec shorthand) are column keys:
label is display text only. Legends and tooltips show it, and fall back to the key when there is none. An axis title comes from config({ axes: { y: { label: '…' } } }); without one, the axis shows the column’s label, or no title when the column has none.
Row keys must exactly match a column
key. Values under keys with no matching
column definition are ignored.Value format detection
Every column gets one value format, which drives how a scale interprets it and how the renderer formats it. Inference runs per column, in two passes:- The year pass. The engine looks at the first 5 non-empty rows. The first undeclared column with at least two non-empty cells there, all whole numbers from 1800 to 2199, becomes a temporal
yearcolumn. This keeps2021, 2022, 2023off a numeric axis. If any column declaresvalueFormat: { type: 'year' }, the pass is skipped. - The first non-empty cell. Every other undeclared column takes its format from its first non-empty cell alone, tried in this order: number → date → weekly date range → percentage → currency → text. A
Dateobject is a date.
null, with no warning. So row order matters:
Declaring a format
The same cell can mean two things:2010 is a headcount or a year, '1' a category or a number. When you know, set valueFormat on the column. A declared column skips inference and is parsed and formatted under that format:
dateFormat its cells use, such as { type: 'date', dateFormat: 'dd-MM-yyyy' }. A cell that does not fit becomes null, as under inference.
Declare a numeric format for every count column whose values could pass for years. Declaring the year column as integer keeps that column numeric, but the year pass still checks its undeclared siblings: an undeclared population column holding 1950, 2000 would become dates. Declare both to keep both numeric:
type: 'year' stops the year pass for the whole table; an integer declaration does not.
Numbers
Numbers and numeric strings are read as numbers. Thousands separators, decimals and magnitude suffixes are supported:Dates
Date-like strings are parsed in many formats: ISO dates, named months and locale-specific orderings:Jan, Feb) work as well as full names. data._metadata.parsingLocale decides whether an ambiguous date like 01/02/2024 is read day-first (en-GB, pt-PT, ar) or month-first (en-US). The first non-empty cell fixes one date format for the whole column, so a column that mixes 2024-01-15 with 15/01/2024 loses the cells that do not match.
Weekly date ranges are also detected: 1 Feb – 7 Feb or 1 Feb 2024 – 7 Feb 2024, each a 7-day span.
Dates without a year
A format with no year —month (Jan), day_month (14 Jan) or a weekly range without one — gets a synthetic year. The engine walks the column in row order, one sequence per group. The sequence starts in the current year. Each time a date falls earlier in the year than the one before it, the year advances. So Jan … Dec, Jan, Feb reads as 14 consecutive months instead of folding back on itself, and reordering the rows moves the axis.
Percentages
Values with a% suffix are percentages, stored as fractions: '64.5%' becomes 0.645. The renderer multiplies by 100 when it formats, so the axis reads as you wrote it.
12 among '64.5%' values renders as 1200%. Write '12%'.
Currencies
Currency strings are parsed by their symbol. Supported symbols:$, €, £, ¥, ₹, ₱, ₩, ₪, ₫, ₽, ฿, ₦, ₺, zł, kr, Fr, R, P, R$, Rp, RM, د.إ, ﷼, Ch$, NT$, HK$, S$, A$, C$, NZ$, MX$.
-$100, $-100).
Text
Anything else is text.How formats reach scales
The format feeds the scale you declare for each aesthetic. A bare position scale (scale.x()) picks its type from the column’s format. For x, y and ySecondary:
- A text column → a discrete (band) scale.
- A numeric, percentage or currency column → a continuous scale.
- A date column → a
datetimescale.
color, a text column infers a discrete scale; a numeric or date column infers a continuous one. On size, alpha and strokeWidth, a date column infers continuous: timestamps become plain numbers, since a ramp needs no date-aware ticks. On lineType, every format infers discrete. An aesthetic bound to a constant ({ value: 5 }), left unmapped, or pointing at a column that is not in the data falls back to continuous.
An explicit method — scale.x.continuous(), scale.x.discrete(), scale.x.datetime() — overrides the inference. It must still fit the column’s format: a continuous scale on a date column fails to compile with INCOMPATIBLE_TYPE. See the line chart guide for worked examples.
Empty and missing values
A cell is empty when it isnull, undefined, an empty or whitespace-only string, or '-'. Empty cells become null in the parsed column. Two rules follow:
- A row whose every cell is empty is dropped.
- A column with no non-empty cell at all is dropped, so nothing can map to it.
missingValues param breaks the path, bridges it, or treats the gap as zero.
Schema
Column[]
required
The column definitions.
string
required
A unique, stable name for the column. Row objects use it as their key, and a
spec’s mapping references it.
string
Display text for legends, tooltips and, when the axis config sets no label,
the axis title. Legends and tooltips fall back to the
key.ExplicitValueFormat
How to read the column’s cells when you know better than inference, for
example
{ type: 'integer' }, { type: 'text' } or
{ type: 'currency', iso: 'usd' }. A declared column skips inference; see
Declaring a format.Row[]
required
The rows. Each is an object keyed by column key. A value is a
string,
number, Date or null.object
Host state carried with the table. The engine reads
parsingLocale; the other
keys are set by the Graphy editor and are not part of the SDK.There are two
parsingLocale settings with different jobs.
data._metadata.parsingLocale (default 'en-GB') decides how data cells are
parsed. config({parsingLocale}) (default 'en-US') decides how values
written in the spec, such as highlight predicates and annotation anchors, are
read. It is also the display locale unless formattingLocale on
GraphProvider overrides it. The config one does not change how a data cell
is read.
