mayacharts 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +619 -0
  3. package/dist/core/a11y.d.ts +10 -0
  4. package/dist/core/format.d.ts +2 -0
  5. package/dist/core/layout.d.ts +22 -0
  6. package/dist/core/marks/bar.d.ts +2 -0
  7. package/dist/core/marks/dumbbell.d.ts +3 -0
  8. package/dist/core/marks/heatmap.d.ts +3 -0
  9. package/dist/core/marks/kpi.d.ts +2 -0
  10. package/dist/core/marks/line.d.ts +4 -0
  11. package/dist/core/marks/scatter.d.ts +2 -0
  12. package/dist/core/registry.d.ts +13 -0
  13. package/dist/core/render.d.ts +8 -0
  14. package/dist/core/scale.d.ts +3 -0
  15. package/dist/core/shape.d.ts +14 -0
  16. package/dist/core/strings.d.ts +37 -0
  17. package/dist/core/svg.d.ts +13 -0
  18. package/dist/core/ticks.d.ts +2 -0
  19. package/dist/core/types.d.ts +424 -0
  20. package/dist/core/validate.d.ts +24 -0
  21. package/dist/element/animate.d.ts +13 -0
  22. package/dist/element/drill.d.ts +12 -0
  23. package/dist/element/html.d.ts +1 -0
  24. package/dist/element/maya-chart.d.ts +21 -0
  25. package/dist/element/measure.d.ts +9 -0
  26. package/dist/element/select.d.ts +14 -0
  27. package/dist/element/tooltip.d.ts +10 -0
  28. package/dist/element/zoom.d.ts +11 -0
  29. package/dist/element.d.ts +15 -0
  30. package/dist/element.js +4 -0
  31. package/dist/element.js.map +1 -0
  32. package/dist/flow.d.ts +3 -0
  33. package/dist/flow.js +3 -0
  34. package/dist/flow.js.map +1 -0
  35. package/dist/geo.d.ts +3 -0
  36. package/dist/geo.js +3 -0
  37. package/dist/geo.js.map +1 -0
  38. package/dist/global.d.ts +4 -0
  39. package/dist/hierarchy.d.ts +15 -0
  40. package/dist/hierarchy.js +3 -0
  41. package/dist/hierarchy.js.map +1 -0
  42. package/dist/index.d.ts +5 -0
  43. package/dist/index.js +4 -0
  44. package/dist/index.js.map +1 -0
  45. package/dist/maya.global.js +4 -0
  46. package/dist/maya.global.js.map +1 -0
  47. package/dist/styles/theme.d.ts +1 -0
  48. package/dist/theme.css +1 -0
  49. package/llms.txt +102 -0
  50. package/package.json +105 -0
  51. package/schema.json +381 -0
