Overview
The mayaCharts spec is plain JSON. Rule: x is always the category,
y is always the value, whatever the orientation. yDomain is
always the value axis.
Where the element reads the spec
The <maya-chart> element takes its spec from the first of these that is
set: the spec property (assigning data sets it too), then the
JSON script child, then the spec attribute. A property you have set wins over
any later change to the attribute, so use one source. Assign undefined to the
property to fall back to the script child or the attribute.
Data fields
Encoding fields
Formatting fields
Interaction fields
Time axes
Dates in x values are automatically detected and placed on a proportional time axis when
using line, area or vertical bar charts. ISO 8601 dates are recognized as year-month
("2024-03"), full date ("2024-03-05") or date-time ("2024-03-05T14:30:00Z"); a date-time
without an offset is read as UTC. A bare year such as "2024" stays a category. Numbers are
never auto-detected as dates; use xType: "time" explicitly to interpret them
as epoch milliseconds. A time axis preserves the chronological order and spacing of dates,
so sort and limit options keep a category axis instead. To disable time axis detection and
use a category axis with ISO dates, set xType: "category". All ticks and
boundaries are placed at UTC calendar boundaries.
Large data
A chart handles up to a million rows wherever the chart makes sense, by reducing what it
draws. Line and area charts reduce long series to about one point per 2 px of plot width
(at most 1000 categories, and 4000 shared between series) using the LTTB (Largest Triangle
Three Buckets) downsampling algorithm, keeping each series' first, last, minimum and
maximum points so trends and extremes remain visible. A time axis reduces whenever it has
more points than that budget; a category axis reduces past 1000 categories, over the
category index. A kpi thins its sparkline the same way. The data table and screen reader
description indicate how many points are displayed. A bar with more categories than fit
(past 10000 marks) and no limit keeps the top N by total, N being 10 per 40
px of plot width, and rolls the rest into "Other". Scatter and beeswarm charts above 10000
visible points are drawn as density cells. A table draws the rows that fit its height, and
its hidden data table lists the first 1000. The bar roll-up also adds a sentence to
renderParts(...).warnings. Charts that cannot reduce without changing meaning
(waterfall, dumbbell, parallel and the module charts) fail with
too-many-marks, naming the mark count, the 10000 cap and the row count, and
suggest limit or aggregate.
The row pass (grouping, aggregation, time parsing, validation) is cached per
data array: a resize, legend toggle, zoom or view change re-renders without
walking the rows again. The cache is keyed by the array's identity, length, first row and
last row, so a push, a shift or a replaced last row is noticed; after editing any other
row in place, assign a new array (chart.data = [...rows]).
Style fields
Examples
1. Currency bar
{ "type": "bar", "x": "month", "y": "revenue", "format": "currency",
"data": [{ "month": "Jan", "revenue": 10500 }] }
Vertical bar chart with currency-formatted values.
2. Stacked bar
{ "type": "bar", "x": "state", "y": "units", "series": "region", "stack": true,
"data": [{ "state": "CA", "region": "West", "units": 120 }] }
Horizontal regions, stacked per state.
3. Horizontal sorted limited labelled bar
{ "type": "bar", "horizontal": true, "x": "product", "y": "margin",
"sort": "desc", "limit": 5, "labels": true,
"data": [{ "product": "A", "margin": 22 }] }
Top 5 products by margin, descending, with on-bar labels.
4. Sign-coloured percent bar
{ "type": "bar", "x": "metric", "y": "variance", "format": "percent",
"colorBy": "sign",
"data": [{ "metric": "revenue", "variance": 0.15 }] }
Bars toned green (positive) or red (negative).
5. Multi-measure line with date format and zoom
{ "type": "line", "x": "date", "y": ["revenue", "units"], "zoom": true,
"format": { "date": "date", "revenue": "currency" },
"data": [{ "date": "2024-01-01", "revenue": 10000, "units": 50 }] }
Two measures on the y-axis with a measure toggle; drag to zoom, Reset to restore.
6. Stacked area
{ "type": "area", "x": "month", "y": "sales", "series": "region", "stack": true,
"data": [{ "month": "Jan", "region": "North", "sales": 1500 }] }
Regions stacked over time.
7. Waterfall with totals
{ "type": "waterfall", "x": "stage", "y": "amount", "totals": ["Q1", "FY"],
"data": [{ "stage": "Q1", "amount": 100 }] }
Flow chart with Q1 and FY marked as running totals.
8. Bubble scatter with select
{ "type": "scatter", "x": "population", "y": "gdp", "size": "area", "name": "country",
"select": "multi",
"data": [{ "country": "USA", "population": 331, "gdp": 23, "area": 9.8 }] }
Countries as bubbles; click to select multiple.
9. Heatmap count
{ "type": "heatmap", "x": "hour", "y": "traffic", "aggregate": "count",
"data": [{ "hour": "09", "traffic": "high" }] }
Count of observations per hour and traffic level.
10. Treemap drill
{ "type": "treemap", "path": ["region", "state", "product"], "y": "revenue",
"drill": true,
"data": [{ "region": "West", "state": "CA", "product": "A", "revenue": 5000 }] }
Hierarchical treemap; click to drill into regions, states, and products.
11. Weave
{ "type": "weave", "x": "year", "y": "sales", "series": "team",
"data": [{ "year": "2024", "team": "A", "sales": 10 }, { "year": "2024", "team": "B", "sales": 12 },
{ "year": "2025", "team": "A", "sales": 15 }, { "year": "2025", "team": "B", "sales": 9 }] }
Ranks per year as threads that cross over and under. Import mayacharts/weave.
12. Units
{ "type": "units", "x": "plan", "y": "spend", "name": "customer",
"data": [{ "customer": "c1", "plan": "Pro", "spend": 120 }, { "customer": "c2", "plan": "Free", "spend": 0 }] }
One dot per customer that flies between waffle, bars and swarm. The legend toggles plans. Import mayacharts/units.
13. Orbit
{ "type": "orbit", "x": "product", "y": "revenue", "y2": "growth",
"format": { "growth": "percent" },
"data": [{ "product": "A", "revenue": 500, "growth": 0.12 }, { "product": "B", "revenue": 300, "growth": -0.05 }] }
Planets sized by revenue; growth sets each planet's speed and direction. Import mayacharts/orbit.
14. Constellation
{ "type": "constellation", "x": "account", "y": ["revenue", "seats", "tickets"],
"data": [{ "account": "Acme", "revenue": 120, "seats": 40, "tickets": 3 },
{ "account": "Globex", "revenue": 80, "seats": 25, "tickets": 9 },
{ "account": "Initech", "revenue": 95, "seats": 30, "tickets": 4 }] }
Accounts placed by how alike their measures are. Import mayacharts/constellation.