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
package/dist/flow.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { Mark } from "./core/types.ts";
2
+ export declare const sankey: Mark;
3
+ export {};
package/dist/flow.js ADDED
@@ -0,0 +1,3 @@
1
+ /*! mayacharts v0.1.0 | MIT | https://github.com/BbekShr/mayacharts */
2
+ var e=Symbol.for(`mayacharts.marks@0`);Object.hasOwn(globalThis,e)||Object.defineProperty(globalThis,e,{value:/* @__PURE__ */ new Map});var t=globalThis[e];function n(e,n){t.has(e)||t.set(e,n),typeof globalThis.dispatchEvent==`function`&&globalThis.dispatchEvent(new Event(`maya-register`))}var r={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`};function i(e){return String(e).replace(/[&<>"']/g,e=>r[e])}function a(e){return Math.round(e*100)/100}function o(e,t,n){let r=``;for(let e in t){let n=t[e];n!=null&&n!==!1&&(r+=n===!0?` ${e}=""`:` ${e}="${i(n)}"`)}return n===void 0?`<${e}${r}/>`:`<${e}${r}>${n}</${e}>`}var s=(...e)=>e.map(e=>encodeURIComponent(String(e).replace(/\p{Cs}/gu,`�`)).replace(/~/g,`%7E`)).join(`~`),c=12,l=8,u={noun:`Sankey`,check(e,t){(!Array.isArray(e.path)||e.path.length<2)&&t(`invalid-option`,`path`,`spec.path on "sankey" needs at least 2 levels.`,`Example: path: ["source", "target"] (outer to inner).`)},draw(e){let{spec:t,plot:n}=e,r=t.path,i=r.length,u=[],d=r.map(()=>/* @__PURE__ */ new Map),f=/* @__PURE__ */ new Map,p=(e,t)=>{let n=d[e].get(t);return n||(n={lv:e,name:t,i:u.length,in:0,out:0,v:0,y:0},d[e].set(t,n),u.push(n)),n};for(let n of t.data){let a=n[t.y];if(typeof a!=`number`)continue;a>0||e.fail(`non-positive-value`,t.y,`spec.${t.y} is ${a}, but sankey sizes must be positive.`);let o=p(0,String(n[r[0]]));for(let e=1;e<i;e++){let t=p(e,String(n[r[e]])),i=o.i+`\0`+t.i,s=f.get(i);s||f.set(i,s={s:o,t,vals:[],v:0,sy:0,ty:0}),s.vals.push(a),o=t}}let m=e.agg(t.aggregate),h=[...f.values()];for(let n of h)n.v=m(n.vals)??0,n.v>0||e.fail(`non-positive-value`,t.y,`link ${n.s.name} to ${n.t.name} is ${n.v}, but sankey sizes must be positive.`),n.s.out+=n.v,n.t.in+=n.v;for(let e of u)e.v=Math.max(e.in,e.out);let g=e=>u.filter(t=>t.lv===e).sort((e,t)=>t.v-e.v),_=1/0;for(let e=0;e<i;e++){let t=g(e),r=t.reduce((e,t)=>e+t.v,0);r>0&&(_=Math.min(_,(n.h-l*(t.length-1))/r))}_>0&&_<1/0||(_=0);for(let e=0;e<i;e++){let t=n.y;for(let n of g(e))n.y=t,t+=n.v*_+l}let v=e=>n.x+e.lv*(n.w-c)/(i-1);for(let e of u){let t=e.y;for(let n of h.filter(t=>t.s===e).sort((e,t)=>e.t.y-t.t.y))n.sy=t,t+=n.v*_;t=e.y;for(let n of h.filter(t=>t.t===e).sort((e,t)=>e.s.y-t.s.y))n.ty=t,t+=n.v*_}let y=0,b=``;for(let n of h){let[r,i,l,u]=[v(n.s)+c,v(n.t),n.v*_,(v(n.s)+c+v(n.t))/2],[d,f]=[n.sy,n.ty],p=`M${a(r)} ${a(d)}C${a(u)} ${a(d)} ${a(u)} ${a(f)} ${a(i)} ${a(f)}L${a(i)} ${a(f+l)}C${a(u)} ${a(f+l)} ${a(u)} ${a(d+l)} ${a(r)} ${a(d+l)}Z`;b+=o(`path`,{"data-maya":`link`,"data-key":s(`k`,n.s.lv,n.s.name,n.t.name),"data-c":y++,"data-s":n.s.i%8,"data-x":`${n.s.name} → ${n.t.name}`,"data-series":``,"data-y":n.v,"data-f":e.fmt(t.y,n.v),d:p})}for(let n of u){let r=n.v*_;b+=o(`rect`,{"data-maya":`mark`,"data-key":s(`n`,n.lv,n.name),"data-c":y++,"data-s":n.i%8,"data-x":n.name,"data-series":``,"data-y":n.v,"data-f":e.fmt(t.y,n.v),"data-depth":n.lv,x:a(v(n)),y:a(n.y),width:c,height:a(r)});let l=n.lv===i-1;e.label(l?v(n)-4:v(n)+c+4,n.y+r/2,n.name,l?`end`:`start`)}return{marks:b,hits:``}}};n(`sankey`,u);export{u as sankey};
3
+ //# sourceMappingURL=flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flow.js","names":["KEY","MODULES","register","type","mark","ESC","esc","s","c","r","n","el","a","k","attrs","v","children","tag","key","parts","p","W","PAD","sankey","spec","fail","ctx","P","cols","nodes","byLv","links","node","lv","name","row","prev","next","l","red","ls","col","b","sum","plot","y","x","o","marks","x0","x1","th","m","d","h","last"],"sources":["../src/core/registry.ts","../src/core/svg.ts","../src/flow.ts"],"sourcesContent":["/*\n * Mark registry for optional modules (hierarchy, flow, geo). Imports nothing at runtime,\n * so every bundle that includes it (index, element, each module, the IIFE) shares one\n * table through a version-keyed global symbol. First definer wins; the property is\n * non-writable and non-configurable so a later bundle cannot swap the table.\n * Core marks are NOT here: they live in render.ts's static CORE map.\n */\nimport type { Mark } from \"./types.ts\";\n\n// ponytail: kept in sync with package.json by hand (one line, checked at release).\nexport const VERSION = \"0.1.0\";\n// ponytail: keyed by major; pre-1.0 Mark-contract breaks must bump this by hand.\nexport const MAJOR = \"0\";\n\nconst KEY = Symbol.for(\"mayacharts.marks@\" + MAJOR);\nif (!Object.hasOwn(globalThis, KEY))\n Object.defineProperty(globalThis, KEY, { value: new Map<string, Mark>() });\n\n/** type -> Mark for every registered module type (shared across bundles). */\nexport const MODULES = (globalThis as unknown as Record<symbol, Map<string, Mark>>)[KEY]!;\n\n/** Types that ship in core (static CORE map in render.ts). */\nexport const CORE_TYPES = [\n \"bar\",\n \"line\",\n \"area\",\n \"scatter\",\n \"heatmap\",\n \"waterfall\",\n \"kpi\",\n \"dumbbell\",\n] as const;\n\n/** Module types and the import that provides them (for the unknown-type hint). */\nexport const MODULE_OF: Readonly<Record<string, string>> = {\n treemap: \"hierarchy\",\n sunburst: \"hierarchy\",\n sankey: \"flow\",\n hexmap: \"geo\",\n};\n\n/** Not exported from the public entry: modules call it on import. First wins. */\nexport function register(type: string, mark: Mark): void {\n if (!MODULES.has(type)) MODULES.set(type, mark);\n // Connected <maya-chart>s re-render on this, so late module loads fix \"unknown type\".\n if (typeof globalThis.dispatchEvent === \"function\")\n globalThis.dispatchEvent(new Event(\"maya-register\"));\n}\n\n/** Registered module types. */\nexport const types = (): string[] => [...MODULES.keys()];\n","const ESC: Record<string, string> = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#39;\",\n};\n\nexport function esc(s: string | number): string {\n return String(s).replace(/[&<>\"']/g, (c) => ESC[c]!);\n}\n\nexport function r(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nexport function el(\n tag: string,\n attrs: Record<string, string | number | boolean | null | undefined>,\n children?: string,\n): string {\n let a = \"\";\n for (const k in attrs) {\n const v = attrs[k];\n if (v == null || v === false) continue;\n a += v === true ? ` ${k}=\"\"` : ` ${k}=\"${esc(v)}\"`;\n }\n return children === undefined ? `<${tag}${a}/>` : `<${tag}${a}>${children}</${tag}>`;\n}\n\n/** Sentinel category for `limit`'s rolled-up rest. Cannot collide with real data text. */\nexport const OTHER = \"\\u0000other\";\n\n/**\n * Mark identity: each part `encodeURIComponent`ed (lone surrogates replaced, `~` -> %7E),\n * joined by `~`. Grammar: band `S~C`; line/area `l~S`/`a~S`; scatter `S~name` (or index);\n * hierarchy `h~p0~p1…`; sankey node `n~depth~name`, link `k~depth~src~dst`; hexmap `g~CODE`.\n */\nexport const key = (...parts: unknown[]): string =>\n parts\n .map((p) => encodeURIComponent(String(p).replace(/\\p{Cs}/gu, \"�\")).replace(/~/g, \"%7E\"))\n .join(\"~\");\n\n/** Invisible target grown to >= 24 px around a small rect mark; \"\" when it is big enough. */\nexport function hit(d: Parameters<typeof el>[1], x: number, y: number, w: number, h: number) {\n const [gw, gh] = [Math.max(w, 24), Math.max(h, 24)];\n return w < 24 || h < 24\n ? el(\n \"rect\",\n Object.assign({ \"data-maya\": \"hit\" }, d, {\n \"data-maya\": \"hit\",\n x: r(x - (gw - w) / 2),\n y: r(y - (gh - h) / 2),\n width: r(gw),\n height: r(gh),\n fill: \"transparent\",\n }),\n )\n : \"\";\n}\n","// mayacharts/flow: sankey. Imports only registry, svg and types (never validate/render/shape).\nimport { register } from \"./core/registry.ts\";\nimport { el, key, r } from \"./core/svg.ts\";\nimport type { Mark } from \"./core/types.ts\";\n\nconst W = 12;\nconst PAD = 8;\n\ninterface N {\n lv: number;\n name: string;\n i: number;\n in: number;\n out: number;\n v: number;\n y: number;\n}\ninterface L {\n s: N;\n t: N;\n vals: number[];\n v: number;\n sy: number;\n ty: number;\n}\n\nexport const sankey: Mark = {\n noun: \"Sankey\",\n check(spec, fail) {\n if (!Array.isArray(spec.path) || spec.path.length < 2)\n fail(\n \"invalid-option\",\n \"path\",\n 'spec.path on \"sankey\" needs at least 2 levels.',\n 'Example: path: [\"source\", \"target\"] (outer to inner).',\n );\n },\n draw(ctx) {\n const { spec, plot } = ctx;\n const P = spec.path;\n const cols = P.length;\n // Maps, not objects: node names such as \"__proto__\" are plain data.\n const nodes: N[] = [];\n const byLv: Map<string, N>[] = P.map(() => new Map());\n const links = new Map<string, L>();\n const node = (lv: number, name: string): N => {\n let n = byLv[lv]!.get(name);\n if (!n) {\n n = { lv, name, i: nodes.length, in: 0, out: 0, v: 0, y: 0 };\n byLv[lv]!.set(name, n);\n nodes.push(n);\n }\n return n;\n };\n for (const row of spec.data) {\n const v = row[spec.y];\n if (typeof v !== \"number\") continue;\n if (!(v > 0))\n ctx.fail(\n \"non-positive-value\",\n spec.y,\n `spec.${spec.y} is ${v}, but sankey sizes must be positive.`,\n );\n let prev = node(0, String(row[P[0]!]));\n for (let lv = 1; lv < cols; lv++) {\n const next = node(lv, String(row[P[lv]!]));\n const k = prev.i + \"\\0\" + next.i;\n let l = links.get(k);\n if (!l) links.set(k, (l = { s: prev, t: next, vals: [], v: 0, sy: 0, ty: 0 }));\n l.vals.push(v);\n prev = next;\n }\n }\n const red = ctx.agg(spec.aggregate);\n const ls = [...links.values()];\n for (const l of ls) {\n l.v = red(l.vals) ?? 0;\n if (!(l.v > 0))\n ctx.fail(\n \"non-positive-value\",\n spec.y,\n `link ${l.s.name} to ${l.t.name} is ${l.v}, but sankey sizes must be positive.`,\n );\n l.s.out += l.v;\n l.t.in += l.v;\n }\n for (const n of nodes) n.v = Math.max(n.in, n.out);\n\n // ponytail: no crossing minimisation; columns sorted by value only.\n const col = (lv: number) => nodes.filter((n) => n.lv === lv).sort((a, b) => b.v - a.v);\n let k = Infinity;\n for (let lv = 0; lv < cols; lv++) {\n const c = col(lv);\n const sum = c.reduce((a, n) => a + n.v, 0);\n if (sum > 0) k = Math.min(k, (plot.h - PAD * (c.length - 1)) / sum);\n }\n if (!(k > 0 && k < Infinity)) k = 0;\n for (let lv = 0; lv < cols; lv++) {\n let y = plot.y;\n for (const n of col(lv)) ((n.y = y), (y += n.v * k + PAD));\n }\n const x = (n: N) => plot.x + (n.lv * (plot.w - W)) / (cols - 1);\n for (const n of nodes) {\n let o = n.y;\n for (const l of ls.filter((l) => l.s === n).sort((a, b) => a.t.y - b.t.y))\n ((l.sy = o), (o += l.v * k));\n o = n.y;\n for (const l of ls.filter((l) => l.t === n).sort((a, b) => a.s.y - b.s.y))\n ((l.ty = o), (o += l.v * k));\n }\n\n let c = 0;\n let marks = \"\";\n for (const l of ls) {\n const [x0, x1, th, m] = [x(l.s) + W, x(l.t), l.v * k, (x(l.s) + W + x(l.t)) / 2];\n const [a, b] = [l.sy, l.ty];\n const d = `M${r(x0)} ${r(a)}C${r(m)} ${r(a)} ${r(m)} ${r(b)} ${r(x1)} ${r(b)}L${r(x1)} ${r(b + th)}C${r(m)} ${r(b + th)} ${r(m)} ${r(a + th)} ${r(x0)} ${r(a + th)}Z`;\n marks += el(\"path\", {\n \"data-maya\": \"link\",\n \"data-key\": key(\"k\", l.s.lv, l.s.name, l.t.name),\n \"data-c\": c++,\n \"data-s\": l.s.i % 8,\n \"data-x\": `${l.s.name} → ${l.t.name}`,\n \"data-series\": \"\",\n \"data-y\": l.v,\n \"data-f\": ctx.fmt(spec.y, l.v),\n d,\n });\n }\n for (const n of nodes) {\n const h = n.v * k;\n marks += el(\"rect\", {\n \"data-maya\": \"mark\",\n \"data-key\": key(\"n\", n.lv, n.name),\n \"data-c\": c++,\n \"data-s\": n.i % 8,\n \"data-x\": n.name,\n \"data-series\": \"\",\n \"data-y\": n.v,\n \"data-f\": ctx.fmt(spec.y, n.v),\n \"data-depth\": n.lv,\n x: r(x(n)),\n y: r(n.y),\n width: W,\n height: r(h),\n });\n const last = n.lv === cols - 1;\n ctx.label(last ? x(n) - 4 : x(n) + W + 4, n.y + h / 2, n.name, last ? \"end\" : \"start\");\n }\n return { marks, hits: \"\" };\n },\n};\n\nregister(\"sankey\", sankey);\n\nexport {};\n"],"mappings":"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"}
package/dist/geo.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ import type { Mark } from "./core/types.ts";
2
+ export declare const hexmap: Mark;
3
+ export {};
package/dist/geo.js ADDED
@@ -0,0 +1,3 @@
1
+ /*! mayacharts v0.1.0 | MIT | https://github.com/BbekShr/mayacharts */
2
+ var e=Symbol.for(`mayacharts.marks@0`);Object.hasOwn(globalThis,e)||Object.defineProperty(globalThis,e,{value:/* @__PURE__ */ new Map});var t=globalThis[e];function n(e,n){t.has(e)||t.set(e,n),typeof globalThis.dispatchEvent==`function`&&globalThis.dispatchEvent(new Event(`maya-register`))}var r={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`};function i(e){return String(e).replace(/[&<>"']/g,e=>r[e])}function a(e){return Math.round(e*100)/100}function o(e,t,n){let r=``;for(let e in t){let n=t[e];n!=null&&n!==!1&&(r+=n===!0?` ${e}=""`:` ${e}="${i(n)}"`)}return n===void 0?`<${e}${r}/>`:`<${e}${r}>${n}</${e}>`}var s=(...e)=>e.map(e=>encodeURIComponent(String(e).replace(/\p{Cs}/gu,`�`)).replace(/~/g,`%7E`)).join(`~`),c=`AK Alaska 0 0|ME Maine 10 0|WI Wisconsin 5 1|VT Vermont 9 1|NH New Hampshire 10 1|WA Washington 0 2|ID Idaho 1 2|MT Montana 2 2|ND North Dakota 3 2|MN Minnesota 4 2|IL Illinois 5 2|MI Michigan 6 2|NY New York 8 2|MA Massachusetts 9 2|OR Oregon 0 3|NV Nevada 1 3|WY Wyoming 2 3|SD South Dakota 3 3|IA Iowa 4 3|IN Indiana 5 3|OH Ohio 6 3|PA Pennsylvania 7 3|NJ New Jersey 8 3|CT Connecticut 9 3|RI Rhode Island 10 3|CA California 0 4|UT Utah 1 4|CO Colorado 2 4|NE Nebraska 3 4|MO Missouri 4 4|KY Kentucky 5 4|WV West Virginia 6 4|VA Virginia 7 4|MD Maryland 8 4|DE Delaware 9 4|AZ Arizona 1 5|NM New Mexico 2 5|KS Kansas 3 5|AR Arkansas 4 5|TN Tennessee 5 5|NC North Carolina 6 5|SC South Carolina 7 5|DC District of Columbia 8 5|OK Oklahoma 3 6|LA Louisiana 4 6|MS Mississippi 5 6|AL Alabama 6 6|GA Georgia 7 6|HI Hawaii 0 7|TX Texas 3 7|FL Florida 7 7|PR Puerto Rico 8 8`.split(`|`).map(e=>{let t=/^(\S+) (.+) (\d+) (\d+)$/.exec(e);return{code:t[1],name:t[2],c:+t[3],r:+t[4]}}),l=/* @__PURE__ */ new Map;for(let e of c)l.set(e.code.toLowerCase(),e).set(e.name.toLowerCase(),e);var u=e=>l.get(String(e).trim().toLowerCase()),d=e=>{let t=e.trim().toLowerCase(),n=``,r=4;for(let[e,i]of l){let a=Math.abs(t.length-e.length)+[...e].filter(e=>!t.includes(e)).length+[...t].filter(t=>!e.includes(t)).length;a<r&&([r,n]=[a,e.length===2?i.code:i.name])}return n},f=Math.sqrt(3),p=Math.max(...c.map(e=>e.c))+1.5,m=Math.max(...c.map(e=>e.r))+1,h={noun:`Hex map`,check(e,t){e.data.forEach((n,r)=>{let i=n[e.x];if(i==null||u(i))return;let a=d(String(i));t(`unknown-state`,`data[${r}].${e.x}`,`"${i}" is not a US state`,a&&`Did you mean "${a}"?`,`Use a two-letter code or full name (50 states, DC, PR).`)})},draw(e){let{spec:t,shaped:n,plot:r}=e,l=Math.min(r.w/(f*p),r.h/(1.5*(m-1)+2)),d=r.x+(r.w-f*l*p)/2,h=r.y+(r.h-l*(1.5*(m-1)+2))/2,g=l*.94,_=e=>[d+f*l*(e.c+.5+e.r%2/2),h+l+1.5*l*e.r],v=e=>{let[t,n]=_(e);return`M`+[0,1,2,3,4,5].map(e=>{let r=Math.PI/3*e-Math.PI/6;return`${a(t+g*Math.cos(r))} ${a(n+g*Math.sin(r))}`}).join(`L`)+`Z`},y=/* @__PURE__ */ new Map;n.cells.forEach(e=>{let t=u(n.categories[e.ci]);t&&e.value!==null&&y.set(t,(y.get(t)??0)+e.value)});let b=[...y.values()],x=Math.min(...b),S=Math.max(...b),C=``;for(let e of c)C+=o(`path`,{d:v(e),fill:`none`});let w=``,T=0;for(let[n,r]of y){let[i,a]=_(n);w+=o(`path`,{"data-maya":`mark`,"data-key":s(`g`,n.code),"data-c":T++,"data-s":0,"data-x":n.name,"data-series":``,"data-f":e.fmt(t.y,r),"data-y":r,"data-neg":r<0,"data-tone":e.tone(r),"data-q":S>x?Math.min(9,Math.floor((r-x)/(S-x)*10)):9,d:v(n)}),e.label(i,a,n.code,`center`)}let E=S>x?`<div class="maya-legend" data-maya="ramp"><span>${i(e.fmt(t.y,x))}</span><i></i><span>${i(e.fmt(t.y,S))}</span></div>`:``;return{marks:w,hits:``,grid:C,legend:E}}};n(`hexmap`,h);export{h as hexmap};
3
+ //# sourceMappingURL=geo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geo.js","names":["KEY","MODULES","register","type","mark","ESC","esc","s","c","r","n","el","a","k","attrs","v","children","tag","key","parts","p","STATES","m","BY","find","near","best","min","ch","R3","COLS","ROWS","hexmap","spec","row","d","fail","i","ctx","plot","ox","oy","at","st","hex","cx","cy","sum","shaped","vals","lo","hi","grid","marks","legend"],"sources":["../src/core/registry.ts","../src/core/svg.ts","../src/geo.ts"],"sourcesContent":["/*\n * Mark registry for optional modules (hierarchy, flow, geo). Imports nothing at runtime,\n * so every bundle that includes it (index, element, each module, the IIFE) shares one\n * table through a version-keyed global symbol. First definer wins; the property is\n * non-writable and non-configurable so a later bundle cannot swap the table.\n * Core marks are NOT here: they live in render.ts's static CORE map.\n */\nimport type { Mark } from \"./types.ts\";\n\n// ponytail: kept in sync with package.json by hand (one line, checked at release).\nexport const VERSION = \"0.1.0\";\n// ponytail: keyed by major; pre-1.0 Mark-contract breaks must bump this by hand.\nexport const MAJOR = \"0\";\n\nconst KEY = Symbol.for(\"mayacharts.marks@\" + MAJOR);\nif (!Object.hasOwn(globalThis, KEY))\n Object.defineProperty(globalThis, KEY, { value: new Map<string, Mark>() });\n\n/** type -> Mark for every registered module type (shared across bundles). */\nexport const MODULES = (globalThis as unknown as Record<symbol, Map<string, Mark>>)[KEY]!;\n\n/** Types that ship in core (static CORE map in render.ts). */\nexport const CORE_TYPES = [\n \"bar\",\n \"line\",\n \"area\",\n \"scatter\",\n \"heatmap\",\n \"waterfall\",\n \"kpi\",\n \"dumbbell\",\n] as const;\n\n/** Module types and the import that provides them (for the unknown-type hint). */\nexport const MODULE_OF: Readonly<Record<string, string>> = {\n treemap: \"hierarchy\",\n sunburst: \"hierarchy\",\n sankey: \"flow\",\n hexmap: \"geo\",\n};\n\n/** Not exported from the public entry: modules call it on import. First wins. */\nexport function register(type: string, mark: Mark): void {\n if (!MODULES.has(type)) MODULES.set(type, mark);\n // Connected <maya-chart>s re-render on this, so late module loads fix \"unknown type\".\n if (typeof globalThis.dispatchEvent === \"function\")\n globalThis.dispatchEvent(new Event(\"maya-register\"));\n}\n\n/** Registered module types. */\nexport const types = (): string[] => [...MODULES.keys()];\n","const ESC: Record<string, string> = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#39;\",\n};\n\nexport function esc(s: string | number): string {\n return String(s).replace(/[&<>\"']/g, (c) => ESC[c]!);\n}\n\nexport function r(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nexport function el(\n tag: string,\n attrs: Record<string, string | number | boolean | null | undefined>,\n children?: string,\n): string {\n let a = \"\";\n for (const k in attrs) {\n const v = attrs[k];\n if (v == null || v === false) continue;\n a += v === true ? ` ${k}=\"\"` : ` ${k}=\"${esc(v)}\"`;\n }\n return children === undefined ? `<${tag}${a}/>` : `<${tag}${a}>${children}</${tag}>`;\n}\n\n/** Sentinel category for `limit`'s rolled-up rest. Cannot collide with real data text. */\nexport const OTHER = \"\\u0000other\";\n\n/**\n * Mark identity: each part `encodeURIComponent`ed (lone surrogates replaced, `~` -> %7E),\n * joined by `~`. Grammar: band `S~C`; line/area `l~S`/`a~S`; scatter `S~name` (or index);\n * hierarchy `h~p0~p1…`; sankey node `n~depth~name`, link `k~depth~src~dst`; hexmap `g~CODE`.\n */\nexport const key = (...parts: unknown[]): string =>\n parts\n .map((p) => encodeURIComponent(String(p).replace(/\\p{Cs}/gu, \"�\")).replace(/~/g, \"%7E\"))\n .join(\"~\");\n\n/** Invisible target grown to >= 24 px around a small rect mark; \"\" when it is big enough. */\nexport function hit(d: Parameters<typeof el>[1], x: number, y: number, w: number, h: number) {\n const [gw, gh] = [Math.max(w, 24), Math.max(h, 24)];\n return w < 24 || h < 24\n ? el(\n \"rect\",\n Object.assign({ \"data-maya\": \"hit\" }, d, {\n \"data-maya\": \"hit\",\n x: r(x - (gw - w) / 2),\n y: r(y - (gh - h) / 2),\n width: r(gw),\n height: r(gh),\n fill: \"transparent\",\n }),\n )\n : \"\";\n}\n","// US state hex cartogram. Importing this file registers the \"hexmap\" type.\nimport { register } from \"./core/registry.ts\";\nimport { el, key, r, esc } from \"./core/svg.ts\";\nimport type { Mark } from \"./core/types.ts\";\n\n// \"CODE Name col row\": odd-r offset grid (odd rows shift right half a hex), pointy-top.\nconst TABLE =\n \"AK Alaska 0 0|ME Maine 10 0|WI Wisconsin 5 1|VT Vermont 9 1|NH New Hampshire 10 1|\" +\n \"WA Washington 0 2|ID Idaho 1 2|MT Montana 2 2|ND North Dakota 3 2|MN Minnesota 4 2|IL Illinois 5 2|MI Michigan 6 2|NY New York 8 2|MA Massachusetts 9 2|\" +\n \"OR Oregon 0 3|NV Nevada 1 3|WY Wyoming 2 3|SD South Dakota 3 3|IA Iowa 4 3|IN Indiana 5 3|OH Ohio 6 3|PA Pennsylvania 7 3|NJ New Jersey 8 3|CT Connecticut 9 3|RI Rhode Island 10 3|\" +\n \"CA California 0 4|UT Utah 1 4|CO Colorado 2 4|NE Nebraska 3 4|MO Missouri 4 4|KY Kentucky 5 4|WV West Virginia 6 4|VA Virginia 7 4|MD Maryland 8 4|DE Delaware 9 4|\" +\n \"AZ Arizona 1 5|NM New Mexico 2 5|KS Kansas 3 5|AR Arkansas 4 5|TN Tennessee 5 5|NC North Carolina 6 5|SC South Carolina 7 5|DC District of Columbia 8 5|\" +\n \"OK Oklahoma 3 6|LA Louisiana 4 6|MS Mississippi 5 6|AL Alabama 6 6|GA Georgia 7 6|\" +\n \"HI Hawaii 0 7|TX Texas 3 7|FL Florida 7 7|PR Puerto Rico 8 8\";\n\nconst STATES = TABLE.split(\"|\").map((e) => {\n const m = /^(\\S+) (.+) (\\d+) (\\d+)$/.exec(e)!;\n return { code: m[1]!, name: m[2]!, c: +m[3]!, r: +m[4]! };\n});\nconst BY = new Map<string, (typeof STATES)[number]>();\nfor (const s of STATES) BY.set(s.code.toLowerCase(), s).set(s.name.toLowerCase(), s);\n\nconst find = (v: unknown) => BY.get(String(v).trim().toLowerCase());\n\n/** Closest code or name (a few edits away), else \"\". */\nconst near = (v: string): string => {\n const a = v.trim().toLowerCase();\n let best = \"\";\n let min = 4;\n for (const [k, s] of BY) {\n const n =\n Math.abs(a.length - k.length) +\n [...k].filter((ch) => !a.includes(ch)).length +\n [...a].filter((ch) => !k.includes(ch)).length;\n if (n < min) [min, best] = [n, k.length === 2 ? s.code : s.name];\n }\n return best;\n};\n\nconst R3 = Math.sqrt(3);\nconst COLS = Math.max(...STATES.map((s) => s.c)) + 1.5;\nconst ROWS = Math.max(...STATES.map((s) => s.r)) + 1;\n\nexport const hexmap: Mark = {\n noun: \"Hex map\",\n check(spec, fail) {\n spec.data.forEach((row, i) => {\n const v = (row as Record<string, unknown>)[spec.x as string];\n if (v == null || find(v)) return;\n const d = near(String(v));\n fail(\n \"unknown-state\",\n `data[${i}].${spec.x}`,\n `\"${v}\" is not a US state`,\n d && `Did you mean \"${d}\"?`,\n \"Use a two-letter code or full name (50 states, DC, PR).\",\n );\n });\n },\n draw(ctx) {\n const { spec, shaped, plot } = ctx;\n const s = Math.min(plot.w / (R3 * COLS), plot.h / (1.5 * (ROWS - 1) + 2));\n const ox = plot.x + (plot.w - R3 * s * COLS) / 2;\n const oy = plot.y + (plot.h - s * (1.5 * (ROWS - 1) + 2)) / 2;\n const k = s * 0.94;\n const at = (st: (typeof STATES)[number]) => [\n ox + R3 * s * (st.c + 0.5 + (st.r % 2) / 2),\n oy + s + 1.5 * s * st.r,\n ];\n const hex = (st: (typeof STATES)[number]) => {\n const [cx, cy] = at(st) as [number, number];\n return (\n \"M\" +\n [0, 1, 2, 3, 4, 5]\n .map((i) => {\n const a = (Math.PI / 3) * i - Math.PI / 6;\n return `${r(cx + k * Math.cos(a))} ${r(cy + k * Math.sin(a))}`;\n })\n .join(\"L\") +\n \"Z\"\n );\n };\n\n const sum = new Map<(typeof STATES)[number], number>();\n shaped.cells.forEach((c) => {\n const st = find(shaped.categories[c.ci]);\n if (st && c.value !== null) sum.set(st, (sum.get(st) ?? 0) + c.value);\n });\n const vals = [...sum.values()];\n const lo = Math.min(...vals);\n const hi = Math.max(...vals);\n\n let grid = \"\";\n for (const st of STATES) grid += el(\"path\", { d: hex(st), fill: \"none\" });\n let marks = \"\";\n let n = 0;\n for (const [st, v] of sum) {\n const [cx, cy] = at(st) as [number, number];\n marks += el(\"path\", {\n \"data-maya\": \"mark\",\n \"data-key\": key(\"g\", st.code),\n \"data-c\": n++,\n \"data-s\": 0,\n \"data-x\": st.name,\n \"data-series\": \"\",\n \"data-f\": ctx.fmt(spec.y, v),\n \"data-y\": v,\n \"data-neg\": v < 0,\n \"data-tone\": ctx.tone(v),\n \"data-q\": hi > lo ? Math.min(9, Math.floor(((v - lo) / (hi - lo)) * 10)) : 9,\n d: hex(st),\n });\n ctx.label(cx, cy, st.code, \"center\");\n }\n const legend =\n hi > lo\n ? `<div class=\"maya-legend\" data-maya=\"ramp\"><span>${esc(ctx.fmt(spec.y, lo))}</span><i></i><span>${esc(ctx.fmt(spec.y, hi))}</span></div>`\n : \"\";\n return { marks, hits: \"\", grid, legend };\n },\n};\n\nregister(\"hexmap\", hexmap);\n\nexport {};\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import "./hierarchy.ts";
2
+ import "./flow.ts";
3
+ import "./geo.ts";
4
+ export {};
@@ -0,0 +1,15 @@
1
+ import type { MarkCtx, Row } from "./core/types.ts";
2
+ interface Node {
3
+ name: string;
4
+ value: number;
5
+ children: Node[];
6
+ depth: number;
7
+ /** Names from the first path level down to this node. */
8
+ parts: string[];
9
+ /** colorBy field value (leaves only). */
10
+ cv: number | null;
11
+ }
12
+ type Reduce = ReturnType<MarkCtx["agg"]>;
13
+ /** Rows -> nested tree in first-appearance order. Map-keyed, so any name is safe. */
14
+ export declare function tree(rows: readonly Row[], path: readonly string[], y: string, agg: Reduce, cb?: string | null): Node;
15
+ export {};
@@ -0,0 +1,3 @@
1
+ /*! mayacharts v0.1.0 | MIT | https://github.com/BbekShr/mayacharts */
2
+ var e=Symbol.for(`mayacharts.marks@0`);Object.hasOwn(globalThis,e)||Object.defineProperty(globalThis,e,{value:/* @__PURE__ */ new Map});var t=globalThis[e];function n(e,n){t.has(e)||t.set(e,n),typeof globalThis.dispatchEvent==`function`&&globalThis.dispatchEvent(new Event(`maya-register`))}var r={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`};function i(e){return String(e).replace(/[&<>"']/g,e=>r[e])}function a(e){return Math.round(e*100)/100}function o(e,t,n){let r=``;for(let e in t){let n=t[e];n!=null&&n!==!1&&(r+=n===!0?` ${e}=""`:` ${e}="${i(n)}"`)}return n===void 0?`<${e}${r}/>`:`<${e}${r}>${n}</${e}>`}var s=(...e)=>e.map(e=>encodeURIComponent(String(e).replace(/\p{Cs}/gu,`�`)).replace(/~/g,`%7E`)).join(`~`);function c(e,t,n,r,i){let[s,c]=[Math.max(r,24),Math.max(i,24)];return r<24||i<24?o(`rect`,Object.assign({"data-maya":`hit`},e,{"data-maya":`hit`,x:a(t-(s-r)/2),y:a(n-(c-i)/2),width:a(s),height:a(c),fill:`transparent`})):``}function l(e,t,n,r,i=null){let a=()=>({kids:/* @__PURE__ */ new Map,ys:[],cs:[]}),o=a();for(let r of e){let e=r[n];if(typeof e!=`number`)continue;let s=o;for(let e of t){let t=String(r[e]);s=s.kids.get(t)??s.kids.set(t,a()).get(t)}s.ys.push(e);let c=i===null?null:r[i];typeof c==`number`&&s.cs.push(c)}let s=(e,t,n,i)=>{let a=[...e.kids].map(([e,t])=>s(t,e,n+1,[...i,e]));return{name:t,children:a,depth:n,parts:i,cv:e.cs.length?r(e.cs):null,value:a.length?a.reduce((e,t)=>e+t.value,0):r(e.ys)??0}};return s(o,``,0,[])}function u(e,t,n,r,i){let a=[],o=e.filter(e=>e.value>0).sort((e,t)=>t.value-e.value),s=o.reduce((e,t)=>e+t.value,0),c=0;for(;c<o.length;){let e=Math.min(r,i),l=r*i/s,u=(t,n,r)=>Math.max(e*e*r/(t*t),t*t/(e*e*n)),d=c,f=0,p=1/0;for(;d<o.length;d++){let e=o[d].value*l,t=f+e,n=u(t,e,o[c].value*l);if(d>c&&n>p)break;p=n,f=t}let m=o.slice(c,d),h=e?f/e:0,g=0;for(let o of m){let s=f?o.value*l*e/f:0;a.push(r>=i?[o,t,n+g,h,s]:[o,t+g,n,s,h]),g+=s}r>=i?(t+=h,r-=h):(n+=h,i-=h),s-=m.reduce((e,t)=>e+t.value,0),c=d}return a}function d(e){let{spec:t}=e;t.data.forEach((n,r)=>{let i=n[t.y];typeof i==`number`&&!(i>0)&&e.fail(`non-positive-value`,`data[${r}].${t.y}`,`Value ${i} is not positive.`,`Treemaps and sunbursts size shapes by value, so every value must be above zero.`,`To show negative values use a bar chart with colorBy: "sign".`)});let n=typeof t.colorBy==`string`&&t.colorBy!==`sign`?t.colorBy:null,r=l(t.data,t.path,t.y,e.agg(t.aggregate),n),i=0,a=r.children;return{root:r,tops:a,attrs:n=>{let r=[...t.drilled,...n.parts],o=a.findIndex(e=>e.name===n.parts[0]);return{"data-maya":`mark`,"data-key":s(`h`,...r),"data-c":i++,"data-s":o%8,"data-x":r.join(` › `),"data-series":``,"data-y":n.value,"data-f":e.fmt(t.y,n.value),"data-tone":e.tone(n.value),"data-q":n.cv===null?null:e.q(n.cv),"data-depth":n.depth}}}}var f=e=>e.length*7.2+4,p={noun:`Treemap`,draw(e){let{plot:t,spec:n}=e,{root:r,attrs:i}=d(e),s=``,l=``,p=(t,r,d,m,h)=>{let g=t.depth>1?.5:0,[_,v,y,b]=[r+g,d+g,Math.max(0,m-2*g),Math.max(0,h-2*g)];if(!t.children.length){let r=i(t);s+=o(`rect`,{...r,x:a(_),y:a(v),width:a(y),height:a(b)}),l+=c(r,_,v,y,b);let[u,d,p,m]=[_+y/2,v+b/2,r[`data-f`],`${t.name} · ${r[`data-f`]}`];if(!n.labels||b<16)return;b>=34&&f(t.name)<=y&&f(p)<=y?e.label(u,d-8,t.name,`center`)&&e.label(u,d+8,p,`center`):f(m)<=y?e.label(u,d,m,`center`):f(p)<=y&&e.label(u,d,p,`center`);return}t.depth===1&&f(t.name)<=y&&b>=30&&e.label(_+y/2,v+9,t.name,`center`);for(let[e,n,r,i,a]of u(t.children,_,v,y,b))p(e,n,r,i,a)};return p(r,t.x,t.y,t.w,t.h),{marks:s,hits:l}}},m=Math.PI*2;n(`treemap`,p),n(`sunburst`,{noun:`Sunburst`,draw(e){let{plot:t,spec:n}=e,{root:r,attrs:i}=d(e),s=n.path.length,c=Math.min(t.w,t.h)/2,[l,u]=[t.x+t.w/2,t.y+t.h/2],f=(e,t)=>`${a(l+e*Math.cos(t-Math.PI/2))} ${a(u+e*Math.sin(t-Math.PI/2))}`,p=``,h=(e,t,n)=>{if(e.depth){let[r,l]=[e.depth*c/(s+1),(e.depth+1)*c/(s+1)],u=Math.min(n,t+m*359.99/360),d=+(u-t>Math.PI),h=`M${f(l,t)}A${a(l)} ${a(l)} 0 ${d} 1 ${f(l,u)}L${f(r,u)}A${a(r)} ${a(r)} 0 ${d} 0 ${f(r,t)}Z`;p+=o(`path`,{...i(e),d:h})}let r=t;for(let i of e.children){let a=(n-t)*i.value/e.value;h(i,r,r+a),r+=a}};return h(r,0,m),{marks:p,hits:``}}});export{l as tree};
3
+ //# sourceMappingURL=hierarchy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hierarchy.js","names":["KEY","MODULES","register","type","mark","ESC","esc","s","c","r","n","el","a","k","attrs","v","children","tag","key","parts","p","hit","gw","gh","w","h","d","x","y","tree","mk","top","row","rows","f","path","cb","build","raw","depth","agg","squarify","out","items","nodes","b","rest","i","side","scale","worst","mx","mn","j","sum","best","wst","thick","len","setup","ctx","spec","root","tops","t","text","treemap","marks","hits","walk","bx","by","bw","bh","lx","ly","one","cx","cy","cw","ch","plot","TAU","D","R","pt","rad","r0","r1","e","a1","a0","big","span"],"sources":["../src/core/registry.ts","../src/core/svg.ts","../src/hierarchy.ts"],"sourcesContent":["/*\n * Mark registry for optional modules (hierarchy, flow, geo). Imports nothing at runtime,\n * so every bundle that includes it (index, element, each module, the IIFE) shares one\n * table through a version-keyed global symbol. First definer wins; the property is\n * non-writable and non-configurable so a later bundle cannot swap the table.\n * Core marks are NOT here: they live in render.ts's static CORE map.\n */\nimport type { Mark } from \"./types.ts\";\n\n// ponytail: kept in sync with package.json by hand (one line, checked at release).\nexport const VERSION = \"0.1.0\";\n// ponytail: keyed by major; pre-1.0 Mark-contract breaks must bump this by hand.\nexport const MAJOR = \"0\";\n\nconst KEY = Symbol.for(\"mayacharts.marks@\" + MAJOR);\nif (!Object.hasOwn(globalThis, KEY))\n Object.defineProperty(globalThis, KEY, { value: new Map<string, Mark>() });\n\n/** type -> Mark for every registered module type (shared across bundles). */\nexport const MODULES = (globalThis as unknown as Record<symbol, Map<string, Mark>>)[KEY]!;\n\n/** Types that ship in core (static CORE map in render.ts). */\nexport const CORE_TYPES = [\n \"bar\",\n \"line\",\n \"area\",\n \"scatter\",\n \"heatmap\",\n \"waterfall\",\n \"kpi\",\n \"dumbbell\",\n] as const;\n\n/** Module types and the import that provides them (for the unknown-type hint). */\nexport const MODULE_OF: Readonly<Record<string, string>> = {\n treemap: \"hierarchy\",\n sunburst: \"hierarchy\",\n sankey: \"flow\",\n hexmap: \"geo\",\n};\n\n/** Not exported from the public entry: modules call it on import. First wins. */\nexport function register(type: string, mark: Mark): void {\n if (!MODULES.has(type)) MODULES.set(type, mark);\n // Connected <maya-chart>s re-render on this, so late module loads fix \"unknown type\".\n if (typeof globalThis.dispatchEvent === \"function\")\n globalThis.dispatchEvent(new Event(\"maya-register\"));\n}\n\n/** Registered module types. */\nexport const types = (): string[] => [...MODULES.keys()];\n","const ESC: Record<string, string> = {\n \"&\": \"&amp;\",\n \"<\": \"&lt;\",\n \">\": \"&gt;\",\n '\"': \"&quot;\",\n \"'\": \"&#39;\",\n};\n\nexport function esc(s: string | number): string {\n return String(s).replace(/[&<>\"']/g, (c) => ESC[c]!);\n}\n\nexport function r(n: number): number {\n return Math.round(n * 100) / 100;\n}\n\nexport function el(\n tag: string,\n attrs: Record<string, string | number | boolean | null | undefined>,\n children?: string,\n): string {\n let a = \"\";\n for (const k in attrs) {\n const v = attrs[k];\n if (v == null || v === false) continue;\n a += v === true ? ` ${k}=\"\"` : ` ${k}=\"${esc(v)}\"`;\n }\n return children === undefined ? `<${tag}${a}/>` : `<${tag}${a}>${children}</${tag}>`;\n}\n\n/** Sentinel category for `limit`'s rolled-up rest. Cannot collide with real data text. */\nexport const OTHER = \"\\u0000other\";\n\n/**\n * Mark identity: each part `encodeURIComponent`ed (lone surrogates replaced, `~` -> %7E),\n * joined by `~`. Grammar: band `S~C`; line/area `l~S`/`a~S`; scatter `S~name` (or index);\n * hierarchy `h~p0~p1…`; sankey node `n~depth~name`, link `k~depth~src~dst`; hexmap `g~CODE`.\n */\nexport const key = (...parts: unknown[]): string =>\n parts\n .map((p) => encodeURIComponent(String(p).replace(/\\p{Cs}/gu, \"�\")).replace(/~/g, \"%7E\"))\n .join(\"~\");\n\n/** Invisible target grown to >= 24 px around a small rect mark; \"\" when it is big enough. */\nexport function hit(d: Parameters<typeof el>[1], x: number, y: number, w: number, h: number) {\n const [gw, gh] = [Math.max(w, 24), Math.max(h, 24)];\n return w < 24 || h < 24\n ? el(\n \"rect\",\n Object.assign({ \"data-maya\": \"hit\" }, d, {\n \"data-maya\": \"hit\",\n x: r(x - (gw - w) / 2),\n y: r(y - (gh - h) / 2),\n width: r(gw),\n height: r(gh),\n fill: \"transparent\",\n }),\n )\n : \"\";\n}\n","// treemap + sunburst. Importing this file registers both types.\nimport { register } from \"./core/registry.ts\";\nimport { el, hit, key, r } from \"./core/svg.ts\";\nimport type { Aggregate, Mark, MarkCtx, MarkOut, Row } from \"./core/types.ts\";\n\ninterface Node {\n name: string;\n value: number;\n children: Node[];\n depth: number;\n /** Names from the first path level down to this node. */\n parts: string[];\n /** colorBy field value (leaves only). */\n cv: number | null;\n}\n\ntype Reduce = ReturnType<MarkCtx[\"agg\"]>;\n\n/** Rows -> nested tree in first-appearance order. Map-keyed, so any name is safe. */\nexport function tree(\n rows: readonly Row[],\n path: readonly string[],\n y: string,\n agg: Reduce,\n cb: string | null = null,\n): Node {\n type Raw = { kids: Map<string, Raw>; ys: number[]; cs: number[] };\n const mk = (): Raw => ({ kids: new Map(), ys: [], cs: [] });\n const top = mk();\n for (const row of rows) {\n const v = row[y];\n if (typeof v !== \"number\") continue;\n let n = top;\n for (const f of path) {\n const k = String(row[f]);\n n = n.kids.get(k) ?? n.kids.set(k, mk()).get(k)!;\n }\n n.ys.push(v);\n const c = cb === null ? null : row[cb];\n if (typeof c === \"number\") n.cs.push(c);\n }\n const build = (raw: Raw, name: string, depth: number, parts: string[]): Node => {\n const children = [...raw.kids].map(([k, c]) => build(c, k, depth + 1, [...parts, k]));\n return {\n name,\n children,\n depth,\n parts,\n cv: raw.cs.length ? agg(raw.cs) : null,\n value: children.length ? children.reduce((s, c) => s + c.value, 0) : (agg(raw.ys) ?? 0),\n };\n };\n return build(top, \"\", 0, []);\n}\n\n/** Bruls squarify: [node, x, y, w, h] for `nodes` filling the box. */\nfunction squarify(nodes: Node[], x: number, y: number, w: number, h: number) {\n const out: [Node, number, number, number, number][] = [];\n const items = nodes.filter((n) => n.value > 0).sort((a, b) => b.value - a.value);\n let rest = items.reduce((s, n) => s + n.value, 0);\n let i = 0;\n while (i < items.length) {\n const side = Math.min(w, h);\n const scale = (w * h) / rest;\n const worst = (a: number, mn: number, mx: number) =>\n Math.max((side * side * mx) / (a * a), (a * a) / (side * side * mn));\n let j = i;\n let sum = 0;\n let best = Infinity;\n for (; j < items.length; j++) {\n const v = items[j]!.value * scale;\n const s = sum + v;\n const wst = worst(s, v, items[i]!.value * scale);\n if (j > i && wst > best) break;\n best = wst;\n sum = s;\n }\n const row = items.slice(i, j);\n const thick = side ? sum / side : 0;\n let p = 0;\n for (const n of row) {\n const len = sum ? (n.value * scale * side) / sum : 0;\n out.push(w >= h ? [n, x, y + p, thick, len] : [n, x + p, y, len, thick]);\n p += len;\n }\n if (w >= h) ((x += thick), (w -= thick));\n else ((y += thick), (h -= thick));\n rest -= row.reduce((s, n) => s + n.value, 0);\n i = j;\n }\n return out;\n}\n\n/** Validate values, build the tree, and compute attributes shared by both marks. */\nfunction setup(ctx: MarkCtx) {\n const { spec } = ctx;\n spec.data.forEach((row, i) => {\n const v = row[spec.y];\n if (typeof v === \"number\" && !(v > 0))\n ctx.fail(\n \"non-positive-value\",\n `data[${i}].${spec.y}`,\n `Value ${v} is not positive.`,\n \"Treemaps and sunbursts size shapes by value, so every value must be above zero.\",\n 'To show negative values use a bar chart with colorBy: \"sign\".',\n );\n });\n const cb = typeof spec.colorBy === \"string\" && spec.colorBy !== \"sign\" ? spec.colorBy : null;\n const root = tree(spec.data, spec.path, spec.y, ctx.agg(spec.aggregate as Aggregate), cb);\n let c = 0;\n const tops = root.children;\n const attrs = (n: Node) => {\n const parts = [...spec.drilled, ...n.parts];\n const s = tops.findIndex((t) => t.name === n.parts[0]);\n return {\n \"data-maya\": \"mark\",\n \"data-key\": key(\"h\", ...parts),\n \"data-c\": c++,\n \"data-s\": s % 8,\n \"data-x\": parts.join(\" › \"),\n \"data-series\": \"\",\n \"data-y\": n.value,\n \"data-f\": ctx.fmt(spec.y, n.value),\n \"data-tone\": ctx.tone(n.value),\n \"data-q\": n.cv === null ? null : ctx.q(n.cv),\n \"data-depth\": n.depth,\n };\n };\n return { root, tops, attrs };\n}\n\nconst text = (s: string) => s.length * 7.2 + 4;\n\nconst treemap: Mark = {\n noun: \"Treemap\",\n draw(ctx): MarkOut {\n const { plot, spec } = ctx;\n const { root, attrs } = setup(ctx);\n let marks = \"\";\n let hits = \"\";\n const walk = (n: Node, x: number, y: number, w: number, h: number): void => {\n // 0.5 px inset below the top level: siblings sit 1 px apart (stroke adds more).\n const g = n.depth > 1 ? 0.5 : 0;\n const [bx, by, bw, bh] = [x + g, y + g, Math.max(0, w - 2 * g), Math.max(0, h - 2 * g)];\n if (!n.children.length) {\n const a = attrs(n);\n marks += el(\"rect\", { ...a, x: r(bx), y: r(by), width: r(bw), height: r(bh) });\n hits += hit(a, bx, by, bw, bh);\n // Name over value when both fit, else \"name · value\" on one line, else the value.\n const [lx, ly, f, one] = [\n bx + bw / 2,\n by + bh / 2,\n a[\"data-f\"],\n `${n.name} · ${a[\"data-f\"]}`,\n ];\n if (!spec.labels || bh < 16) return;\n if (bh >= 34 && text(n.name) <= bw && text(f) <= bw)\n ctx.label(lx, ly - 8, n.name, \"center\") && ctx.label(lx, ly + 8, f, \"center\");\n else if (text(one) <= bw) ctx.label(lx, ly, one, \"center\");\n else if (text(f) <= bw) ctx.label(lx, ly, f, \"center\");\n return;\n }\n if (n.depth === 1 && text(n.name) <= bw && bh >= 30)\n ctx.label(bx + bw / 2, by + 9, n.name, \"center\");\n for (const [c, cx, cy, cw, ch] of squarify(n.children, bx, by, bw, bh))\n walk(c, cx, cy, cw, ch);\n };\n walk(root, plot.x, plot.y, plot.w, plot.h);\n return { marks, hits };\n },\n};\n\nconst TAU = Math.PI * 2;\n\nconst sunburst: Mark = {\n noun: \"Sunburst\",\n draw(ctx): MarkOut {\n const { plot, spec } = ctx;\n const { root, attrs } = setup(ctx);\n const D = spec.path.length;\n const R = Math.min(plot.w, plot.h) / 2;\n const [cx, cy] = [plot.x + plot.w / 2, plot.y + plot.h / 2];\n const pt = (rad: number, a: number) =>\n `${r(cx + rad * Math.cos(a - Math.PI / 2))} ${r(cy + rad * Math.sin(a - Math.PI / 2))}`;\n let marks = \"\";\n const walk = (n: Node, a0: number, a1: number): void => {\n if (n.depth) {\n const [r0, r1] = [(n.depth * R) / (D + 1), ((n.depth + 1) * R) / (D + 1)];\n const e = Math.min(a1, a0 + (TAU * 359.99) / 360);\n const big = e - a0 > Math.PI ? 1 : 0;\n const d =\n `M${pt(r1, a0)}A${r(r1)} ${r(r1)} 0 ${big} 1 ${pt(r1, e)}` +\n `L${pt(r0, e)}A${r(r0)} ${r(r0)} 0 ${big} 0 ${pt(r0, a0)}Z`;\n marks += el(\"path\", { ...attrs(n), d });\n }\n let a = a0;\n for (const c of n.children) {\n const span = ((a1 - a0) * c.value) / n.value;\n walk(c, a, a + span);\n a += span;\n }\n };\n walk(root, 0, TAU);\n return { marks, hits: \"\" };\n },\n};\n\nregister(\"treemap\", treemap);\nregister(\"sunburst\", sunburst);\n\nexport {};\n"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { render, renderShell, renderParts } from "./core/render.ts";
2
+ export { validateSpec, MayaSpecError } from "./core/validate.ts";
3
+ export { VERSION as version } from "./core/registry.ts";
4
+ export type { ErrorCode } from "./core/validate.ts";
5
+ export type { Aggregate, ChartSpec, ChartType, DatePreset, Field, FieldFormat, FormatPreset, MayaErrorDetail, MayaSelectDetail, MayaViewDetail, NumberPreset, RenderOptions, Row, Sel, TextKey, ThemeToken, View, } from "./core/types.ts";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ /*! mayacharts v0.1.0 | MIT | https://github.com/BbekShr/mayacharts */
2
+ var e={noData:`No data`,other:`Other`,back:`Back`,reset:`Reset zoom`,showing:`Showing {0}`,drilledInto:`Drilled into {0}`,zoomedTo:`Zoomed to {0} – {1}`,selected:`{0} selected`,selectionCleared:`Selection cleared`,chartOf:`{0} chart of {1} by {2}`,firstOf:`First {0} of {1} rows`,measures:`Measure`,crumbs:`Drill path`,positive:`positive`,negative:`negative`,above:`above target`,below:`below target`,vs:`{0} vs {1}`,ofTarget:`{0} of target {1}`};function t(t,n,...r){return((t.text&&Object.hasOwn(t.text,n)?t.text[n]:void 0)??e[n]).replace(/\{(\d)\}/g,(e,t)=>String(r[+t]??``))}var n={"&":`&amp;`,"<":`&lt;`,">":`&gt;`,'"':`&quot;`,"'":`&#39;`};function r(e){return String(e).replace(/[&<>"']/g,e=>n[e])}function i(e){return Math.round(e*100)/100}function a(e,t,n){let i=``;for(let e in t){let n=t[e];n!=null&&n!==!1&&(i+=n===!0?` ${e}=""`:` ${e}="${r(n)}"`)}return n===void 0?`<${e}${i}/>`:`<${e}${i}>${n}</${e}>`}var o=`\0other`,s=(...e)=>e.map(e=>encodeURIComponent(String(e).replace(/\p{Cs}/gu,`�`)).replace(/~/g,`%7E`)).join(`~`);function c(e,t,n,r,o){let[s,c]=[Math.max(r,24),Math.max(o,24)];return r<24||o<24?a(`rect`,Object.assign({"data-maya":`hit`},e,{"data-maya":`hit`,x:i(t-(s-r)/2),y:i(n-(c-o)/2),width:i(s),height:i(c),fill:`transparent`})):``}var l=e=>e.title??`${e.titles.get(e.y)??e.y} by ${e.titles.get(e.x)??(e.x||e.path.join(` / `))}`,u=[`scatter`,`treemap`,`sunburst`,`sankey`,`hexmap`],d=1e3;function f(e,n,r,i){if(e.description!==null)return e.description;let a=t=>e.titles.get(t)??t,o=t(e,`chartOf`,i,a(e.y),e.x?a(e.x):e.path.join(` / `));if(e.series!==null&&n.series.length&&(o+=`, ${e.stack?`stacked`:`grouped`} by ${a(e.series)} (${n.series.join(`, `)})`),u.includes(e.type))return`${o}. ${e.data.length} rows.`;let s=0,c=1/0,l=-1/0;for(let e of n.cells)e.value!==null&&(s++,c=Math.min(c,e.value),l=Math.max(l,e.value));let d=t=>r(e.y,t);return s?s===1?`${o}. 1 value: ${d(c)}.`:`${o}. ${s} values from ${d(c)} to ${d(l)}.`:o+`. No data.`}function p(e,n,i,a){let o=t=>e.titles.get(t)??t,s=(t,n)=>{if(n==null)return``;let o=t===e.y&&typeof n==`number`?a(n):null;return r(i(t,n))+(o?` (${r(o)})`:``)},c=n=>n>d?t(e,`firstOf`,d,n):l(e),f,p,m;if(u.includes(e.type)){let t=[...new Set([e.x,...e.path,e.series,e.name,e.size,e.y,typeof e.colorBy==`string`&&e.colorBy!==`sign`?e.colorBy:null].filter(e=>!!e))];m=e.data.length,f=t.map(e=>`<th>${r(o(e))}</th>`).join(``),p=e.data.slice(0,d).map(e=>`<tr>${t.map(t=>`<td>${s(t,e[t])}</td>`).join(``)}</tr>`).join(``)}else{let t=e.series===null?[o(e.y)]:n.visible.map(e=>n.series[e]);m=n.categories.length,f=`<th>${r(o(e.x))}</th>`+t.map(e=>`<th>${r(e)}</th>`).join(``);let i=new Map(n.cells.map(e=>[e.ci+`,`+e.si,e.value]));p=``;for(let t=0;t<Math.min(m,d);t++){p+=`<tr><th scope="row">${r(n.categories[t])}</th>`;for(let r of n.visible)p+=`<td>${s(e.y,i.get(t+`,`+r))}</td>`;p+=`</tr>`}}return`<table class="maya-sr"><caption>${r(c(m))}</caption><thead><tr>${f}</tr></thead><tbody>${p}</tbody></table>`}var m=e=>{for(let t=0;t<8;t++)if(Math.abs(e*10**t-Math.round(e*10**t))<1e-9)return t;return 8},h=`year month day hour minute second weekday era timeZone dateStyle timeStyle fractionalSecondDigits hour12 dayPeriod timeZoneName`.split(` `),g={date:{dateStyle:`medium`},month:{month:`short`,year:`numeric`},year:{year:`numeric`},time:{timeStyle:`short`},datetime:{dateStyle:`medium`,timeStyle:`short`}};function _(e,t=e.y,n){typeof t==`number`&&([t,n]=[e.y,t]);let r=e.format.get(t),i=Intl.NumberFormat.supportedLocalesOf(e.locale).length?e.locale:`en-US`,a=n===void 0?2:m(n),o=``,s=``,c=null,l=null,u=typeof r==`string`?r:`auto`;if(typeof r==`string`&&Object.hasOwn(g,r))c=new Intl.DateTimeFormat(i,{timeZone:`UTC`,...g[r]});else if(typeof r==`object`&&r){let{prefix:e=``,suffix:t=``,...n}=r;[o,s]=[String(e),String(t)],h.some(e=>Object.hasOwn(n,e))?c=new Intl.DateTimeFormat(i,{timeZone:`UTC`,...n}):l=new Intl.NumberFormat(i,n)}if(!c&&!l){let t=u===`integer`?{maximumFractionDigits:0}:u===`decimal`?{minimumFractionDigits:2,maximumFractionDigits:2}:u===`compact`?{notation:`compact`,maximumFractionDigits:1}:u===`percent`?{style:`percent`,minimumFractionDigits:Math.max(0,a-2),maximumFractionDigits:Math.max(1,a-2)}:u===`currency`?{style:`currency`,currency:e.currency,minimumFractionDigits:n!==void 0&&n>=1?0:a,maximumFractionDigits:n!==void 0&&n>=1?0:Math.max(a,2)}:{maximumFractionDigits:Math.max(a,2)};l=new Intl.NumberFormat(i,t)}return e=>{if(e==null)return``;let t;if(c){let n=typeof e==`string`&&/^-?\d+$/.test(e)?/* @__PURE__ */ new Date(+e):typeof e==`number`||typeof e==`string`||e instanceof Date?new Date(e):NaN;t=Number.isNaN(+n)?String(e):c.format(n)}else t=typeof e==`number`?l.format(e):String(e);return o+t+s}}function v(e,t,n=.2,r=.1){let i=e.length,a=t[1]-t[0],o=a/(i-n+r*2)||1,s=t[0]+(a-o*(i-n))/2;return{domain:e,step:o,bandwidth:o*(1-n),at:e=>s+o*e}}function y(e,t){let[n,r]=e,[i,a]=t,o=r===n?0:(a-i)/(r-n);return{domain:e,range:t,of:e=>r===n?(i+a)/2:i+(e-n)*o}}var b=e=>parseFloat(e.toPrecision(12));function x(e,t,n=5){t===e&&([e,t]=e===0?[0,1]:[e-1,t+1]);let r=10**Math.floor(Math.log10((t-e)/n)),i=r,a=1/0,o=e<0&&t>0;for(let s of[1,2,2.5,5,10]){let c=r*s,l=Math.floor(e/c+1e-9),u=Math.ceil(t/c-1e-9)-l+1,d=o?u>n+3?1/0:(u-1+Math.abs(u-n)/1e3)*c:Math.abs(u-n);d<a-1e-9*Math.abs(d)&&(a=d,i=c)}let s=Math.floor(e/i+1e-9),c=Math.ceil(t/i-1e-9),l=[];for(let e=s;e<=c;e++)l.push(b(e*i));return{domain:[b(s*i),b(c*i)],values:l,step:b(i)}}var S=e=>e>=4352&&e<=4447||e>=11904&&e<=42191||e>=44032&&e<=55203||e>=63744&&e<=64255||e>=65072&&e<=65103||e>=65280&&e<=65376||e>=65504&&e<=65510,C=e=>{let t=0,n=0;for(let r of e)S(r.codePointAt(0))?n++:t++;return t*7.2+n*12},w=e=>C(e)+8,T=e=>e.reduce((e,t)=>Math.max(e,w(t)),0);function E(e,t){if(C(e)<=t)return e;let n=``,r=0;for(let i of e){if(r+=C(i),r+7.2>t)break;n+=i}return n+`…`}function D(e,t,n){let r=(t.field===e.y?e.yDomain:e.xDomain)??null,[i,a]=r??t.domain,o=x(i,a),s=r?o.values.filter(e=>e>=i&&e<=a):o.values;return{domain:r??o.domain,values:s,labels:s.map(e=>n(t.field,e,o.step))}}function O(e,[t,n,o],s,c){let{width:l,height:u}=s,d=t&&t.kind===`linear`?D(e,t,c):null,f=n&&n.kind===`linear`?D(e,n,c):null,p=t&&!d?t.domain.map(e=>c(t.field,e)):[],m=n&&!f?n.domain.map(e=>c(n.field,e)):[],h=f?f.labels:m.map(e=>E(e,l*.4-8)),g=o&&o.kind===`linear`?D(e,o,c):null,_=g&&o&&e.titles.get(o.field),b=n&&e.titles.get(n.field),x=t&&e.titles.get(t.field),S=(e.yAxis&&n?T(h)+10:8)+(b?18:0),w=(e.xAxis&&t?24:8)+(x?18:0),O={x:S,y:10,w:Math.max(1,l-S-(g?(e.yAxis?T(g.labels)+4:8)+(_?18:0):Math.max(12,d?C(d.labels.at(-1)??``)/2+2:0))),h:Math.max(1,u-10-w)},k=t?t.kind===`band`?v(t.domain,[O.x,O.x+O.w]):y(d.domain,[O.x,O.x+O.w]):null,A=n?n.kind===`band`?v(n.domain,[O.y,O.y+O.h]):y(f.domain,[O.y+O.h,O.y]):null,j=g?y(g.domain,[O.y+O.h,O.y]):null,M=``;if(e.grid){let e=i(O.x+O.w);if(f)for(let t of f.values){let n=i(A.of(t));M+=a(`line`,{x1:i(O.x),x2:e,y1:n,y2:n})}if(d)for(let e of d.values){let t=i(k.of(e));M+=a(`line`,{x1:t,x2:t,y1:i(O.y),y2:i(O.y+O.h)})}}let N=``;if(e.yAxis&&n){if(f)f.values.forEach((e,t)=>{N+=a(`text`,{x:i(O.x-6),y:i(A.of(e)),"text-anchor":`end`,"dominant-baseline":`middle`},r(f.labels[t]))});else{let e=A,t=Math.max(1,Math.ceil(14/(O.h/Math.max(1,n.domain.length))));m.forEach((n,o)=>{if(o%t)return;let s=h[o];N+=a(`text`,{x:i(O.x-6),y:i(e.at(o)+e.bandwidth/2),"text-anchor":`end`,"dominant-baseline":`middle`},r(s)+(s===n?``:a(`title`,{},r(n))))})}}if(b){let e=i(O.y+O.h/2);N+=a(`text`,{x:9,y:e,"text-anchor":`middle`,transform:`rotate(-90 9 ${e})`},r(b))}if(g&&j&&(e.yAxis&&g.values.forEach((e,t)=>{N+=a(`text`,{x:i(O.x+O.w+6),y:i(j.of(e)),"text-anchor":`start`,"dominant-baseline":`middle`},r(g.labels[t]))}),_)){let[e,t]=[l-9,i(O.y+O.h/2)];N+=a(`text`,{x:e,y:t,"text-anchor":`middle`,transform:`rotate(90 ${e} ${t})`},r(_))}let P=``;if(e.xAxis&&t){let e=i(O.y+O.h+16);if(d){let t=Math.max(1,Math.ceil(T(d.labels)/(O.w/Math.max(1,d.values.length-1))));d.values.forEach((n,o)=>{o%t||(P+=a(`text`,{x:i(k.of(n)),y:e,"text-anchor":`middle`},r(d.labels[o])))})}else{let t=k,n=Math.max(1,Math.ceil(T(p)/(O.w/Math.max(1,p.length))));p.forEach((o,s)=>{s%n===0&&(P+=a(`text`,{x:i(t.at(s)+t.bandwidth/2),y:e,"text-anchor":`middle`},r(o)))})}}x&&(P+=a(`text`,{x:i(O.x+O.w/2),y:u-4,"text-anchor":`middle`},r(x)));let F=d&&f,I=t?.kind===`band`?t:n?.kind===`band`?n:null;return{plot:O,x:k,y:A,y2:j,grid:M,ay:N,ax:P,attrs:{"data-plot":`${i(O.x)} ${i(O.y)} ${i(O.w)} ${i(O.h)}`,"data-n":F||!I?null:I.domain.length,"data-xd":F?d.domain.join(` `):null,"data-yd":F?f.domain.join(` `):null}}}function k(e){let t=0,n=0;return{add(r){n=t===0||e===`sum`||e===`mean`?n+r:e===`min`?Math.min(n,r):e===`max`?Math.max(n,r):n,t++},value:()=>e===`count`?t:t===0?null:e===`mean`?n/t:n}}function A(e,t={}){let{hidden:n=[],window:r}=Array.isArray(t)?{hidden:t}:t,i=[],a=/* @__PURE__ */ new Map,s=/* @__PURE__ */ new Map;for(let t of e.data){let n=String(t[e.x]),r=e.series===null?``:String(t[e.series]),o=a.get(r);o===void 0&&a.set(r,o=i.push(r)-1);let c=s.get(n);c||s.set(n,c={label:n,rows:[],vals:[]}),c.rows.push([o,t[e.y],e.y2===null?void 0:t[e.y2]])}let c=t=>{let n=/* @__PURE__ */ new Map;for(let[r,i]of t){let t=n.get(r);t||n.set(r,t=k(e.aggregate)),typeof i==`number`&&t.add(i)}return i.map((e,t)=>n.get(t)?.value()??null)},l=t=>{let n=k(e.aggregate);for(let[,,e]of t.rows)typeof e==`number`&&n.add(e);t.y2=n.value()},u=[...s.values()];for(let e of u)e.vals=c(e.rows),l(e);let d=e=>e.vals.reduce((e,t)=>e+(t??0),0);if(e.sort){let t=e.sort===`asc`?1:-1;u=u.map(e=>[e,d(e)]).sort((e,n)=>t*(e[1]-n[1])).map(e=>e[0])}if(e.limit!==null&&u.length>e.limit){let t=new Set(u.map(e=>[e,d(e)]).sort((e,t)=>t[1]-e[1]).slice(0,e.limit).map(e=>e[0])),n={label:o,rows:u.filter(e=>!t.has(e)).flatMap(e=>e.rows),vals:[]};n.vals=c(n.rows),l(n),u=[...u.filter(e=>t.has(e)),n]}let f=e.type===`waterfall`,p=/* @__PURE__ */ new Map;if(f){let t=0;for(let n of u)e.totals.includes(n.label)?p.set(n,[0,t]):p.set(n,[t,t+=d(n)])}if(r?.length===2&&u.length){let e=Math.min(u.length-1,Math.max(0,Math.trunc(r[1]))),t=Math.min(e,Math.max(0,Math.trunc(r[0])));u=u.slice(t,e+1)}let m=[];i.forEach((e,t)=>n.includes(e)||m.push(t));let h=[],g=0,_=0;return u.forEach((t,n)=>{let r=0,i=0;for(let a of m){let o=t.vals[a]??null,s=o??0,[c,l]=f?p.get(t):[0,s];e.stack&&(s<0?[c,l]=[i,i+=s]:[c,l]=[r,r+=s]),g=Math.min(g,c,l),_=Math.max(_,c,l),h.push({ci:n,si:a,value:o,y0:c,y1:l})}}),{categories:u.map(e=>e.label),totals:u.map(t=>e.totals.includes(t.label)),series:i,visible:m,cells:h,extent:[g,_],y2:e.y2===null?[]:u.map(e=>e.y2??null)}}function j(e){let t=typeof e.colorBy==`string`&&e.colorBy!==`sign`?e.colorBy:null,n=/* @__PURE__ */ new Map;if(t)for(let r of e.data){let i=r[t];if(typeof i!=`number`)continue;let a=String(r[e.x])+`\0`+(e.series===null?``:String(r[e.series]));(n.get(a)??n.set(a,k(e.aggregate)).get(a)).add(i)}return(e,t)=>n.get(e+`\0`+t)?.value()??null}function M(e){let t=[];for(let n of e.cells)t[n.ci]=n;let n=e.visible[0]??0,r=0,i=[];return e.categories.forEach((a,o)=>{let s=t[o];if(s){if(e.totals[o])return void i.push({ci:o,si:n,y0:0,y1:r,v:r,s:2});s.value!==null&&i.push({ci:o,si:n,y0:r,y1:r+=s.value,v:s.value,s:+(s.value<0)})}}),i}var N=(e,t)=>e.type===`waterfall`?M(t):t.cells.flatMap(e=>e.value===null?[]:[{ci:e.ci,si:e.si,y0:e.y0,y1:e.y1,v:e.value,s:e.si%8}]),P={noun:`Bar`,axes(e,t){let n=t.extent[0],r=t.extent[1];if(e.type===`waterfall`){n=r=0;for(let e of M(t))n=Math.min(n,e.y0,e.y1),r=Math.max(r,e.y0,e.y1)}let i={kind:`band`,field:e.x,domain:t.categories},a={kind:`linear`,field:e.y,domain:[n,r]};if(e.y2!==null){let n=t.y2.filter(e=>e!==null);return[i,a,{kind:`linear`,field:e.y2,domain:[Math.min(0,...n),Math.max(0,...n)]}]}return e.horizontal?[a,i]:[i,a]},draw(e){let{spec:t,shaped:n}=e,r=t.horizontal,l=r?e.y:e.x,u=r?e.x:e.y,d=v(n.visible.map(e=>n.series[e]),[0,l.bandwidth],.1,0),f=j(t),p=``,m=``;for(let h of N(t,n)){let g=n.visible.indexOf(h.si),_=l.at(h.ci)+(t.stack||t.type===`waterfall`?0:d.at(g)),v=t.stack||t.type===`waterfall`?l.bandwidth:d.bandwidth,[y,b]=[u.of(h.y0),u.of(h.y1)],x=Math.min(y,b),S=Math.abs(y-b),[C,w,T,E]=r?[x,_,S,v]:[_,x,v,S],D=n.categories[h.ci],O=n.series[h.si],k=f(D,O),A={"data-key":s(O,D),"data-c":h.ci,"data-s":h.s,"data-x":e.fmt(t.x,D),"data-series":O,"data-f":e.fmt(t.y,h.v),"data-y":h.v,"data-neg":h.v<0,"data-tone":e.tone(h.v),"data-q":k===null?null:e.q(k),"data-other":D===o,"data-total":n.totals[h.ci]};if(p+=a(`rect`,{"data-maya":`mark`,...A,x:i(C),y:i(w),width:i(T),height:i(E)}),m+=c(A,C,w,T,E),t.labels){let n=e.fmt(t.y,h.v),i=n.length*7.2+4,[a,o]=[C+T/2,w+E/2],s=h.v<0;r?i<=T&&E>=14?e.label(a,o,n,`center`):e.label(s?C-4:C+T+4,o,n,s?`end`:`start`):i<=T&&E>=16?e.label(a,o,n,`center`):e.label(a,s?w+E:w,n,s?`below`:`above`)}}if(e.y2&&t.y2!==null&&n.y2.length){let r=t.y2,o=n.series.length%8,u=t.titles.get(r)??r,d=``,f=!0,h=``;n.y2.forEach((p,g)=>{if(p===null){f=!0;return}let _=i(l.at(g)+l.bandwidth/2),v=i(e.y2.of(p));d+=`${f?`M`:`L`}${_} ${v}`,f=!1;let y=n.categories[g],b={"data-key":s(`\0y2`,y),"data-c":g,"data-s":o,"data-x":e.fmt(t.x,y),"data-series":u,"data-f":e.fmt(r,p),"data-y":p,"data-neg":p<0};h+=a(`circle`,{"data-maya":`mark`,...b,r:3,cx:_,cy:v}),m+=c(b,_-3,v-3,6,6),t.labels&&e.label(+_,+v,e.fmt(r,p),`above`)}),p+=a(`path`,{"data-maya":`line`,"data-key":s(`l`,`\0y2`),"data-s":o,pathLength:1,d:d||null})+h}return{marks:p,hits:m}}},F={noun:`Dumbbell`,axes(e,t){let n={kind:`band`,field:e.x,domain:t.categories},r={kind:`linear`,field:e.y,domain:t.extent};return e.horizontal?[r,n]:[n,r]},draw(e){let{spec:t,shaped:n}=e,r=t.horizontal,l=r?e.y:e.x,u=r?e.x:e.y,d=Math.max(3,Math.min(5,l.bandwidth/2-1)),f=/* @__PURE__ */ new Map;for(let e of n.cells)e.value!==null&&e.si<2&&((f.get(e.ci)??f.set(e.ci,[]).get(e.ci))[e.si]=e.value);let p=``,m=``,h=``;for(let[g,_]of[...f].sort((e,t)=>e[0]-t[0])){let f=n.categories[g],v=l.at(g)+l.bandwidth/2,y=e=>r?[u.of(e),v]:[v,u.of(e)],[b,x]=_;if(b!==void 0&&x!==void 0){let[t,n]=y(b),[r,o]=y(x);p+=a(`line`,{"data-maya":`link`,"data-key":s(`k`,f),"data-c":g,"data-tone":e.tone(x-b),"stroke-width":2,x1:i(t),y1:i(n),x2:i(r),y2:i(o)})}for(let l of[0,1]){let u=_[l];if(u===void 0)continue;let[p,v]=y(u),b=n.series[l],x={"data-key":s(b,f),"data-c":g,"data-s":l%8,"data-x":e.fmt(t.x,f),"data-series":b,"data-f":e.fmt(t.y,u),"data-y":u,"data-neg":u<0,"data-other":f===o};if(m+=a(`circle`,{"data-maya":`mark`,...x,cx:i(p),cy:i(v),r:d}),h+=c(x,p-d,v-d,d*2,d*2),t.labels){let n=_[1-l],[i,a]=y(n??u),o=e.fmt(t.y,u),s=r?p>=i:v>=a,c=n===void 0?r:l===1?s:!s;r?e.label(p+(c?d+4:-d-4),v,o,c?`start`:`end`):e.label(p,v+(c?d:-d),o,c?`below`:`above`)}}}return{marks:p+m,hits:h}}},I={noun:`Heatmap`,axes:(e,t)=>[{kind:`band`,field:e.x,domain:t.categories},{kind:`band`,field:e.series??``,domain:t.series}],draw(e){let{spec:t,shaped:n}=e,o=e.x,l=e.y,u=n.cells.filter(e=>e.value!==null),d=1/0,f=-1/0;for(let e of u)d=Math.min(d,e.value),f=Math.max(f,e.value);let p=e=>f>d?Math.min(9,Math.max(0,Math.floor((e-d)/(f-d)*10))):9,m=``,h=``;for(let[r,d]of u.entries()){let u=d.value,f=n.visible.indexOf(d.si),g=o.at(d.ci)+1,_=l.at(f)+1,v=Math.max(0,o.bandwidth-2),y=Math.max(0,l.bandwidth-2),b=n.categories[d.ci],x=n.series[d.si],S={"data-key":s(x,b),"data-c":r,"data-x":e.fmt(t.x,b),"data-series":x,"data-y":u,"data-f":e.fmt(t.y,u),"data-q":p(u)};m+=a(`rect`,{"data-maya":`mark`,...S,x:i(g),y:i(_),width:i(v),height:i(y)}),h+=c(S,g,_,v,y),t.labels!==!1&&v>=24&&y>=24&&e.label(g+v/2,_+y/2,e.fmt(t.y,u),`center`)}let g=u.length>0?`<div class="maya-legend" data-maya="ramp"><span>${r(e.fmt(t.y,d))}</span><i></i><span>${r(e.fmt(t.y,f))}</span></div>`:``;return{marks:m,hits:h,grid:``,legend:g}}},L=12,R=e=>typeof e==`number`?e:null;function ee(e){let{spec:t,shaped:n,width:o,height:c}=e,l=t.x?n.categories:[],u=t.x?n.cells.filter(e=>e.si===0).sort((e,t)=>e.ci-t.ci):[],d=u.filter(e=>e.value!==null),f=d[d.length-1],p=t.x?f?.value??null:e.agg(t.aggregate)(t.data.map(e=>R(e[t.y]))),m=o/2;if(p===null)return{marks:``,hits:``,labels:a(`text`,{"data-maya":`empty`,x:i(m),y:i(c/2),"text-anchor":`middle`},r(e.t(`noData`)))};let h=f?.ci??0,g=t.x?e.fmt(t.x,l[h]):``,_=e.fmt(t.y,p),v=i(Math.max(16,Math.min(c*.32,72,(o-24)/(_.length*.62)))),y={"data-c":h,"data-s":0,"data-x":g,"data-series":``,"data-y":p,"data-f":_},b=(e,t)=>a(`text`,{"dominant-baseline":`hanging`,x:L,...e},r(t)),x=a(`text`,{"data-maya":`mark`,"data-key":`v`,...y,"font-size":v,x:L,y:L,"dominant-baseline":`hanging`},r(_)),S=``,C=``,w=L+v+4,T=d[d.length-2];if(f&&T&&T.value){let n=(p-T.value)/Math.abs(T.value),r=new Intl.NumberFormat(t.locale,{style:`percent`,maximumFractionDigits:1,signDisplay:`exceptZero`}).format(n);S+=b({"data-kpi":`delta`,"data-tone":n>0?`good`:n<0?`bad`:null,y:i(w),"font-size":12},e.t(`vs`,r,e.fmt(t.x,l[T.ci]))),w+=16}g&&(S+=b({"data-kpi":`period`,y:i(w),"font-size":11},g)),w+=18;let E=``,D=typeof t.colorBy==`object`&&t.colorBy?t.colorBy.target:null,O=c-L;if(D){let n=o-24,r=Math.min(Math.max(p/D,0),1.2)/1.2,s=new Intl.NumberFormat(t.locale,{style:`percent`,maximumFractionDigits:1});O-=8,E=a(`rect`,{"data-kpi":`track`,x:L,y:O,width:i(n),height:8,rx:4}),x+=a(`rect`,{"data-maya":`mark`,"data-key":`b`,...y,"data-kpi":`fill`,"data-tone":e.tone(p),x:L,y:O,width:i(n*r),height:8,rx:4}),S+=a(`line`,{"data-kpi":`target`,"stroke-width":2,x1:i(L+n/1.2),x2:i(L+n/1.2),y1:O-3,y2:O+11}),S+=b({"data-kpi":`of`,y:O-16,"font-size":11},e.t(`ofTarget`,s.format(p/D),e.fmt(t.y,D))),O-=24}if(l.length>=3&&O-w>=28){let n=d.map(e=>e.value),r=Math.min(...n),p=Math.max(...n)-r||1,m=l.length-1,h=(o-24)/m,g=e=>i(L+e*h),_=e=>i(O-(e-r)/p*(O-w-4)-2),v=``,y=!0;u.forEach(n=>{if(n.value===null)return void(y=!0);v+=`${y?`M`:`L`}${g(n.ci)} ${_(n.value)}`,y=!1,x+=a(`circle`,{"data-maya":`mark`,"data-key":s(``,l[n.ci]),"data-c":n.ci,"data-s":0,"data-x":e.fmt(t.x,l[n.ci]),"data-series":``,"data-y":n.value,"data-f":e.fmt(t.y,n.value),"data-neg":n.value<0,"data-last":n===f,r:3,cx:g(n.ci),cy:_(n.value)})}),x=a(`path`,{"data-maya":`line`,"data-key":s(`l`,``),"data-s":0,pathLength:1,d:v||null})+x,l.forEach((e,t)=>{C+=a(`rect`,{"data-maya":`hit`,"data-c":t,x:i(Math.max(0,L+t*h-h/2)),y:0,width:i(h),height:c,fill:`transparent`})})}return{marks:x,hits:C,labels:S,grid:E}}var te={noun:`KPI`,draw:ee},ne=(e,t)=>[{kind:`band`,field:e.x,domain:t.categories},{kind:`linear`,field:e.y,domain:t.extent}];function re(e,t){let{spec:n,shaped:r,plot:c}=e,l=e.x,u=e.y,d=j(n),f=e=>i(l.at(e)+l.bandwidth/2),p=``,m=``,h=``;for(let c of r.visible){let l=r.series[c],g=r.cells.filter(e=>e.si===c).sort((e,t)=>e.ci-t.ci),_=``,v=!0,y=[[]];for(let t of g){if(t.value===null&&!n.stack?y.push([]):y[y.length-1].push(t),t.value===null){v=!0;continue}_+=`${v?`M`:`L`}${f(t.ci)} ${i(u.of(t.y1))}`,v=!1;let p=r.categories[t.ci],m=d(p,l),g=p===o,b=e.fmt(n.x,p);h+=a(`circle`,{"data-maya":`mark`,"data-key":s(l,p),"data-c":t.ci,"data-s":c%8,"data-x":b,"data-series":l,"data-y":t.value,"data-f":e.fmt(n.y,t.value),"data-neg":t.value<0,"data-tone":e.tone(t.value),"data-q":m===null?null:e.q(m),"data-other":g,r:3,cx:f(t.ci),cy:i(u.of(t.y1))}),n.labels&&e.label(f(t.ci),u.of(t.y1),e.fmt(n.y,t.value),`above`)}if(t){let e=y.filter(e=>e.length>0).map(e=>e.map((e,t)=>`${t?`L`:`M`}${f(e.ci)} ${i(u.of(e.y1))}`).join(``)+[...e].reverse().map(e=>`L${f(e.ci)} ${i(u.of(e.y0))}`).join(``)+`Z`).join(``);e&&(p+=a(`path`,{"data-maya":`area`,"data-key":s(`a`,l),"data-s":c%8,d:e}))}m+=a(`path`,{"data-maya":`line`,"data-key":s(`l`,l),"data-s":c%8,pathLength:1,d:_||null})}let g=``;return r.categories.forEach((e,t)=>{g+=a(`rect`,{"data-maya":`hit`,"data-c":t,x:i(l.at(t)),y:i(c.y),width:i(l.bandwidth),height:i(c.h),fill:`transparent`})}),{marks:p+m+h,hits:g,cross:a(`line`,{x1:0,x2:0,y1:i(c.y),y2:i(c.y+c.h)})}}var ie={noun:`Line`,axes:ne,draw:e=>re(e,!1)},ae={noun:`Area`,axes:ne,draw:e=>re(e,!0)},oe=24;function se(e,t){let n=[],r=e.xDomain,i=e.yDomain,a=e.window;return e.data.forEach((o,s)=>{let c=o[e.x],l=o[e.y];if(typeof c!=`number`||typeof l!=`number`||r&&(c<r[0]||c>r[1])||i&&(l<i[0]||l>i[1])||a&&(c<a[0]||c>a[1]||l<a[2]||l>a[3]))return;let u=t.series.indexOf(e.series===null?``:String(o[e.series]));if(!t.visible.includes(u))return;let d=e.size===null?null:o[e.size],f=e.name===null?null:o[e.name];n.push({i:s,x:c,y:l,sz:typeof d==`number`?d:null,si:u,name:f==null?null:String(f),row:o})}),n}var ce={noun:`Scatter`,axes(e,t){let n=1/0,r=-1/0,i=1/0,a=-1/0;for(let o of se(e,t))n=Math.min(n,o.x),r=Math.max(r,o.x),i=Math.min(i,o.y),a=Math.max(a,o.y);n>r&&(n=r=0,i=a=0);let o=e.size===null?0:(r-n)*.06,s=e.size===null?0:(a-i)*.06,c=(e,t)=>e>=0?Math.max(0,e-t):e-t;return[n,r,i,a]=[c(n,o),r+o,c(i,s),a+s],[{kind:`linear`,field:e.x,domain:e.xDomain??[n,r]},{kind:`linear`,field:e.y,domain:e.yDomain??[i,a]}]},draw(e){let{spec:t,shaped:n,plot:r}=e,o=e.x,c=e.y,l=se(t,n),u=0;for(let e of l)e.sz!==null&&(u=Math.max(u,Math.abs(e.sz)));let d=Math.min(r.w,r.h)/16,f=typeof t.colorBy==`string`&&t.colorBy!==`sign`?t.colorBy:null,p=/* @__PURE__ */ new Map,m=l.map(r=>{let i=r.sz!==null&&u>0?2+Math.sqrt(Math.abs(r.sz)/u)*d:4,a=r.i;if(r.name!==null){let e=(p.get(r.name)??0)+1;p.set(r.name,e),a=e>1?`${r.name}#${e}`:r.name}let l=n.series[r.si],m=e.fmt(t.x,r.x),h=e.fmt(t.y,r.y),g=f?r.row[f]:null;return{p:r,rad:i,d:{"data-key":s(l,a),"data-c":r.i,"data-s":r.si%8,"data-x":r.name??m,"data-series":l,"data-y":r.y,"data-f":r.name===null&&r.sz===null?h:[m,h,r.sz===null?null:e.fmt(t.size,r.sz)].filter(e=>e!==null).join(` · `),"data-neg":r.y<0,"data-tone":e.tone(r.y),"data-q":typeof g==`number`?e.q(g):null},cx:o.of(r.x),cy:c.of(r.y)}});m.sort((e,t)=>t.rad-e.rad);let h=``,g=``;for(let{p:n,rad:r,d:o,cx:s,cy:c}of m)h+=a(`circle`,{"data-maya":`mark`,...o,r:i(r),cx:i(s),cy:i(c)}),r*2<oe&&(g+=a(`circle`,{"data-maya":`hit`,...o,r:i(Math.max(r,12)),cx:i(s),cy:i(c),fill:`transparent`})),t.labels&&e.label(s,c-r,e.fmt(t.y,n.y),`above`);return{marks:h,hits:g}}},le=`0.1.0`,z=Symbol.for(`mayacharts.marks@0`);Object.hasOwn(globalThis,z)||Object.defineProperty(globalThis,z,{value:/* @__PURE__ */ new Map});var B=globalThis[z],ue=[`bar`,`line`,`area`,`scatter`,`heatmap`,`waterfall`,`kpi`,`dumbbell`],de={treemap:`hierarchy`,sunburst:`hierarchy`,sankey:`flow`,hexmap:`geo`},fe=()=>[...B.keys()],pe=`--maya-fg:#1f2328;--maya-fg-muted:#656d76;--maya-bg:#fff`,me=`--maya-fg:#e6edf3;--maya-fg-muted:#9198a1;--maya-bg:#0d1117`,V=(e,t=0)=>Array.from({length:e},(e,n)=>n+t),he=V(8).map(e=>`[data-s="${e}"]{--c:var(--maya-series-${e+1})}`).join(``),ge=V(10).map(e=>`[data-q="${e}"]{--q:${Math.round(20+e*80/9)}%}`).join(``),_e=V(8).map(e=>`.maya:has([data-s="${e}"]:hover) [data-maya=mark]:not([data-s="${e}"]){opacity:.3}`).join(``),ve=V(3,2).map(e=>`.maya-ctl[data-n="${e}"]::before{width:calc((100% - 4px)/${e})}`).join(``)+V(3,1).map(e=>`.maya-ctl[data-i="${e}"]::before{transform:translateX(${e*100}%)}`).join(``),ye=`border:0;background:none;padding:0;font:inherit;color:var(--maya-fg-muted);cursor:pointer`,be=`: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{${pe}}@media (prefers-color-scheme:dark){:host,.maya-root{${me}}}}: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;${ye};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}`+ve+`.maya-ctl [role=radio]{${ye};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}`+he+`[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))}`+ge+`[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}`+_e+`[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}}`,xe=class extends Error{code;path;constructor(e,t,n){super(n),this.name=`MayaSpecError`,this.code=e,this.path=t}},H=e=>e.split(` `),U=Object.fromEntries([...H(`$schema x y2 series size name title description locale currency`).map(e=>[e,`string`]),...H(`stack horizontal labels legend tooltip drill zoom grid xAxis yAxis table animate`).map(e=>[e,`boolean`])]),Se=[...H(`type data y path totals aggregate sort limit format titles text yDomain xDomain select`),...H(`colors colorBy theme`),...Object.keys(U)],Ce=[`bar`,`line`,`area`],we=[`treemap`,`sunburst`,`sankey`],W=`bar,line,area`,Te=`treemap,sunburst,sankey`,Ee=Object.fromEntries(H(`horizontal:bar,dumbbell y2:bar size:scatter name:scatter path:${W},${Te} totals:waterfall series:${W},scatter,heatmap,dumbbell sort:${W},heatmap,dumbbell limit:${W},heatmap,dumbbell stack:bar,area colorBy:${W},waterfall,scatter,dumbbell,kpi,treemap,sunburst,hexmap xDomain:scatter drill:${W},${Te} select:${W},waterfall,scatter,heatmap,dumbbell,treemap,sunburst,hexmap zoom:line,area,scatter`).map(e=>e.split(`:`)).map(([e,t])=>[e,t.split(`,`)])),De=H(`sum mean count min max`),Oe=H(`auto integer decimal compact percent currency date month year time datetime`),ke=H(`dateStyle timeStyle weekday era year month day dayPeriod hour minute second fractionalSecondDigits timeZoneName timeZone hour12 hourCycle calendar`),Ae=e=>ke.some(t=>Object.hasOwn(e,t)),je=[...H(`font fontSize fg fgMuted grid bg accent radius tooltipBg tooltipFg focus good bad`),...[1,2,3,4,5,6,7,8].map(e=>`series`+e)],Me={x:`the category axis`,y:`the plotted numbers`,y2:`the right-axis line`,series:`splitting rows into series`,size:`bubble area`,name:`point identity`,path:`the hierarchy levels`,colorBy:`colouring marks by value`,format:`formatting that field`,titles:`naming that field`},Ne=`Use horizontal: true to put categories on the left axis.`,Pe=`Size comes from the element's CSS box, or render(spec, { width, height }).`,Fe=`Pie and donut charts are not supported: use "bar" or "treemap" to compare parts.`,Ie=`Use type: "hexmap" (import "mayacharts/geo").`,Le=`Example: { type: "bar", data: [{ month: "Jan", revenue: 10 }], x: "month", y: "revenue" }`,Re={label:`Use titles: { <field>: "Name" } for display names, or labels: true for values on marks.`,xLabel:`Use titles: { <x field>: "Name" }. titles is keyed by field and also names tooltips and table headers.`,yLabel:`Use titles: { <y field>: "Name" }. titles is keyed by field and also names tooltips, legend and table headers.`,yFormat:`Use format: "compact" (applies to every y), or format: { <field>: "currency" }.`,dataKey:`Use y: "<field>" for values and x: "<field>" for categories.`,indexAxis:Ne,orientation:Ne,width:Pe,height:Pe,color:`Use colors: [...] for the palette, or colorBy: "sign" | { target: n } | "<field>".`,groupBy:`Use series: "<field>".`,formatter:`Functions are not supported (the spec is JSON). Use format presets or Intl options.`,"size:number":`spec.size names a field for bubble area. For chart size use CSS, or render(spec, { width, height }).`,"select:boolean":`Use select: true or "multi"; omit it to disable selection.`},ze={column:`Use type: "bar".`,barh:`Use type: "bar" with horizontal: true.`,bubble:`Use type: "scatter" with size: "<field>".`,choropleth:Ie,map:Ie,pie:Fe,donut:Fe},Be=H(`rgb rgba hsl hsla oklch oklab lab lch color color-mix light-dark var calc`),Ve=String.raw`\s*(?:"[\w\s.\-]*"|'[\w\s.\-]*'|[\w\-]+(?:\s+[\w\-]+)*)\s*`,He=RegExp(`^${Ve}(?:,${Ve})*$`),G=(e,t)=>Object.hasOwn(e,t)?e[t]:void 0,K=e=>typeof e==`object`&&!!e&&!Array.isArray(e),q=(e,t=0)=>Array.isArray(e)&&e.length>=t&&e.every(e=>typeof e==`string`),J=e=>e===null?`null`:Array.isArray(e)?`array`:typeof e,Y=e=>{let t=typeof e==`string`||K(e)||Array.isArray(e)?JSON.stringify(e):String(e);return t.length>60?t.slice(0,59)+`…`:t},X=(e,t)=>{let n=e.toLowerCase(),r=``,i=40;for(let e of t){let t=e.toLowerCase(),a=Math.abs(n.length-t.length)+[...t].filter(e=>!n.includes(e)).length,o=0;for(;o<9&&n[o]!==void 0&&n[o]===t[o];)o++;a<4&&a*10-o<i&&([i,r]=[a*10-o,e])}return r&&`Did you mean "${r}"?`},Z=(e,t,n,...r)=>{throw new xe(e,t,`mayacharts: ${n}\n${[...r,`-> https://bbekshr.github.io/mayacharts/errors.html#${e}`].filter(Boolean).map(e=>` `+e).join(`
3
+ `)}`)},Q=(e,t,n)=>Z(`invalid-option`,e,`spec.${e} must be ${n}, received ${Y(t)}.`,G(Re,`${e}:${J(t)}`)??``),Ue=(e,t,n)=>{let r=n?He.test(t):/^[#\w\s.,%()+\-\/]*$/.test(t)&&[...t.matchAll(/([\w-]*)\s*\(/g)].every(e=>Be.includes(e[1].toLowerCase()));(!t||!r)&&Z(`unsafe-css-value`,e,`spec.${e} = ${Y(t)} is not a safe CSS value.`,`Allowed: colours, lengths, numbers and ${Be.join(`() `)}(); fonts are family names.`,`Not allowed: url(), image-set(), other functions, ; { } < > \\ and (outside fonts) quotes.`)},$=(e,t,...n)=>Z(`invalid-format`,e,t,...n),We=(e,t,n)=>{if(typeof t==`string`){Oe.includes(t)||$(e,`spec.${e} = ${Y(t)} is not a format preset.`,`Presets: ${Oe.join(`, `)}. Or per field: { <field>: preset or Intl options }.`,X(t,Oe));return}K(t)||$(e,`spec.${e} must be a preset or Intl options, received ${Y(t)}.`);let{prefix:r,suffix:i,...a}=t;for(let[t,n]of[[`prefix`,r],[`suffix`,i]])n!==void 0&&typeof n!=`string`&&$(`${e}.${t}`,`spec.${e}.${t} must be a string, received ${Y(n)}.`);let o=Ae(a);try{o?new Intl.DateTimeFormat(n,a):new Intl.NumberFormat(n,a)}catch(n){$(e,`spec.${e} = ${Y(t)} is not valid ${o?`Intl.DateTimeFormat`:`Intl.NumberFormat`} options.`,n instanceof Error?n.message:String(n))}},Ge=[[`y`,`a field name or a non-empty array of field names`,e=>typeof e==`string`||q(e,1)],[`path`,`a non-empty array of field names`,e=>q(e,1)],[`totals`,`an array of x values (strings)`,e=>q(e)],[`aggregate`,`one of ${De.join(`, `)}`,e=>De.includes(e)],[`sort`,`"asc" or "desc"`,e=>e===`asc`||e===`desc`],[`limit`,`a positive integer`,e=>Number.isInteger(e)&&e>0],[`select`,`true or "multi"`,e=>e===!0||e===`multi`],[`colorBy`,`"sign", { target: number } or a numeric field name`,e=>typeof e==`string`&&!!e||K(e)&&Object.keys(e).join()===`target`&&Number.isFinite(e.target)],[`titles`,`an object of strings keyed by field`,e=>K(e)&&Object.values(e).every(e=>typeof e==`string`)]];function Ke(t){K(t)||Z(`spec-not-object`,`spec`,`spec must be a plain object, received ${J(t)}.`,`Received: ${Y(t)}`);let n=t;for(let e of Object.keys(n))Se.includes(e)||Z(`unknown-option`,e,`spec.${e} is not a known option.`,G(Re,e)??X(e,Se),`Known options: ${Se.join(`, `)}.`);let r=n.type;r===void 0&&Z(`missing-field`,`type`,`spec.type is required but missing.`,`Required fields: type, data, x, y.`,Le);let i=[...ue,...fe()],a=typeof r==`string`?r:void 0;if(a===void 0||!i.includes(a)){let e=a===void 0?void 0:G(de,a);e&&Z(`unknown-type`,`type`,`spec.type = "${r}" needs the "${e}" module, which is not loaded.`,`Add: import "mayacharts/${e}"`),Z(`unknown-type`,`type`,`spec.type = ${Y(r)} is not a chart type.`,`Valid types: ${i.join(`, `)}.`,a===void 0?``:G(ze,a)??X(a,[...i,...Object.keys(de)]))}let o=r,s=we.includes(o),c=s?`path`:`x`,l=t.path;o===`sankey`&&Array.isArray(l)&&l.length<2&&Z(`invalid-option`,`path`,`spec.path needs at least two levels for a sankey.`,`Example: path: ["region", "family"]`);let u=e=>Z(`missing-field`,e,`spec.${e} is required but missing.`,`Required fields: type, data, ${c}, y.`,s?`Example: { type: "${o}", data: [{ region: "N", state: "NY", sales: 10 }], path: ["region", "state"], y: "sales" }`:Le);n.data===void 0&&u(`data`),Array.isArray(n.data)||Z(`data-not-array`,`data`,`spec.data must be an array of rows, received ${J(n.data)}.`);let d=n.data;d.forEach((e,t)=>{K(e)||Z(`row-not-object`,`data[${t}]`,`spec.data[${t}] must be an object, received ${J(e)}.`,`Received: ${Y(e)}`)}),n[c]===void 0&&o!==`kpi`&&!(c===`x`&&Ce.includes(o)&&n.path!==void 0)&&u(c),n.y===void 0&&u(`y`),o===`dumbbell`&&n.series===void 0&&u(`series`);for(let e in U)n[e]!==void 0&&typeof n[e]!==U[e]&&Q(e,n[e],`a ${U[e]}`);for(let[e,t,r]of Ge)n[e]!==void 0&&!r(n[e])&&Q(e,n[e],t);let{y:f,path:p,select:m,colors:h,colorBy:g,theme:_,text:v}=n;if(v!==void 0){K(v)||Q(`text`,v,`an object of strings`);for(let[t,n]of Object.entries(v))Object.hasOwn(e,t)||Z(`invalid-option`,`text.${t}`,`spec.text.${t} is not a text key.`,X(t,Object.keys(e)),`Text keys: ${Object.keys(e).join(`, `)}.`),typeof n!=`string`&&Q(`text.${t}`,n,`a string`)}for(let e of[`yDomain`,`xDomain`]){let t=n[e];t!==void 0&&!(Array.isArray(t)&&t.length===2&&Number.isFinite(t[0])&&Number.isFinite(t[1])&&t[0]<t[1])&&Z(`invalid-domain`,e,`spec.${e} = ${Y(t)} is not a valid domain.`,`Expected [min, max] with finite numbers and min < max, e.g. [0, 100].`)}let y=`en-US`;if(typeof n.locale==`string`){let e=!1;try{e=Intl.NumberFormat.supportedLocalesOf(n.locale).length>0}catch{}e||$(`locale`,`spec.locale = ${Y(n.locale)} is not a locale this runtime supports.`,`Use a BCP 47 tag such as "de-DE". Node built with small ICU supports English only.`),y=n.locale}if(typeof n.currency==`string`)try{new Intl.NumberFormat(y,{style:`currency`,currency:n.currency})}catch{$(`currency`,`spec.currency = ${Y(n.currency)} is not an ISO 4217 currency code.`,`Use a three-letter code such as "USD" or "EUR".`)}if(typeof n.format==`string`)We(`format`,n.format,y);else if(n.format!==void 0){K(n.format)||Q(`format`,n.format,`a preset or an object keyed by field`);for(let[e,t]of Object.entries(n.format))We(`format.${e}`,t,y)}if(h!==void 0){let e=Array.isArray(h)?h.map((e,t)=>[`[${t}]`,e]):K(h)?Object.entries(h).map(([e,t])=>[`.${e}`,t]):null;(!e||!e.every(([,e])=>typeof e==`string`))&&Q(`colors`,h,`an array of colours, or an object of colours by series value`),e.length>8&&Z(`invalid-option`,`colors`,`spec.colors has ${e.length} colours; the palette has 8 slots.`,`Pass at most 8. Series 9 and later reuse slots in order.`);for(let[t,n]of e)Ue(`colors${t}`,n,!1)}if(_!==void 0){K(_)&&Object.values(_).every(e=>typeof e==`string`)||Q(`theme`,_,`an object of string values`);for(let e of Object.keys(_))je.includes(e)||Z(`invalid-theme`,`theme.${e}`,`spec.theme.${e} is not a theme token.`,`Valid tokens: ${je.join(`, `)}.`,X(e,je));for(let[e,t]of Object.entries(_))Ue(`theme.${e}`,t,e===`font`)}n.stack===!0&&o===`line`&&Z(`stack-unsupported`,`stack`,`spec.stack is not supported with spec.type = "line".`,`Use type "area" (or "bar") to stack series.`);for(let e in Ee)n[e]!==void 0&&n[e]!==!1&&!Ee[e].includes(o)&&Z(`option-unsupported`,e,`spec.${e} is not supported with spec.type = "${o}".`,`spec.${e} works with: ${Ee[e].join(`, `)}.`);let b=Ce.includes(o),x=[[g!==void 0&&n.series!==void 0&&o!==`dumbbell`,`colorBy`,`spec.colorBy cannot be combined with spec.series.`,`Series already set the colours; remove one of them.`],[n.yDomain!==void 0&&Array.isArray(f),`yDomain`,`spec.yDomain cannot be combined with a y array.`,`Each measure needs its own domain; use a single y or remove yDomain.`],[n.drill===!0&&m!==void 0,`select`,`spec.select cannot be combined with spec.drill.`,`A click either drills or selects; choose one.`],[b&&p!==void 0&&n.x!==void 0,`x`,`spec.x cannot be combined with spec.path.`,`With path, the current drill level is the category; remove x.`],[n.y2!==void 0&&n.horizontal===!0,`y2`,`spec.y2 cannot be combined with spec.horizontal.`,`The y2 line needs a right value axis; draw vertical bars.`],[o===`kpi`&&g!==void 0&&!K(g),`colorBy`,`spec.colorBy on "kpi" must be { target: number }.`,`A kpi compares its headline with one target, drawn as a bullet bar.`],[b&&n.drill===!0&&p===void 0,`drill`,`spec.drill on "${o}" needs spec.path.`,`Replace x with path: ["region", "state"] (outer to inner).`]];for(let[e,t,n,r]of x)e&&Z(`option-unsupported`,t,n,r);if(d.length){let e=[...new Set(d.flatMap(e=>Object.keys(e)))],t=(t,n,r,i)=>Z(`unknown-field`,t,n,`Fields found: ${e.slice(0,20).join(`, `)}.`,X(r,e),i),r=typeof f==`string`?[f]:f,i=(e,t)=>t.map((t,n)=>[`${e}[${n}]`,t]),a=[[`x`,n.x],...typeof f==`string`?[[`y`,f]]:i(`y`,r),[`series`,n.series],[`y2`,n.y2],[`size`,n.size],[`name`,n.name],...i(`path`,p??[]),[`colorBy`,g===`sign`?void 0:g]];for(let[n,r]of a){if(typeof r!=`string`||e.includes(r))continue;let i=n.replace(/\[.*/,``);t(n,`spec.${n} = ${Y(r)} is not a field in spec.data.`,r,`spec.${i} names the field used for ${Me[i]}.`)}for(let r of[`format`,`titles`])if(K(n[r]))for(let i of Object.keys(n[r]))e.includes(i)||t(`${r}.${i}`,`spec.${r} key "${i}" is not a field in spec.data.`,i,`spec.${r} keys name fields, for ${Me[r]}.`);g===`sign`&&e.includes(`sign`)&&Z(`invalid-option`,`colorBy`,`spec.colorBy = "sign" colours by the sign of y, but spec.data also has a field named "sign".`,`Rename that field (e.g. data.map(({ sign, ...r }) => ({ ...r, signValue: sign }))) to colour by it.`);let c=(e,t)=>d.forEach((n,r)=>t(n[e],`data[${r}].${e}`)),l=(e,t,n)=>c(e,(r,i)=>{r==null||typeof r==`number`&&Number.isFinite(r)||Z(t,i,`spec.${i} is ${Y(r)} (a ${J(r)}), but spec.${n} requires numbers.`,typeof r==`string`&&r.trim()&&Number.isFinite(Number(r))?`Convert first: data.map(r => ({ ...r, ${e}: Number(r.${e}) }))`:`Use null for a gap in the data.`)});for(let e of r)l(e,`non-numeric-y`,`y`);if(typeof n.size==`string`&&l(n.size,`non-numeric-field`,`size`),typeof n.y2==`string`&&l(n.y2,`non-numeric-field`,`y2`),o===`dumbbell`&&typeof n.series==`string`){let e=new Set(d.map(e=>String(e[n.series]))).size;e!==2&&Z(`invalid-option`,`series`,`spec.series on "dumbbell" needs exactly 2 values, found ${e}.`,`The first value seen is the start of each bar, the second the end, e.g. last year and this year.`)}if(o===`scatter`&&typeof n.x==`string`&&l(n.x,`non-numeric-field`,`x`),typeof g==`string`&&g!==`sign`&&l(g,`non-numeric-field`,`colorBy`),s)for(let e of r)c(e,(t,n)=>{typeof t==`number`&&t<=0&&Z(`non-positive-value`,n,`spec.${n} is ${t}, but ${o} sizes must be positive.`,`Filter first: data.filter(r => r.${e} > 0), or chart the signed values with "bar".`)})}B.get(o)?.check?.(t,Z)}function qe(e){if(e===void 0)return;K(e)||Z(`invalid-option`,`options`,`options must be a plain object, received ${J(e)}.`);let t=e,n=(e,t,n)=>Z(`unknown-option`,`${e}.${t}`,`${e}.${t} is not a known render option.`,X(t,n),`Known options: ${n.join(`, `)}.`),r=H(`width height view selected nonce`);for(let e of Object.keys(t))r.includes(e)||n(`options`,e,r);let i=(e,t,n)=>Z(`invalid-option`,`options.${e}`,`options.${e} must be ${n}, received ${Y(t)}.`);for(let e of[`width`,`height`]){let n=t[e];n!==void 0&&!(typeof n==`number`&&Number.isFinite(n)&&n>0)&&Z(`invalid-size`,`options.${e}`,`options.${e} = ${Y(n)} is not a valid size.`,`Size must be a finite number greater than 0.`)}let{view:a,selected:o,nonce:s}=t;if(a!==void 0){K(a)||i(`view`,a,`an object`);let e=H(`measure drill window hidden`);for(let t of Object.keys(a))e.includes(t)||n(`options.view`,t,e);let{measure:t,drill:r,window:o,hidden:s}=a;t!==void 0&&!(Number.isInteger(t)&&t>=0)&&i(`view.measure`,t,`an index (integer >= 0)`),r!==void 0&&!q(r)&&i(`view.drill`,r,`an array of strings`),s!==void 0&&!q(s)&&i(`view.hidden`,s,`an array of strings`),o!==void 0&&(!Array.isArray(o)||o.length!==2&&o.length!==4||!o.every(Number.isFinite))&&i(`view.window`,o,`[i0, i1] or [x0, x1, y0, y1] of finite numbers`)}o!==void 0&&!(Array.isArray(o)&&o.every(e=>K(e)&&Object.keys(e).every(e=>[`x`,`series`,`name`].includes(e))))&&i(`selected`,o,`an array of { x?, series?, name? }`),s!==void 0&&!(typeof s==`string`&&/^[\w+/=-]+$/.test(s))&&i(`nonce`,s,`a base64 nonce string`)}function Je(e,t={}){let n=typeof e.y==`string`?[e.y]:[...e.y],r=Math.min(t.measure??0,n.length-1),i=[...e.path??[]],a=e.drill?(t.drill??[]).slice(0,Math.max(0,i.length-1)):[],o=i.slice(a.length),s=e.format,c=e=>Object.entries(e??{}).filter(e=>e[1]!==void 0);return{type:e.type,data:a.length?e.data.filter(e=>a.every((t,n)=>String(e[i[n]])===t)):e.data,x:e.x??(Ce.includes(e.type)?o[0]??``:``),y:n[r],measures:n,measure:r,series:e.series??null,y2:e.y2??null,path:o,drilled:a,window:t.window&&t.window.length===4?t.window:null,size:e.size??null,name:e.name??null,totals:[...e.totals??[]],stack:e.stack??!1,horizontal:e.horizontal??!1,aggregate:e.aggregate??`sum`,sort:e.sort??null,limit:e.limit??null,format:new Map(typeof s==`string`?n.map(e=>[e,s]):c(s)),titles:new Map(c(e.titles)),labels:e.labels??null,text:{...e.text},title:e.title??null,description:e.description??null,legend:e.legend??(e.series!==void 0||e.y2!==void 0),tooltip:e.tooltip??!0,drill:e.drill??!1,select:e.select??!1,zoom:e.zoom??!1,grid:e.grid??!0,xAxis:e.xAxis??!0,yAxis:e.yAxis??!0,locale:e.locale??`en-US`,currency:e.currency??`USD`,yDomain:e.yDomain??null,xDomain:e.xDomain??null,table:e.table??!0,animate:e.animate??!0,colors:Array.isArray(e.colors)?e.colors:e.colors?new Map(Object.entries(e.colors)):null,colorBy:e.colorBy??null,theme:e.theme??{}}}var Ye={bar:P,waterfall:P,line:ie,area:ae,scatter:ce,heatmap:I,kpi:te,dumbbell:F},Xe=e=>e.replace(/[A-Z]|\d+/g,e=>`-`+e.toLowerCase());function Ze(e,n,o){Ke(e),n!==void 0&&qe(n);let s=Object.hasOwn(Ye,e.type)?Ye[e.type]:B.get(e.type),c=Je(e,n?.view),u=n?.width??640,d=n?.height??320,m=A(c,n?.view??{}),h=e=>e>5e3&&Z(`too-many-marks`,`data`,`${e} marks exceed the limit of 5000.`,`Use spec.limit to keep the top N categories, or aggregate the rows first.`);h(m.cells.length);let g=/* @__PURE__ */ new Map,v=(e,n,r)=>{if(n===`\0other`)return t(c,`other`);let i=e+`\0`+r,a=g.get(i);return a||g.set(i,a=_(c,e,r)),a(n)},y=c.colorBy,b=1/0,x=-1/0;if(typeof y==`string`&&y!==`sign`)for(let e of c.data){let t=e[y];typeof t==`number`&&(b=Math.min(b,t),x=Math.max(x,t))}let S=e=>y===`sign`?e<0?`bad`:`good`:y&&typeof y==`object`?e>=y.target?`good`:`bad`:null,C=e=>{let n=S(e);return n===null?null:t(c,y===`sign`?n===`good`?`positive`:`negative`:n===`good`?`above`:`below`)},w=[],T=``,E=(e,t,n,o)=>{let s=n.length*7.2+4,c=o===`start`?e:o===`end`?e-s:e-s/2,l=o===`above`?t-16:o===`below`?t+2:t-7;return c<0||l<0||c+s>u||l+14>d||w.some(e=>c<e[2]&&c+s>e[0]&&l<e[3]&&l+14>e[1])?!1:(w.push([c,l,c+s,l+14]),T+=a(`text`,{x:i(e),y:i(o===`above`?t-4:o===`below`?t+13:t),"text-anchor":o===`start`||o===`end`?o:`middle`,"dominant-baseline":o===`above`||o===`below`?null:`middle`,"data-in":o===`center`},r(n)),!0)},D=s.axes?O(c,s.axes(c,m),{width:u,height:d},v):null,j=D?.plot??{x:0,y:0,w:u,h:d},M={spec:c,shaped:m,width:u,height:d,plot:j,x:D?.x??null,y:D?.y??null,y2:D?.y2??null,fmt:v,label:E,tone:S,q:e=>x>b?Math.min(9,Math.max(0,Math.floor((e-b)/(x-b)*10))):9,agg:e=>t=>{let n=k(e);for(let e of t)typeof e==`number`&&n.add(e);return n.value()},fail:Z,t:(e,...n)=>t(c,e,...n)};s.check?.(e,Z);let N=null,P=``;if(c.data.length===0)P=a(`text`,{"data-maya":`empty`,x:u/2,y:d/2,"text-anchor":`middle`,"dominant-baseline":`middle`},r(t(c,`noData`)));else{let e=(e,t)=>a(`g`,{"data-maya":e},t),t=s.draw(M);h(t.marks.split(` data-maya="mark"`).length-1),N=t.legend??null,P=e(`grid`,t.grid??D?.grid??``)+e(`axis-y`,D?.ay??``)+e(`axis-x`,D?.ax??``)+e(`marks`,t.marks)+e(`labels`,(t.labels??``)+T)+e(`cross`,t.cross??``)+e(`hits`,t.hits)}let F=[];if(Array.isArray(c.colors))c.colors.forEach((e,t)=>F.push([`--maya-series-${t+1}`,e]));else if(c.colors)for(let[e,t]of c.colors){let n=m.series.indexOf(e);n>=0&&F.push([`--maya-series-${n%8+1}`,t])}for(let e in c.theme)F.push([`--maya-${Xe(e)}`,c.theme[e]]);let I=F.map(([e,t])=>`${e}:${t};`).join(``),L=a(`svg`,{class:o===null?`maya-svg`:`maya-root maya-svg`,viewBox:`0 0 ${u} ${d}`,width:u,height:d,role:`img`,"aria-label":o===null?null:l(c),"aria-labelledby":o===null?`maya-t`:null,"aria-describedby":o===null?`maya-d`:null,tabindex:o===null?`0`:null,style:o===null?null:I||null,"data-plot":`${i(j.x)} ${i(j.y)} ${i(j.w)} ${i(j.h)}`,...D?.attrs,"data-dir":c.horizontal?`h`:null},(o?`<style>${o}</style>`:``)+a(`title`,{id:o===null?`maya-t`:null},r(l(c)))+a(`desc`,{id:o===null?`maya-d`:null},r(f(c,m,v,s.noun)))+P),R=``;return N!==null&&c.legend?R=N:(c.series!==null||c.y2!==null)&&c.legend?R=`<div class="maya-legend" data-maya="legend">`+(c.series===null&&c.y2!==null?`<span data-s="0"><i></i>${r(c.titles.get(c.y)??c.y)}</span>`:``)+(c.series===null?[]:m.series).map((e,t)=>a(`button`,{type:`button`,"data-si":t,"data-s":t%8,"data-key":e,"aria-pressed":String(m.visible.includes(t))},`<i></i>${r(e)}`)).join(``)+(c.y2===null?``:`<span data-s="${m.series.length%8}" data-line><i></i>${r(c.titles.get(c.y2)??c.y2)}</span>`)+`</div>`:e.legend!==!1&&y!==null&&c.series===null&&c.type!==`kpi`&&(R=y===`sign`||typeof y==`object`?`<div class="maya-legend" data-maya="tone">`+[`good`,`bad`].map(e=>`<span data-tone="${e}"><i></i>${r(t(c,y===`sign`?e===`good`?`positive`:`negative`:e===`good`?`above`:`below`))}</span>`).join(``)+`</div>`:x>b?`<div class="maya-legend" data-maya="ramp"><span>${r(v(y,b))}</span><i></i><span>${r(v(y,x))}</span></div>`:``),{svg:L,legend:R,controls:c.measures.length>1?`<div class="maya-ctl" role="radiogroup" aria-label="${r(t(c,`measures`))}" data-n="${c.measures.length}" data-i="${c.measure}">`+c.measures.map((e,t)=>`<button type="button" role="radio" aria-checked="${t===c.measure}" data-i="${t}" tabindex="${t===c.measure?0:-1}">${r(c.titles.get(e)??e)}</button>`).join(``)+`</div>`:``,crumbs:c.drilled.length>0?`<nav class="maya-crumbs" aria-label="${r(t(c,`crumbs`))}"><button type="button" data-depth="0">${r(t(c,`back`))}</button>`+c.drilled.map((e,t)=>`<span aria-hidden="true">›</span><button type="button" data-depth="${t+1}"${t===c.drilled.length-1?` aria-current="page"`:``}>${r(String(e))}</button>`).join(``)+`</nav>`:c.drill?`<div class="maya-crumbs" aria-hidden="true"></div>`:``,table:c.table?p(c,m,v,C):``,title:c.title===null?``:`<div class="maya-title">${r(c.title)}</div>`,style:I,vars:F,warnings:[]}}function Qe(e,t){return Ze(e,t,null)}function $e(e,t){return Ze(e,t,be).svg}function et(e,t,n){let i=e.style?` style="${r(e.style)}"`:``,a=n?` nonce="${r(n)}"`:``;return`${t?`<style${a}>${t}</style>`:``}<div class="maya"${i}>${e.title}${e.controls}${e.legend}${e.crumbs}<div class="maya-box">${e.svg}</div>${e.table}<div class="maya-sr" data-maya="live" aria-live="polite"></div><div class="maya-probe" data-maya="probe"></div><div class="maya-tip" popover="manual" role="tooltip"></div></div>`}function tt(e){let t=e=>typeof e==`object`?Object.keys(e):[],n=/* @__PURE__ */ new Set([e.x,...typeof e.y==`string`?[e.y]:e.y,e.series,e.y2,e.size,e.name,...e.path??[],typeof e.colorBy==`string`?e.colorBy:void 0,...t(e.format),...t(e.titles)]);return{...e,data:e.data.map(e=>Object.fromEntries(Object.entries(e).filter(([e])=>n.has(e))))}}function nt(e,t){let n=Qe(e,t),r=JSON.stringify(tt(e)).replace(/</g,`\\u003c`);return`<maya-chart><template shadowrootmode="open">${et(n,be,t?.nonce)}</template><script type="application/json">${r}<\/script></maya-chart>`}export{xe as MayaSpecError,$e as render,Qe as renderParts,nt as renderShell,Ke as validateSpec,le as version};
4
+ //# sourceMappingURL=index.js.map