plotleaf 0.3.2 → 0.4.1

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,13 +20,17 @@ Follow https://plotleaf-site.loueed.workers.dev/agent and give me a preview and
20
20
 
21
21
  ## Status
22
22
 
23
+ **0.4.1** removes metric-value scrollbars; exceptionally long values wrap rather than clip.
24
+
25
+ **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.
26
+
23
27
  **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.
24
28
 
25
29
  The initial MVP includes validation, live preview/reload, self-contained HTML export and a generated component specification. All bundled examples use fictional data.
26
30
 
27
31
  **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.
28
32
 
29
- 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. Filters, maps, subtotals and reusable compositions remain planned increments.
33
+ 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.
30
34
 
31
35
  ## Quick start
32
36
 
@@ -169,3 +173,24 @@ Bun builds a Node-target ESM executable and browser-target IIFE assets. The brow
169
173
  MIT licensed. Bundled chart licenses/notices are retained in the package and exported HTML.
170
174
 
171
175
  See [CONTRIBUTING.md](https://github.com/LoueeD/plotleaf/blob/main/CONTRIBUTING.md) for the platform matrix and contribution workflow. The `v0.1.0` source tag reproduces the published npm archive; subsequent source changes require a new package version before release. Renderer releases require the owner's manual visual review of the running preview, in addition to automated checks.
176
+
177
+
178
+ ## Interactive prepared views
179
+
180
+ ```markdown
181
+ ::explore{data="./regional-views.json" title="Regional performance"}
182
+ ```
183
+
184
+ The JSON bundle declares native `inputs`, their defaults/supported values and
185
+ complete `views`. Every view binds all input IDs through `when` and contains
186
+ Markdown using the existing components plus optional inline JSON `datasets`.
187
+ The agent prepares every value and denominator; Plotleaf selects the matching
188
+ view without recalculating analytics. Controls affect only their exploration;
189
+ static prose and metrics outside it stay fixed. Reset restores defaults and an
190
+ unsupported combination hides stale results.
191
+
192
+ See the [interactive example](https://plotleaf-site.loueed.workers.dev/playground/?example=interactions),
193
+ [authoring guide](https://plotleaf-site.loueed.workers.dev/docs/) and `npx plotleaf schema`
194
+ for the exact contract and limits. All selectable data remains readable in the
195
+ HTML file; hidden views are not redaction. Native controls need JavaScript, while
196
+ the default view and data alternatives remain readable without it.
@@ -1 +1 @@
1
- (()=>{var d=new Intl.Collator("en-GB",{numeric:!0,sensitivity:"base"});for(let a of document.querySelectorAll("table[data-plotleaf-table]")){let r=a.tBodies[0];if(!r)continue;let i=[...r.rows],u=-1,n=!1;for(let o of a.querySelectorAll("thead button[data-column]"))o.disabled=!1,o.addEventListener("click",()=>{let s=Number(o.dataset.column);n=u===s?!n:!1,u=s;let c=i.map((e,t)=>({row:e,index:t,value:JSON.parse(e.cells[s]?.dataset.raw??"null")}));c.sort((e,t)=>{if(e.value===null||t.value===null)return e.value===t.value?e.index-t.index:e.value===null?1:-1;let l=typeof e.value==="number"&&typeof t.value==="number"?e.value-t.value:d.compare(String(e.value),String(t.value));return(n?-l:l)||e.index-t.index}),r.replaceChildren(...c.map((e)=>e.row)),a.querySelectorAll("thead th[aria-sort]").forEach((e)=>{let t=e.contains(o);e.setAttribute("aria-sort",t?n?"descending":"ascending":"none");let l=e.querySelector(".sort-indicator");if(l)l.textContent=t?n?"↓":"↑":"↕"})})}})();
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?"↓":"↑":"↕"})})}})();