plotleaf 0.4.0 → 0.5.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.
package/README.md CHANGED
@@ -20,6 +20,10 @@ Follow https://plotleaf-site.loueed.workers.dev/agent and give me a preview and
20
20
 
21
21
  ## Status
22
22
 
23
+ **0.5.0** adds reusable declarative compositions and agent-prepared, explicitly scoped subtotals that remain with their groups when sorting.
24
+
25
+ **0.4.1** removes metric-value scrollbars; exceptionally long values wrap rather than clip.
26
+
23
27
  **0.4.0** adds scoped interactive explorations: dropdowns, segmented choices, toggles, literal text/number inputs and supported date ranges select complete agent-prepared views. Metrics, charts, funnels, tables and data alternatives update together, including offline HTML. Unsupported selections show an unavailable state; no analytics or arbitrary queries run in reports.
24
28
 
25
29
  **0.3.2** adds the website links and updated agent setup prompt. Read the [docs](https://plotleaf-site.loueed.workers.dev/docs/), explore [example reports](https://plotleaf-site.loueed.workers.dev/examples/), or try the [browser playground](https://plotleaf-site.loueed.workers.dev/playground/) without installing anything. The playground supports Markdown and JSON; local image imports and larger reports use the CLI.
@@ -28,7 +32,7 @@ The initial MVP includes validation, live preview/reload, self-contained HTML ex
28
32
 
29
33
  **0.3.0** adds local PNG/JPEG image cells, static sparklines and a cumulative example report. Donut charts and prepared funnel/progress views are available since 0.2.0. Check your installed CLI version or schema before using newer components.
30
34
 
31
- Implemented components: responsive grids, metrics/comparisons, line/area/bar/donut charts, prepared funnel/progress stages, literal chart targets, sortable/formatted tables and callouts. Reports support light/dark system preference, native chart-data disclosures and responsive layouts. Scoped prepared-view controls are supported. Arbitrary row queries, maps, subtotals and reusable compositions remain planned increments.
35
+ Implemented components: responsive grids, metrics/comparisons, line/area/bar/donut charts, prepared funnel/progress stages, literal chart targets, sortable/formatted tables and callouts. Reports support light/dark system preference, native chart-data disclosures and responsive layouts. Scoped prepared-view controls, reusable compositions and prepared subtotals are supported. Arbitrary row queries and maps remain planned increments.
32
36
 
33
37
  ## Quick start
34
38
 
@@ -1 +1 @@
1
- (()=>{var u=(l)=>typeof l==="object"?`${l.start}/${l.end}`:`${typeof l}:${String(l)}`;var b=JSON.parse(document.getElementById("plotleaf-data")?.textContent??"{}");for(let l of b.explorations??[]){let s=function(){let t=new Map,e=!0;for(let n of l.inputs){let i=f(n.id),m=i[0],p;if(n.type==="select")p=n.options[Number(m.value)]?.value??"\x00";else if(n.type==="segmented")p=n.options[Number(i.find((r)=>r.checked)?.value??-1)]?.value??"\x00";else if(n.type==="toggle")p=m.checked;else if(n.type==="date-range")p={start:i.find((r)=>r.dataset.rangePart==="start").value,end:i.find((r)=>r.dataset.rangePart==="end").value};else p=n.type==="number"?m.value===""?NaN:Number(m.value):m.value;let y=u(p);t.set(n.id,y);let g=n.type==="toggle"||n.options.some((r)=>u(r.value)===y);for(let r of i)r.setAttribute("aria-invalid",String(!g));e&&=g}let o=e?l.views.find((n)=>l.inputs.every((i)=>t.get(i.id)===u(n.when[i.id]))):void 0;for(let n of a.querySelectorAll("[data-plotleaf-view]"))n.hidden=n.dataset.plotleafView!==o?.id;v.textContent=o?`Showing ${o.label} · Prepared view`:"No prepared view for these selections. Choose supported values or reset.",a.dispatchEvent(new Event("plotleaf:viewchange",{bubbles:!0}))},d=function(){for(let t of l.inputs)for(let e of f(t.id))if(t.type==="toggle")e.checked=t.default;else if(t.type==="date-range")e.value=t.default[e.dataset.rangePart];else if(t.type==="segmented")e.checked=u(t.options[Number(e.value)].value)===u(t.default);else if(t.type==="select")e.value=String(t.options.findIndex((o)=>u(o.value)===u(t.default)));else e.value=String(t.default);s()},a=document.getElementById(`${l.id}-title`)?.parentElement;if(!a)continue;let f=(t)=>[...a.querySelectorAll("[data-plotleaf-input]")].filter((e)=>e.dataset.plotleafInput===t),v=a.querySelector("[data-plotleaf-status]");for(let t of l.inputs)for(let e of f(t.id))e.disabled=!1,e.addEventListener("input",s),e.addEventListener("change",s);let c=a.querySelector("[data-plotleaf-reset]");c.disabled=!1,c.addEventListener("click",d),s()}var E=new Intl.Collator("en-GB",{numeric:!0,sensitivity:"base"});for(let l of document.querySelectorAll("table[data-plotleaf-table]")){let a=l.tBodies[0];if(!a)continue;let f=[...a.rows],v=-1,s=!1;for(let d of l.querySelectorAll("thead button[data-column]"))d.disabled=!1,d.addEventListener("click",()=>{let c=Number(d.dataset.column);s=v===c?!s:!1,v=c;let t=f.map((e,o)=>({row:e,index:o,value:JSON.parse(e.cells[c]?.dataset.raw??"null")}));t.sort((e,o)=>{if(e.value===null||o.value===null)return e.value===o.value?e.index-o.index:e.value===null?1:-1;let n=typeof e.value==="number"&&typeof o.value==="number"?e.value-o.value:E.compare(String(e.value),String(o.value));return(s?-n:n)||e.index-o.index}),a.replaceChildren(...t.map((e)=>e.row)),l.querySelectorAll("thead th[aria-sort]").forEach((e)=>{let o=e.contains(d);e.setAttribute("aria-sort",o?s?"descending":"ascending":"none");let n=e.querySelector(".sort-indicator");if(n)n.textContent=o?s?"↓":"↑":"↕"})})}})();
1
+ (()=>{var p=(l)=>typeof l==="object"?`${l.start}/${l.end}`:`${typeof l}:${String(l)}`;var b=JSON.parse(document.getElementById("plotleaf-data")?.textContent??"{}");for(let l of b.explorations??[]){let s=function(){let t=new Map,n=!0;for(let o of l.inputs){let e=m(o.id),a=e[0],i;if(o.type==="select")i=o.options[Number(a.value)]?.value??"\x00";else if(o.type==="segmented")i=o.options[Number(e.find((u)=>u.checked)?.value??-1)]?.value??"\x00";else if(o.type==="toggle")i=a.checked;else if(o.type==="date-range")i={start:e.find((u)=>u.dataset.rangePart==="start").value,end:e.find((u)=>u.dataset.rangePart==="end").value};else i=o.type==="number"?a.value===""?NaN:Number(a.value):a.value;let g=p(i);t.set(o.id,g);let y=o.type==="toggle"||o.options.some((u)=>p(u.value)===g);for(let u of e)u.setAttribute("aria-invalid",String(!y));n&&=y}let c=n?l.views.find((o)=>l.inputs.every((e)=>t.get(e.id)===p(o.when[e.id]))):void 0;for(let o of r.querySelectorAll("[data-plotleaf-view]"))o.hidden=o.dataset.plotleafView!==c?.id;f.textContent=c?`Showing ${c.label} · Prepared view`:"No prepared view for these selections. Choose supported values or reset.",r.dispatchEvent(new Event("plotleaf:viewchange",{bubbles:!0}))},v=function(){for(let t of l.inputs)for(let n of m(t.id))if(t.type==="toggle")n.checked=t.default;else if(t.type==="date-range")n.value=t.default[n.dataset.rangePart];else if(t.type==="segmented")n.checked=p(t.options[Number(n.value)].value)===p(t.default);else if(t.type==="select")n.value=String(t.options.findIndex((c)=>p(c.value)===p(t.default)));else n.value=String(t.default);s()},r=document.getElementById(`${l.id}-title`)?.parentElement;if(!r)continue;let m=(t)=>[...r.querySelectorAll("[data-plotleaf-input]")].filter((n)=>n.dataset.plotleafInput===t),f=r.querySelector("[data-plotleaf-status]");for(let t of l.inputs)for(let n of m(t.id))n.disabled=!1,n.addEventListener("input",s),n.addEventListener("change",s);let d=r.querySelector("[data-plotleaf-reset]");d.disabled=!1,d.addEventListener("click",v),s()}var h=new Intl.Collator("en-GB",{numeric:!0,sensitivity:"base"});for(let l of document.querySelectorAll("table[data-plotleaf-table]")){let r=[...l.tBodies].map((s)=>({body:s,original:[...s.rows]}));if(!r.length)continue;let m=-1,f=!1;for(let s of l.querySelectorAll("thead button[data-column]"))s.disabled=!1,s.addEventListener("click",()=>{let v=Number(s.dataset.column);f=m===v?!f:!1,m=v;for(let{body:d,original:t}of r){let n=t.filter((e)=>e.hasAttribute("data-plotleaf-group-header")),c=t.filter((e)=>e.hasAttribute("data-plotleaf-subtotal")),o=t.filter((e)=>!n.includes(e)&&!c.includes(e)).map((e,a)=>({row:e,index:a,value:JSON.parse(e.cells[v]?.dataset.raw??"null")}));o.sort((e,a)=>{if(e.value===null||a.value===null)return e.value===a.value?e.index-a.index:e.value===null?1:-1;let i=typeof e.value==="number"&&typeof a.value==="number"?e.value-a.value:h.compare(String(e.value),String(a.value));return(f?-i:i)||e.index-a.index}),d.replaceChildren(...n,...o.map((e)=>e.row),...c)}l.querySelectorAll("thead th[aria-sort]").forEach((d)=>{let t=d.contains(s);d.setAttribute("aria-sort",t?f?"descending":"ascending":"none");let n=d.querySelector(".sort-indicator");if(n)n.textContent=t?f?"↓":"↑":"↕"})})}})();
@@ -1,4 +1,4 @@
1
- (()=>{var rD=Object.defineProperty;var iD=(t)=>t;function nD(t,e){this[t]=iD.bind(null,e)}var aD=(t,e)=>{for(var r in e)rD(t,r,{get:e[r],enumerable:!0,configurable:!0,set:nD.bind(e,r)})};var ft={};aD(ft,{Arc:()=>Eo,BezierCurve:()=>Ao,BoundingRect:()=>ae,Circle:()=>wo,CompoundPath:()=>rl,Ellipse:()=>Cf,Group:()=>we,HOVER_LAYER_FOR_INCREMENTAL:()=>pa,HOVER_LAYER_FROM_THRESHOLD:()=>od,HOVER_LAYER_NO:()=>ad,Image:()=>_t,IncrementalDisplayable:()=>ed,Line:()=>Ht,LinearGradient:()=>Do,OrientedBoundingRect:()=>Nf,Path:()=>ie,Point:()=>fe,Polygon:()=>Mf,Polyline:()=>cn,RadialGradient:()=>Qv,Rect:()=>De,Ring:()=>Ef,Sector:()=>dr,Text:()=>$e,WH:()=>hn,XY:()=>ai,applyTransform:()=>Bf,calcZ2Range:()=>FL,clipPointsByRect:()=>sS,clipRectByRect:()=>lS,createIcon:()=>zf,decomposeTransform:()=>HL,ensureCopyRect:()=>Po,ensureCopyTransform:()=>Vf,expandOrShrinkRect:()=>Lo,extendPath:()=>rS,extendShape:()=>tS,getCurrentCanvasPainter:()=>GL,getShapeClass:()=>iS,getTransform:()=>oS,groupTransition:()=>ld,initProps:()=>Qe,isBoundingRectAxisAligned:()=>Ff,isElementRemoved:()=>ca,lineLineIntersect:()=>uS,linePolygonIntersect:()=>zL,makeImage:()=>kf,makePath:()=>nl,mergePath:()=>aS,payloadDisableAnimation:()=>VL,registerShape:()=>mr,removeElement:()=>Mo,removeElementWithFadeOut:()=>pn,resizePath:()=>sd,retrieveZInfo:()=>al,setTooltipConfig:()=>Uf,subPixelOptimize:()=>RL,subPixelOptimizeLine:()=>ha,subPixelOptimizeRect:()=>NL,transformDirection:()=>kL,traverseElements:()=>Ci,traverseUpdateZ:()=>ol,updateProps:()=>Ve});var zi=(t)=>typeof t==="object"?`${t.start}/${t.end}`:`${typeof t}:${String(t)}`;var oD=JSON.parse(document.getElementById("plotleaf-data")?.textContent??"{}");for(let t of oD.explorations??[]){let n=function(){let s=new Map,l=!0;for(let f of t.inputs){let c=r(f.id),p=c[0],h;if(f.type==="select")h=f.options[Number(p.value)]?.value??"\x00";else if(f.type==="segmented")h=f.options[Number(c.find((m)=>m.checked)?.value??-1)]?.value??"\x00";else if(f.type==="toggle")h=p.checked;else if(f.type==="date-range")h={start:c.find((m)=>m.dataset.rangePart==="start").value,end:c.find((m)=>m.dataset.rangePart==="end").value};else h=f.type==="number"?p.value===""?NaN:Number(p.value):p.value;let v=zi(h);s.set(f.id,v);let d=f.type==="toggle"||f.options.some((m)=>zi(m.value)===v);for(let m of c)m.setAttribute("aria-invalid",String(!d));l&&=d}let u=l?t.views.find((f)=>t.inputs.every((c)=>s.get(c.id)===zi(f.when[c.id]))):void 0;for(let f of e.querySelectorAll("[data-plotleaf-view]"))f.hidden=f.dataset.plotleafView!==u?.id;i.textContent=u?`Showing ${u.label} · Prepared view`:"No prepared view for these selections. Choose supported values or reset.",e.dispatchEvent(new Event("plotleaf:viewchange",{bubbles:!0}))},a=function(){for(let s of t.inputs)for(let l of r(s.id))if(s.type==="toggle")l.checked=s.default;else if(s.type==="date-range")l.value=s.default[l.dataset.rangePart];else if(s.type==="segmented")l.checked=zi(s.options[Number(l.value)].value)===zi(s.default);else if(s.type==="select")l.value=String(s.options.findIndex((u)=>zi(u.value)===zi(s.default)));else l.value=String(s.default);n()},e=document.getElementById(`${t.id}-title`)?.parentElement;if(!e)continue;let r=(s)=>[...e.querySelectorAll("[data-plotleaf-input]")].filter((l)=>l.dataset.plotleafInput===s),i=e.querySelector("[data-plotleaf-status]");for(let s of t.inputs)for(let l of r(s.id))l.disabled=!1,l.addEventListener("input",n),l.addEventListener("change",n);let o=e.querySelector("[data-plotleaf-reset]");o.disabled=!1,o.addEventListener("click",a),n()}var sD=new Intl.Collator("en-GB",{numeric:!0,sensitivity:"base"});for(let t of document.querySelectorAll("table[data-plotleaf-table]")){let e=t.tBodies[0];if(!e)continue;let r=[...e.rows],i=-1,n=!1;for(let a of t.querySelectorAll("thead button[data-column]"))a.disabled=!1,a.addEventListener("click",()=>{let o=Number(a.dataset.column);n=i===o?!n:!1,i=o;let s=r.map((l,u)=>({row:l,index:u,value:JSON.parse(l.cells[o]?.dataset.raw??"null")}));s.sort((l,u)=>{if(l.value===null||u.value===null)return l.value===u.value?l.index-u.index:l.value===null?1:-1;let f=typeof l.value==="number"&&typeof u.value==="number"?l.value-u.value:sD.compare(String(l.value),String(u.value));return(n?-f:f)||l.index-u.index}),e.replaceChildren(...s.map((l)=>l.row)),t.querySelectorAll("thead th[aria-sort]").forEach((l)=>{let u=l.contains(a);l.setAttribute("aria-sort",u?n?"descending":"ascending":"none");let f=l.querySelector(".sort-indicator");if(f)f.textContent=u?n?"↓":"↑":"↕"})})}/*! *****************************************************************************
1
+ (()=>{var rD=Object.defineProperty;var iD=(t)=>t;function nD(t,e){this[t]=iD.bind(null,e)}var aD=(t,e)=>{for(var r in e)rD(t,r,{get:e[r],enumerable:!0,configurable:!0,set:nD.bind(e,r)})};var ft={};aD(ft,{Arc:()=>Eo,BezierCurve:()=>Ao,BoundingRect:()=>ae,Circle:()=>wo,CompoundPath:()=>rl,Ellipse:()=>Cf,Group:()=>we,HOVER_LAYER_FOR_INCREMENTAL:()=>pa,HOVER_LAYER_FROM_THRESHOLD:()=>od,HOVER_LAYER_NO:()=>ad,Image:()=>_t,IncrementalDisplayable:()=>ed,Line:()=>Ht,LinearGradient:()=>Do,OrientedBoundingRect:()=>Nf,Path:()=>ie,Point:()=>fe,Polygon:()=>Mf,Polyline:()=>cn,RadialGradient:()=>Qv,Rect:()=>De,Ring:()=>Ef,Sector:()=>dr,Text:()=>$e,WH:()=>hn,XY:()=>ai,applyTransform:()=>Bf,calcZ2Range:()=>FL,clipPointsByRect:()=>sS,clipRectByRect:()=>lS,createIcon:()=>zf,decomposeTransform:()=>HL,ensureCopyRect:()=>Po,ensureCopyTransform:()=>Vf,expandOrShrinkRect:()=>Lo,extendPath:()=>rS,extendShape:()=>tS,getCurrentCanvasPainter:()=>GL,getShapeClass:()=>iS,getTransform:()=>oS,groupTransition:()=>ld,initProps:()=>Qe,isBoundingRectAxisAligned:()=>Ff,isElementRemoved:()=>ca,lineLineIntersect:()=>uS,linePolygonIntersect:()=>zL,makeImage:()=>kf,makePath:()=>nl,mergePath:()=>aS,payloadDisableAnimation:()=>VL,registerShape:()=>mr,removeElement:()=>Mo,removeElementWithFadeOut:()=>pn,resizePath:()=>sd,retrieveZInfo:()=>al,setTooltipConfig:()=>Uf,subPixelOptimize:()=>RL,subPixelOptimizeLine:()=>ha,subPixelOptimizeRect:()=>NL,transformDirection:()=>kL,traverseElements:()=>Ci,traverseUpdateZ:()=>ol,updateProps:()=>Ve});var zi=(t)=>typeof t==="object"?`${t.start}/${t.end}`:`${typeof t}:${String(t)}`;var oD=JSON.parse(document.getElementById("plotleaf-data")?.textContent??"{}");for(let t of oD.explorations??[]){let n=function(){let s=new Map,l=!0;for(let f of t.inputs){let c=r(f.id),p=c[0],h;if(f.type==="select")h=f.options[Number(p.value)]?.value??"\x00";else if(f.type==="segmented")h=f.options[Number(c.find((m)=>m.checked)?.value??-1)]?.value??"\x00";else if(f.type==="toggle")h=p.checked;else if(f.type==="date-range")h={start:c.find((m)=>m.dataset.rangePart==="start").value,end:c.find((m)=>m.dataset.rangePart==="end").value};else h=f.type==="number"?p.value===""?NaN:Number(p.value):p.value;let v=zi(h);s.set(f.id,v);let d=f.type==="toggle"||f.options.some((m)=>zi(m.value)===v);for(let m of c)m.setAttribute("aria-invalid",String(!d));l&&=d}let u=l?t.views.find((f)=>t.inputs.every((c)=>s.get(c.id)===zi(f.when[c.id]))):void 0;for(let f of e.querySelectorAll("[data-plotleaf-view]"))f.hidden=f.dataset.plotleafView!==u?.id;i.textContent=u?`Showing ${u.label} · Prepared view`:"No prepared view for these selections. Choose supported values or reset.",e.dispatchEvent(new Event("plotleaf:viewchange",{bubbles:!0}))},a=function(){for(let s of t.inputs)for(let l of r(s.id))if(s.type==="toggle")l.checked=s.default;else if(s.type==="date-range")l.value=s.default[l.dataset.rangePart];else if(s.type==="segmented")l.checked=zi(s.options[Number(l.value)].value)===zi(s.default);else if(s.type==="select")l.value=String(s.options.findIndex((u)=>zi(u.value)===zi(s.default)));else l.value=String(s.default);n()},e=document.getElementById(`${t.id}-title`)?.parentElement;if(!e)continue;let r=(s)=>[...e.querySelectorAll("[data-plotleaf-input]")].filter((l)=>l.dataset.plotleafInput===s),i=e.querySelector("[data-plotleaf-status]");for(let s of t.inputs)for(let l of r(s.id))l.disabled=!1,l.addEventListener("input",n),l.addEventListener("change",n);let o=e.querySelector("[data-plotleaf-reset]");o.disabled=!1,o.addEventListener("click",a),n()}var sD=new Intl.Collator("en-GB",{numeric:!0,sensitivity:"base"});for(let t of document.querySelectorAll("table[data-plotleaf-table]")){let e=[...t.tBodies].map((n)=>({body:n,original:[...n.rows]}));if(!e.length)continue;let r=-1,i=!1;for(let n of t.querySelectorAll("thead button[data-column]"))n.disabled=!1,n.addEventListener("click",()=>{let a=Number(n.dataset.column);i=r===a?!i:!1,r=a;for(let{body:o,original:s}of e){let l=s.filter((c)=>c.hasAttribute("data-plotleaf-group-header")),u=s.filter((c)=>c.hasAttribute("data-plotleaf-subtotal")),f=s.filter((c)=>!l.includes(c)&&!u.includes(c)).map((c,p)=>({row:c,index:p,value:JSON.parse(c.cells[a]?.dataset.raw??"null")}));f.sort((c,p)=>{if(c.value===null||p.value===null)return c.value===p.value?c.index-p.index:c.value===null?1:-1;let h=typeof c.value==="number"&&typeof p.value==="number"?c.value-p.value:sD.compare(String(c.value),String(p.value));return(i?-h:h)||c.index-p.index}),o.replaceChildren(...l,...f.map((c)=>c.row),...u)}t.querySelectorAll("thead th[aria-sort]").forEach((o)=>{let s=o.contains(n);o.setAttribute("aria-sort",s?i?"descending":"ascending":"none");let l=o.querySelector(".sort-indicator");if(l)l.textContent=s?i?"↓":"↑":"↕"})})}/*! *****************************************************************************
2
2
  Copyright (c) Microsoft Corporation.
3
3
 
4
4
  Permission to use, copy, modify, and/or distribute this software for any
@@ -214,8 +214,7 @@ code {
214
214
  letter-spacing: -0.035em;
215
215
  line-height: 1.15;
216
216
  margin: 0;
217
- white-space: nowrap;
218
- overflow-x: auto;
217
+ overflow-wrap: anywhere;
219
218
  }
220
219
  .metric-comparison {
221
220
  font-size: 15px;
@@ -444,6 +443,20 @@ caption {
444
443
  text-align: start;
445
444
  padding: 0 0 20px;
446
445
  }
446
+ .table-scope {
447
+ display: block;
448
+ color: var(--muted);
449
+ font-size: 14px;
450
+ font-weight: 400;
451
+ }
452
+ .table-group th {
453
+ color: var(--muted);
454
+ font-size: 14px;
455
+ padding-block: 18px 7px;
456
+ }
457
+ .table-subtotal td {
458
+ font-weight: 550;
459
+ }
447
460
  thead {
448
461
  color: var(--muted);
449
462
  }