@@ -0,0 +1 @@
1
+ export declare const css: string;
package/dist/theme.css ADDED
@@ -0,0 +1 @@
1
+ :host,.maya-root{--maya-font:system-ui,sans-serif;--maya-font-size:12px;--maya-fg:light-dark(#1f2328,#e6edf3);--maya-fg-muted:light-dark(#656d76,#9198a1);--maya-grid:color-mix(in oklab,var(--maya-fg) 12%,transparent);--maya-bg:light-dark(#fff,#0d1117);--maya-accent:oklch(.6 .17 255);--maya-radius:2px;--maya-tooltip-bg:var(--maya-fg);--maya-tooltip-fg:var(--maya-bg);--maya-focus:var(--maya-accent);--maya-good:light-dark(#1a7f37,#3fb950);--maya-bad:light-dark(#cf222e,#f85149);--maya-series-1:var(--maya-accent);--maya-series-2:oklch(.66 .16 50);--maya-series-3:oklch(.62 .15 160);--maya-series-4:oklch(.66 .17 330);--maya-series-5:oklch(.62 .14 90);--maya-series-6:oklch(.62 .12 205);--maya-series-7:oklch(.64 .19 22);--maya-series-8:oklch(.62 .16 295);color-scheme:light dark}@supports not (color:light-dark(#000,#fff)){:host,.maya-root{--maya-fg:#1f2328;--maya-fg-muted:#656d76;--maya-bg:#fff}@media (prefers-color-scheme:dark){:host,.maya-root{--maya-fg:#e6edf3;--maya-fg-muted:#9198a1;--maya-bg:#0d1117}}}:host{display:block;position:relative;container-type:inline-size;min-height:200px}.maya{display:flex;flex-direction:column;height:100%;font:var(--maya-font-size) var(--maya-font);font-variant-numeric:tabular-nums;color:var(--maya-fg)}.maya-title{font-weight:600;font-size:14px}.maya-legend,.maya-crumbs{color:var(--maya-fg-muted);display:flex;flex-wrap:wrap;align-items:center;gap:4px 12px;margin:0 0 8px}.maya-crumbs{min-height:1.25em;line-height:1.25}.maya-legend button,.maya-crumbs button,.maya-reset{display:inline-flex;align-items:center;gap:6px;border:0;background:none;padding:0;font:inherit;color:var(--maya-fg-muted);cursor:pointer;border-radius:4px}.maya-legend [aria-pressed=false]{opacity:.4}:is(.maya-legend,.maya-crumbs) button:focus-visible,.maya-reset:focus-visible,.maya-ctl :focus-visible{outline:2px solid var(--maya-focus);outline-offset:2px}i{width:10px;height:10px;border-radius:3px;background:var(--c)}[data-maya=ramp]{display:flex;align-items:center;gap:6px}[data-maya=ramp] i{width:80px;height:8px;background:linear-gradient(90deg,color-mix(in oklab,var(--maya-accent) 20%,var(--b)),var(--maya-accent))}[data-q],[data-maya=ramp] i{--b:light-dark(var(--maya-bg),color-mix(in oklab,var(--maya-accent) 15%,var(--maya-bg)))}.maya-legend span{display:inline-flex;align-items:center;gap:6px}.maya-reset{position:absolute;top:4px;right:4px;border:1px solid var(--maya-grid);border-radius:99px;padding:2px 10px;background:var(--maya-bg)}.maya-ctl{position:relative;display:inline-grid;grid-auto-flow:column;grid-auto-columns:1fr;align-self:flex-start;margin:0 0 8px;padding:2px;border-radius:8px;background:var(--maya-grid)}.maya-ctl::before{content:'';position:absolute;inset:2px auto 2px 2px;width:calc(100% - 4px);border-radius:6px;background:var(--maya-bg);transition:transform .2s}.maya-ctl[data-n="2"]::before{width:calc((100% - 4px)/2)}.maya-ctl[data-n="3"]::before{width:calc((100% - 4px)/3)}.maya-ctl[data-n="4"]::before{width:calc((100% - 4px)/4)}.maya-ctl[data-i="1"]::before{transform:translateX(100%)}.maya-ctl[data-i="2"]::before{transform:translateX(200%)}.maya-ctl[data-i="3"]::before{transform:translateX(300%)}.maya-ctl [role=radio]{border:0;background:none;padding:0;font:inherit;color:var(--maya-fg-muted);cursor:pointer;position:relative;padding:4px 12px;border-radius:6px}.maya-ctl [aria-checked=true]{color:var(--maya-fg);font-weight:600}.maya-err{margin:0;padding:8px;color:var(--maya-bad);white-space:pre-wrap;font:12px monospace}.maya-box{flex:1;min-height:0;position:relative}.maya-box svg{display:block;width:100%;height:100%;overflow:visible}.maya-svg{direction:ltr;font:var(--maya-font-size) var(--maya-font);font-variant-numeric:tabular-nums}.maya-svg text{fill:var(--maya-fg-muted);unicode-bidi:plaintext}[data-maya=grid] *{stroke:var(--maya-grid);shape-rendering:crispEdges}[data-s="0"]{--c:var(--maya-series-1)}[data-s="1"]{--c:var(--maya-series-2)}[data-s="2"]{--c:var(--maya-series-3)}[data-s="3"]{--c:var(--maya-series-4)}[data-s="4"]{--c:var(--maya-series-5)}[data-s="5"]{--c:var(--maya-series-6)}[data-s="6"]{--c:var(--maya-series-7)}[data-s="7"]{--c:var(--maya-series-8)}[data-other],[data-total]{--c:var(--maya-fg-muted)}[data-tone=good]{--c:var(--maya-good)}[data-tone=bad]{--c:var(--maya-bad)}[data-q]{--c:color-mix(in oklab,var(--maya-accent) var(--q),var(--b))}[data-q="0"]{--q:20%}[data-q="1"]{--q:29%}[data-q="2"]{--q:38%}[data-q="3"]{--q:47%}[data-q="4"]{--q:56%}[data-q="5"]{--q:64%}[data-q="6"]{--q:73%}[data-q="7"]{--q:82%}[data-q="8"]{--q:91%}[data-q="9"]{--q:100%}[data-maya=mark]{fill:var(--c,var(--maya-series-1));rx:var(--maya-radius);transform-box:fill-box;transform-origin:0 0}[data-dir=h] [data-neg]{transform-origin:100% 0}[data-maya=mark],[data-maya=link]{transition:opacity .2s}[data-maya=mark][data-active]{fill:color-mix(in oklab,var(--c,var(--maya-series-1)),var(--maya-fg) 18%)}:where([data-xd] circle[data-maya=mark]){stroke:var(--maya-bg);stroke-width:1}[data-maya=line]~circle[data-maya=mark]:not([data-active],[data-selected],[data-last]){fill-opacity:0}[data-maya=line]{fill:none;stroke:var(--c);stroke-width:2;stroke-linejoin:round}[data-maya=area]{fill:color-mix(in oklab,var(--c) 18%,transparent);stroke:none}[data-maya=link]{fill:var(--c);opacity:.3}[data-maya=link][data-active]{opacity:.6}line[data-maya=link]{stroke:var(--c,var(--maya-fg-muted));opacity:1}text[data-maya=mark]{fill:var(--maya-fg);font-weight:600}[data-kpi=track]{fill:var(--maya-grid)}[data-kpi=target]{stroke:var(--maya-fg)}[data-maya=labels] [data-tone]{fill:var(--c)}[data-maya=labels] :is([data-kpi=period],[data-kpi=of]){fill:var(--maya-fg-muted)}[data-line] i{height:2px;border-radius:1px}[data-depth]{stroke:var(--maya-bg);stroke-width:1}[data-maya=marks]:has([data-active]) [data-maya=mark]:not([data-active],text){opacity:.55}[data-maya=marks]:has([data-selected]) [data-maya=mark]:not([data-selected]){opacity:.35}[data-selected]{stroke:var(--maya-fg);stroke-width:2}.maya:has([data-s="0"]:hover) [data-maya=mark]:not([data-s="0"]){opacity:.3}.maya:has([data-s="1"]:hover) [data-maya=mark]:not([data-s="1"]){opacity:.3}.maya:has([data-s="2"]:hover) [data-maya=mark]:not([data-s="2"]){opacity:.3}.maya:has([data-s="3"]:hover) [data-maya=mark]:not([data-s="3"]){opacity:.3}.maya:has([data-s="4"]:hover) [data-maya=mark]:not([data-s="4"]){opacity:.3}.maya:has([data-s="5"]:hover) [data-maya=mark]:not([data-s="5"]){opacity:.3}.maya:has([data-s="6"]:hover) [data-maya=mark]:not([data-s="6"]){opacity:.3}.maya:has([data-s="7"]:hover) [data-maya=mark]:not([data-s="7"]){opacity:.3}[data-maya=labels],[data-maya=cross]{pointer-events:none}[data-maya=cross]{opacity:0}[data-maya=labels] text{fill:var(--maya-fg);paint-order:stroke;stroke:var(--maya-bg);stroke-width:3;stroke-linejoin:round}[data-maya=labels] [data-in]{stroke:none}[data-maya=cross] line{stroke:var(--maya-fg-muted);stroke-dasharray:3 3}[data-maya=brush]{fill:var(--maya-accent);fill-opacity:.12;stroke:var(--maya-accent);vector-effect:non-scaling-stroke;pointer-events:none}.maya-svg:focus-visible{outline:2px solid var(--maya-focus)}.maya-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.maya-probe{position:absolute;width:0;height:0;pointer-events:none;anchor-name:--maya-probe}.maya-tip{margin:0;inset:auto;border:0;padding:6px 8px;background:var(--maya-tooltip-bg);color:var(--maya-tooltip-fg);border-radius:6px;box-shadow:0 2px 8px #0003;font:var(--maya-font-size) var(--maya-font);pointer-events:none}@supports (anchor-name:--x){.maya-tip{position-anchor:--maya-probe;position-area:block-start;position-try-fallbacks:flip-block,block-start span-inline-start,block-start span-inline-end;margin:8px}}.maya-tip{opacity:0;transition:opacity .12s}.maya-tip.maya-open{opacity:1}.maya-tip b{display:block}.maya-tip div{display:flex;align-items:center;gap:6px}.maya-tip i{outline:1px solid}.maya-tip [data-on]{font-weight:600}@media (pointer:coarse){:is(.maya-legend,.maya-crumbs) button,.maya-ctl [role=radio],.maya-reset,.maya-crumbs{min-height:24px}}@container (max-width:320px){.maya-legend{display:none}.maya-title{font-size:12px}}@media (prefers-contrast:more){:host,.maya-root{--maya-fg-muted:var(--maya-fg);--maya-grid:color-mix(in oklab,var(--maya-fg) 40%,transparent)}}@media (forced-colors:active){.maya-svg,i{forced-color-adjust:none}[data-maya=mark]{stroke:CanvasText;stroke-width:1}[data-tone=bad]{stroke-dasharray:4 2}}@media (prefers-reduced-motion:reduce){*{transition:none!important}}
package/llms.txt ADDED
@@ -0,0 +1,102 @@
1
+ mayaCharts: Beautiful, accessible charts in five lines. Zero dependencies. The browser is the chart engine.
2
+ Uses modern platform: Custom Elements, Web Animations API, CSS Anchor Positioning + Popover, CSS custom properties.
3
+
4
+ USAGE:
5
+ HTML: <maya-chart><script type="application/json">{spec}</script></maya-chart>
6
+ JavaScript: chart.spec = {type: "bar", data, x: "month", y: "revenue"}; chart.data = newRows;
7
+ SSR: import {render, renderShell} from "mayacharts"; render(spec, {width, height});
8
+ Global: <script src="https://cdn.jsdelivr.net/npm/mayacharts/dist/maya.global.js"></script>
9
+ Modules: import "mayacharts/hierarchy" (treemap, sunburst); "mayacharts/flow" (sankey); "mayacharts/geo" (hexmap).
10
+
11
+ SPEC FIELDS:
12
+ type: enum = required. bar line area scatter heatmap waterfall kpi dumbbell treemap sunburst sankey hexmap
13
+ data: Row[] = required. Row objects with field values.
14
+ y: field | field[] = required. Value field; array adds measure toggle.
15
+ x: field = "". Category field (scatter: numeric x; hexmap: state).
16
+ aggregate: sum|mean|count|min|max = sum. How rows sharing (category, series) combine.
17
+ sort: asc|desc = data order. Order categories by total across all series. bar line area heatmap.
18
+ limit: positive integer = -. Keep top N categories; rest roll up into "Other". bar line area heatmap.
19
+ series: field = null. Split into series (heatmap: row category). bar line area scatter heatmap.
20
+ path: field[] = []. Hierarchy outer to inner. treemap sunburst sankey; bar/line/area with drill.
21
+ size: field = null. Bubble area (sqrt scale). scatter only.
22
+ name: field = null. Point identity and tooltip title. scatter only.
23
+ totals: string[] = []. x values drawn as running-total bars. waterfall only.
24
+ stack: boolean = false. Stack series instead of grouping. bar area only.
25
+ horizontal: boolean = false. Categories on left axis. bar dumbbell.
26
+ y2: field = null. Second value field drawn as line on right axis. bar only.
27
+ format: preset|{[field]: preset|Intl} = auto. Per field or one string for all measures.
28
+ titles: {[field]: string} = {}. Display names everywhere (axis, tooltip, legend, table).
29
+ labels: boolean = null. Formatted value on marks. heatmap: true at ≥24 px.
30
+ text: {[key]: string} = {}. Localised UI strings with {0} placeholders. Keys: noData other back reset showing drilledInto zoomedTo selected selectionCleared chartOf firstOf measures crumbs positive negative above below.
31
+ locale: BCP47 = en-US. Formatting locale.
32
+ currency: ISO4217 = USD. Currency for "currency" preset.
33
+ title: string = "". Visible heading and accessible name.
34
+ description: string = "". Accessible description; auto-generated when omitted.
35
+ yDomain: [min, max] = null. Fixed value-axis domain. Not with y array.
36
+ xDomain: [min, max] = null. Fixed x domain. scatter only.
37
+ tooltip: boolean = true. Hover/keyboard tooltip.
38
+ legend: boolean = true if series. Legend; clicking toggles series.
39
+ drill: boolean = false. Click/Enter zooms into branch of path; breadcrumb, Back, Escape pop. treemap sunburst sankey; bar line area with path.
40
+ select: true|"multi" = off. Click/Enter/legend selects marks; Escape clears. Not with drill. All types but sankey.
41
+ zoom: boolean = false. Drag to zoom. line area scatter. Reset, double-click, Escape restore.
42
+ animate: boolean = true. Animate updates (element only).
43
+ colors: string[]|{[series]: color} = null. Max 8; slot assignment stable across updates.
44
+ colorBy: "sign"|{target: n}|field = null. Tone by sign or target, or ramp by numeric field. Not with series. All types but heatmap and sankey.
45
+ theme: {[token]: css} = {}. Theme token overrides (CSS values, allowlisted). Tokens: font fontSize fg fgMuted grid bg accent radius tooltipBg tooltipFg focus good bad series1..series8.
46
+ grid: boolean = true. Grid lines perpendicular to value axis.
47
+ xAxis: boolean = true. Bottom axis.
48
+ yAxis: boolean = true. Left axis.
49
+ table: boolean = true. Visually hidden data table for screen readers.
50
+ $schema: string = "". Ignored; for editors and LLMs.
51
+
52
+ EXAMPLES:
53
+ 1. Currency bar: {type: "bar", x: "month", y: "revenue", format: "currency", data: [{month: "Jan", revenue: 10500}]}
54
+ 2. Stacked bar: {type: "bar", x: "state", y: "units", series: "region", stack: true, data: [{state: "CA", region: "West", units: 120}]}
55
+ 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}]}
56
+ 4. Sign-coloured percent bar: {type: "bar", x: "metric", y: "variance", format: "percent", colorBy: "sign", data: [{metric: "revenue", variance: 0.15}]}
57
+ 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}]}
58
+ 6. Stacked area: {type: "area", x: "month", y: "sales", series: "region", stack: true, data: [{month: "Jan", region: "North", sales: 1500}]}
59
+ 7. Waterfall with totals: {type: "waterfall", x: "stage", y: "amount", totals: ["Q1", "FY"], data: [{stage: "Q1", amount: 100}]}
60
+ 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}]}
61
+ 9. Heatmap count: {type: "heatmap", x: "hour", y: "traffic", aggregate: "count", data: [{hour: "09", traffic: "high"}]}
62
+ 10. Treemap drill: {type: "treemap", path: ["region", "state", "product"], y: "revenue", drill: true, data: [{region: "West", state: "CA", product: "A", revenue: 5000}]}
63
+ 11. KPI with delta and sparkline: {type: "kpi", x: "month", y: "sales", format: "currency", data: [{month: "Mar", sales: 45000}, {month: "Apr", sales: 50700}, {month: "May", sales: 54500}]}
64
+ 12. Dumbbell horizontal: {type: "dumbbell", x: "region", y: "revenue", series: "year", horizontal: true, format: "currency", data: [{region: "North", year: "2024", revenue: 45000}, {region: "North", year: "2025", revenue: 52000}]}
65
+ 13. Bar with dual axis: {type: "bar", x: "month", y: "revenue", y2: "customers", format: {revenue: "currency", customers: "integer"}, data: [{month: "Jan", revenue: 10500, customers: 120}, {month: "Feb", revenue: 12000, customers: 145}]}
66
+
67
+ ERROR CODES:
68
+ spec-not-object: spec must be a plain object
69
+ missing-field: type/data/x (or path)/y is required but missing
70
+ unknown-type: chart type not recognized (with module hint if needed)
71
+ data-not-array: data must be an array of row objects
72
+ row-not-object: data[i] must be a plain object
73
+ unknown-field: field-valued option names no field in data
74
+ non-numeric-y: y field value not a finite number (null allowed)
75
+ non-numeric-field: size/scatter x/colorBy field value not a finite number
76
+ non-positive-value: treemap/sunburst/sankey y value must be positive
77
+ unknown-option: top-level spec key not recognized
78
+ invalid-option: option value wrong type or invalid value
79
+ option-unsupported: option not valid for this chart type or incompatible with another option
80
+ stack-unsupported: stack: true not allowed with type "line" (use "area" instead)
81
+ invalid-domain: yDomain/xDomain not [min, max] with min < max
82
+ invalid-format: format preset unknown, bad Intl options, or unsupported locale/currency
83
+ invalid-theme: theme token not recognized
84
+ unsafe-css-value: colors/theme CSS value blocked by allowlist (no url(), other functions, ; { } < > \)
85
+ invalid-size: RenderOptions width/height not a finite number > 0
86
+ unknown-state: hexmap x value is not a US state (two-letter code or full name; 50 states, DC, PR)
87
+ too-many-marks: more than 5000 marks (suggest limit or aggregate)
88
+
89
+ EVENTS AND STATE:
90
+ Events (bubbles: true, composed: true):
91
+ maya-select {selected: Sel[], target: (Sel & {value}) | null}
92
+ maya-view {measure, drill, window, hidden} (user actions only; window = zoom slice)
93
+ maya-error {code, path, message} (cancelable with preventDefault())
94
+ maya-render {} (signals host that render is complete)
95
+ Two-way sync properties:
96
+ el.view: {measure?, drill?, window?, hidden?} - getter/setter (no events on set; {} resets)
97
+ el.selected: Sel[] - getter/setter (no events on set)
98
+
99
+ RULES FOR AGENTS:
100
+ 1. Never put functions in spec: the spec is JSON, serializable, diffable, and hashable. No callbacks, formatters, or data transforms.
101
+ 2. Unknown types need imports: if type "treemap", "sunburst", "sankey", or "hexmap" fails with unknown-type, add import "mayacharts/<module>".
102
+ 3. Read errors.html when MayaSpecError thrown: every error links https://bbekshr.github.io/mayacharts/errors.html#<code> with cause and fixed example.
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "mayacharts",
3
+ "version": "0.1.0",
4
+ "description": "Beautiful, accessible charts in five lines. Zero dependencies. The browser is the chart engine.",
5
+ "keywords": [
6
+ "chart",
7
+ "charts",
8
+ "svg",
9
+ "web-component",
10
+ "custom-element",
11
+ "dataviz",
12
+ "ssr"
13
+ ],
14
+ "license": "MIT",
15
+ "author": "Bibek Shrestha",
16
+ "homepage": "https://bbekshr.github.io/mayacharts/",
17
+ "repository": {
18
+ "type": "git",
19
+ "url": "git+https://github.com/BbekShr/mayacharts.git"
20
+ },
21
+ "bugs": "https://github.com/BbekShr/mayacharts/issues",
22
+ "type": "module",
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ },
28
+ "./element": {
29
+ "types": "./dist/element.d.ts",
30
+ "default": "./dist/element.js"
31
+ },
32
+ "./hierarchy": {
33
+ "types": "./dist/hierarchy.d.ts",
34
+ "default": "./dist/hierarchy.js"
35
+ },
36
+ "./flow": {
37
+ "types": "./dist/flow.d.ts",
38
+ "default": "./dist/flow.js"
39
+ },
40
+ "./geo": {
41
+ "types": "./dist/geo.d.ts",
42
+ "default": "./dist/geo.js"
43
+ },
44
+ "./global": "./dist/maya.global.js",
45
+ "./theme.css": "./dist/theme.css",
46
+ "./schema.json": "./schema.json",
47
+ "./jsx": {
48
+ "types": "./dist/jsx.d.ts"
49
+ }
50
+ },
51
+ "sideEffects": [
52
+ "./dist/element.js",
53
+ "./dist/hierarchy.js",
54
+ "./dist/flow.js",
55
+ "./dist/geo.js",
56
+ "./dist/maya.global.js",
57
+ "./src/element.ts",
58
+ "./src/hierarchy.ts",
59
+ "./src/flow.ts",
60
+ "./src/geo.ts",
61
+ "./src/global.ts"
62
+ ],
63
+ "files": [
64
+ "dist",
65
+ "schema.json",
66
+ "llms.txt"
67
+ ],
68
+ "engines": {
69
+ "node": ">=22"
70
+ },
71
+ "publishConfig": {
72
+ "access": "public"
73
+ },
74
+ "scripts": {
75
+ "dev": "node scripts/ssr-demo.ts && vite --config site/vite.config.ts",
76
+ "build": "vite build --mode index && vite build --mode element && vite build --mode hierarchy && vite build --mode flow && vite build --mode geo && vite build --mode global && tsc -p tsconfig.build.json",
77
+ "typecheck": "tsc --noEmit",
78
+ "test": "vitest run",
79
+ "test:watch": "vitest",
80
+ "size": "node scripts/size.mjs",
81
+ "format": "prettier --write .",
82
+ "format:check": "prettier --check .",
83
+ "e2e": "playwright test",
84
+ "site:build": "node scripts/ssr-demo.ts && vite build --config site/vite.config.ts"
85
+ },
86
+ "mayaSize": {
87
+ "dist/index.js": 20480,
88
+ "dist/element.js": 28672,
89
+ "dist/theme.css": 2450,
90
+ "dist/hierarchy.js": 3072,
91
+ "dist/flow.js": 2560,
92
+ "dist/geo.js": 3584,
93
+ "dist/maya.global.js": 32768
94
+ },
95
+ "devDependencies": {
96
+ "@axe-core/playwright": "^4.13.0",
97
+ "@playwright/test": "^1.63.0",
98
+ "@types/node": "^26.6.4",
99
+ "happy-dom": "^20.14.5",
100
+ "prettier": "^3.9.9",
101
+ "typescript": "^7.0.2",
102
+ "vite": "^8.3.2",
103
+ "vitest": "^5.0.3"
104
+ }
105
+ }
package/schema.json ADDED
@@ -0,0 +1,381 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://bbekshr.github.io/mayacharts/schema.json",
4
+ "title": "mayaCharts spec",
5
+ "type": "object",
6
+ "required": ["type", "data", "y"],
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "$schema": {
10
+ "type": "string",
11
+ "description": "Ignored; lets editors and LLMs find the JSON schema."
12
+ },
13
+ "type": {
14
+ "type": "string",
15
+ "enum": [
16
+ "bar",
17
+ "line",
18
+ "area",
19
+ "scatter",
20
+ "heatmap",
21
+ "waterfall",
22
+ "kpi",
23
+ "dumbbell",
24
+ "treemap",
25
+ "sunburst",
26
+ "sankey",
27
+ "hexmap"
28
+ ],
29
+ "description": "Chart type. treemap/sunburst need `mayacharts/hierarchy`, sankey `flow`, hexmap `geo`."
30
+ },
31
+ "data": {
32
+ "type": "array",
33
+ "items": {
34
+ "type": "object"
35
+ },
36
+ "description": "Row objects."
37
+ },
38
+ "aggregate": {
39
+ "type": "string",
40
+ "enum": ["sum", "mean", "count", "min", "max"],
41
+ "default": "sum",
42
+ "description": "How rows sharing a (category, series) combine. `count` counts non-null y."
43
+ },
44
+ "sort": {
45
+ "type": "string",
46
+ "enum": ["asc", "desc"],
47
+ "description": "Order categories by total across all series (hidden ones too)."
48
+ },
49
+ "limit": {
50
+ "type": "integer",
51
+ "minimum": 1,
52
+ "description": "Keep the top N categories by total; the rest roll up into a final \"Other\"."
53
+ },
54
+ "x": {
55
+ "type": "string",
56
+ "description": "Category field (scatter: numeric x; hexmap: US state). Not used by path types."
57
+ },
58
+ "y": {
59
+ "oneOf": [
60
+ {
61
+ "type": "string",
62
+ "description": "Value field."
63
+ },
64
+ {
65
+ "type": "array",
66
+ "items": {
67
+ "type": "string"
68
+ },
69
+ "minItems": 1,
70
+ "description": "An array adds a measure toggle, first one active."
71
+ }
72
+ ]
73
+ },
74
+ "y2": {
75
+ "type": "string",
76
+ "description": "Second value field, drawn as a line on a right axis over the bars. Vertical bar only."
77
+ },
78
+ "series": {
79
+ "type": "string",
80
+ "description": "Splits rows into series (heatmap: the row category; dumbbell: exactly two, from and to). bar line area scatter heatmap dumbbell."
81
+ },
82
+ "path": {
83
+ "type": "array",
84
+ "items": {
85
+ "type": "string"
86
+ },
87
+ "minItems": 1,
88
+ "description": "Hierarchy fields, outer to inner. treemap sunburst sankey; bar/line/area with `drill` (replaces `x`)."
89
+ },
90
+ "size": {
91
+ "type": "string",
92
+ "description": "Bubble area field (sqrt scale). scatter only."
93
+ },
94
+ "name": {
95
+ "type": "string",
96
+ "description": "Point identity and tooltip title. scatter only."
97
+ },
98
+ "totals": {
99
+ "type": "array",
100
+ "items": {
101
+ "type": "string"
102
+ },
103
+ "description": "x values drawn as running-total bars. waterfall only."
104
+ },
105
+ "stack": {
106
+ "type": "boolean",
107
+ "description": "Stack series instead of grouping them. bar and area only."
108
+ },
109
+ "horizontal": {
110
+ "type": "boolean",
111
+ "description": "Categories on the left axis. bar and dumbbell."
112
+ },
113
+ "format": {
114
+ "oneOf": [
115
+ {
116
+ "type": "string",
117
+ "enum": [
118
+ "auto",
119
+ "integer",
120
+ "decimal",
121
+ "compact",
122
+ "percent",
123
+ "currency",
124
+ "date",
125
+ "month",
126
+ "year",
127
+ "time",
128
+ "datetime"
129
+ ],
130
+ "description": "A preset for every `y`."
131
+ },
132
+ {
133
+ "type": "object",
134
+ "additionalProperties": {
135
+ "oneOf": [
136
+ {
137
+ "type": "string",
138
+ "enum": [
139
+ "auto",
140
+ "integer",
141
+ "decimal",
142
+ "compact",
143
+ "percent",
144
+ "currency",
145
+ "date",
146
+ "month",
147
+ "year",
148
+ "time",
149
+ "datetime"
150
+ ]
151
+ },
152
+ {
153
+ "type": "object",
154
+ "properties": {
155
+ "prefix": {
156
+ "type": "string"
157
+ },
158
+ "suffix": {
159
+ "type": "string"
160
+ }
161
+ },
162
+ "additionalProperties": true
163
+ }
164
+ ]
165
+ },
166
+ "description": "A preset / Intl options per field. Display only."
167
+ }
168
+ ],
169
+ "description": "Display format for values."
170
+ },
171
+ "titles": {
172
+ "type": "object",
173
+ "additionalProperties": {
174
+ "type": "string"
175
+ },
176
+ "description": "Display names by field: axis titles (shown only when set), tooltip, legend, table."
177
+ },
178
+ "labels": {
179
+ "type": "boolean",
180
+ "description": "Formatted values on marks. Default false (heatmap: true when cells are ≥ 24 px)."
181
+ },
182
+ "text": {
183
+ "type": "object",
184
+ "additionalProperties": {
185
+ "type": "string"
186
+ },
187
+ "description": "Localised UI strings with `{0}` placeholders.",
188
+ "propertyNames": {
189
+ "enum": [
190
+ "noData",
191
+ "other",
192
+ "back",
193
+ "reset",
194
+ "showing",
195
+ "drilledInto",
196
+ "zoomedTo",
197
+ "selected",
198
+ "selectionCleared",
199
+ "chartOf",
200
+ "firstOf",
201
+ "measures",
202
+ "crumbs",
203
+ "positive",
204
+ "negative",
205
+ "above",
206
+ "below",
207
+ "vs",
208
+ "ofTarget"
209
+ ]
210
+ }
211
+ },
212
+ "locale": {
213
+ "type": "string",
214
+ "default": "en-US",
215
+ "description": "BCP 47 locale for formatting."
216
+ },
217
+ "currency": {
218
+ "type": "string",
219
+ "default": "USD",
220
+ "description": "ISO 4217 code for the \"currency\" preset."
221
+ },
222
+ "title": {
223
+ "type": "string",
224
+ "description": "Visible heading, also the accessible name."
225
+ },
226
+ "description": {
227
+ "type": "string",
228
+ "description": "Accessible description; auto-generated when omitted."
229
+ },
230
+ "yDomain": {
231
+ "type": "array",
232
+ "items": {
233
+ "type": "number"
234
+ },
235
+ "minItems": 2,
236
+ "maxItems": 2,
237
+ "description": "Fixed value-axis domain. Not allowed with a `y` array."
238
+ },
239
+ "xDomain": {
240
+ "type": "array",
241
+ "items": {
242
+ "type": "number"
243
+ },
244
+ "minItems": 2,
245
+ "maxItems": 2,
246
+ "description": "Fixed x domain. scatter only."
247
+ },
248
+ "tooltip": {
249
+ "type": "boolean",
250
+ "default": true,
251
+ "description": "Hover/keyboard tooltip."
252
+ },
253
+ "legend": {
254
+ "type": "boolean",
255
+ "description": "Legend; clicking toggles series. Default: true when `series` is set."
256
+ },
257
+ "drill": {
258
+ "type": "boolean",
259
+ "description": "Click/Enter zooms into a branch of `path`; breadcrumb, Back and Escape pop."
260
+ },
261
+ "select": {
262
+ "oneOf": [
263
+ {
264
+ "type": "boolean",
265
+ "enum": [true]
266
+ },
267
+ {
268
+ "type": "string",
269
+ "enum": ["multi"]
270
+ }
271
+ ],
272
+ "description": "Click/Enter/legend selects marks, others dim; Escape clears. Not with `drill`."
273
+ },
274
+ "zoom": {
275
+ "type": "boolean",
276
+ "description": "Drag to zoom. line, area, scatter. Reset chip, double-click and Escape restore."
277
+ },
278
+ "animate": {
279
+ "type": "boolean",
280
+ "default": true,
281
+ "description": "Animate updates (element only)."
282
+ },
283
+ "colors": {
284
+ "oneOf": [
285
+ {
286
+ "type": "array",
287
+ "items": {
288
+ "type": "string"
289
+ },
290
+ "maxItems": 8,
291
+ "description": "Palette in series order (max 8)."
292
+ },
293
+ {
294
+ "type": "object",
295
+ "additionalProperties": {
296
+ "type": "string"
297
+ },
298
+ "description": "Colours by series value.",
299
+ "maxProperties": 8
300
+ }
301
+ ],
302
+ "description": "Palette or colours by series value."
303
+ },
304
+ "colorBy": {
305
+ "anyOf": [
306
+ {
307
+ "type": "string",
308
+ "enum": ["sign"]
309
+ },
310
+ {
311
+ "type": "object",
312
+ "properties": {
313
+ "target": {
314
+ "type": "number"
315
+ }
316
+ },
317
+ "required": ["target"],
318
+ "additionalProperties": false
319
+ },
320
+ {
321
+ "type": "string",
322
+ "description": "A numeric field.",
323
+ "minLength": 1
324
+ }
325
+ ],
326
+ "description": "Tone by sign of y, by a target, or a ramp by a numeric field. Not with `series`."
327
+ },
328
+ "theme": {
329
+ "type": "object",
330
+ "additionalProperties": {
331
+ "type": "string"
332
+ },
333
+ "description": "Theme token overrides (CSS values, allowlisted).",
334
+ "propertyNames": {
335
+ "enum": [
336
+ "font",
337
+ "fontSize",
338
+ "fg",
339
+ "fgMuted",
340
+ "grid",
341
+ "bg",
342
+ "accent",
343
+ "radius",
344
+ "tooltipBg",
345
+ "tooltipFg",
346
+ "focus",
347
+ "good",
348
+ "bad",
349
+ "series1",
350
+ "series2",
351
+ "series3",
352
+ "series4",
353
+ "series5",
354
+ "series6",
355
+ "series7",
356
+ "series8"
357
+ ]
358
+ }
359
+ },
360
+ "grid": {
361
+ "type": "boolean",
362
+ "default": true,
363
+ "description": "Grid lines perpendicular to the value axis."
364
+ },
365
+ "xAxis": {
366
+ "type": "boolean",
367
+ "default": true,
368
+ "description": "Bottom axis."
369
+ },
370
+ "yAxis": {
371
+ "type": "boolean",
372
+ "default": true,
373
+ "description": "Left axis."
374
+ },
375
+ "table": {
376
+ "type": "boolean",
377
+ "default": true,
378
+ "description": "Visually hidden data table for screen readers."
379
+ }
380
+ }
381
+ }