plotleaf 0.1.0 → 0.3.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 +42 -6
- package/dist/assets/base.js +1 -1
- package/dist/assets/charts.js +17 -17
- package/dist/assets/styles.css +244 -0
- package/dist/cli.js +798 -124
- package/examples/catalog/assets/desk-lamp.jpg +0 -0
- package/examples/catalog/assets/field-notebook.png +0 -0
- package/examples/catalog/assets/linen-tote.png +0 -0
- package/examples/catalog/products.json +78 -0
- package/examples/catalog/report.md +39 -0
- package/examples/catalog/showcase-products.json +78 -0
- package/examples/onboarding/funnel.json +30 -0
- package/examples/onboarding/plans.json +14 -0
- package/examples/onboarding/report.md +42 -0
- package/examples/onboarding/signups.json +50 -0
- package/examples/report.md +96 -0
- package/package.json +19 -2
- package/schema/components.json +169 -5
- package/skills/plotleaf/SKILL.md +34 -5
package/README.md
CHANGED
|
@@ -4,13 +4,17 @@ Beautiful, interactive reports from Markdown and prepared JSON. Built for coding
|
|
|
4
4
|
|
|
5
5
|
**The agent does the thinking. We do the rendering.**
|
|
6
6
|
|
|
7
|
+
[Source](https://github.com/LoueeD/plotleaf) · [Issues](https://github.com/LoueeD/plotleaf/issues) · [Verification](https://github.com/LoueeD/plotleaf/actions/workflows/ci.yml) · [Contributing](https://github.com/LoueeD/plotleaf/blob/main/CONTRIBUTING.md)
|
|
8
|
+
|
|
7
9
|
A report is one Markdown file, optionally accompanied by local JSON datasets. No application, configuration file, account, database or hosted service. Export one HTML file that keeps working offline.
|
|
8
10
|
|
|
9
11
|
## Status
|
|
10
12
|
|
|
11
13
|
The initial MVP includes validation, live preview/reload, self-contained HTML export and a generated component specification. All bundled examples use fictional data.
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
**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.
|
|
16
|
+
|
|
17
|
+
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.
|
|
14
18
|
|
|
15
19
|
## Quick start
|
|
16
20
|
|
|
@@ -75,11 +79,41 @@ Attributes are literal values, not JavaScript. Keep leaf directives on one line
|
|
|
75
79
|
|
|
76
80
|
Numbers, comparisons, trends and findings are prepared by the author. `percent` uses ratios (`0.12` → 12%); `percentage-points` uses point values (`0.8` → 0.8 pt); `currency:GBP` uses major units. Whole currency amounts omit `.00`; nonzero cents retain two decimal places. Formatting is `en-GB`; date display is UTC. An increase does not imply positive business sentiment.
|
|
77
81
|
|
|
78
|
-
Use `schema` for current property schemas, child rules and input limits. The installed package includes `schema/components.json`, generated from the validation registry, and `skills/plotleaf/SKILL.md`, a reusable report-authoring guide. Public examples under `examples/storefront/` and `examples/
|
|
82
|
+
Use `schema` for current property schemas, child rules and input limits. The installed package includes `schema/components.json`, generated from the validation registry, and `skills/plotleaf/SKILL.md`, a reusable report-authoring guide. Public examples under `examples/storefront/`, `examples/adoption/`, `examples/onboarding/` and `examples/catalog/` contain only fictional data. Catalogue illustrations are original, purpose-built raster assets.
|
|
83
|
+
|
|
84
|
+
## Donut and funnel
|
|
85
|
+
|
|
86
|
+
```markdown
|
|
87
|
+
::donut{data="./plans.json" category="plan" value="teams" title="Teams by plan"}
|
|
88
|
+
::funnel{data="./funnel.json" stage="stage" value="teams" total="baseline" share="share" status="status" title="Funnel by stage"}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Donuts accept up to eight unique, nonblank categories with nonnegative numeric values. Prepare mutually exclusive parts of one whole. Zero values stay in the legend/table; an all-zero dataset shows an empty state. Categories remain in source order and are never grouped automatically.
|
|
92
|
+
|
|
93
|
+
Funnel data supplies each stage explicitly, for example `{"stage":"Activated","teams":25,"baseline":100,"share":0.25,"status":"below-target"}`. `total` maps the positive denominator; `share` maps a ratio from 0 to 1 and must agree with `value / total` within 0.0005. Status is optional and is never inferred: supported values are `on-target`, `below-target`, `at-risk` and `neutral`. Stages stay in source order, with a limit of 20. Native meters, text status and full data disclosures work without JavaScript.
|
|
94
|
+
|
|
95
|
+
Try the fictional `examples/onboarding/report.md` from a source checkout. See [M3 contracts and tradeoffs](https://github.com/LoueeD/plotleaf/blob/main/docs/m3-visualizations.md).
|
|
96
|
+
|
|
97
|
+
## Image and sparkline columns
|
|
98
|
+
|
|
99
|
+
```markdown
|
|
100
|
+
:::table{data="./products.json" title="Product performance"}
|
|
101
|
+
::column{field="image" label="Preview" kind="image" alt="description"}
|
|
102
|
+
::column{field="product" label="Product"}
|
|
103
|
+
::column{field="weekly_orders" label="Weekly orders" kind="sparkline" sortBy="last_week"}
|
|
104
|
+
::column{field="revenue" label="Revenue" format="currency:USD"}
|
|
105
|
+
:::
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
An image value is a relative PNG/JPEG path or null; `alt` names its row's text-alternative field. The fixed thumbnail box is 64 × 48. Images are bounded, validated and embedded once per unique content hash, with no source paths or runtime requests. Remote/data URLs, active SVG and animated images are rejected.
|
|
109
|
+
|
|
110
|
+
Only explicitly declared sparkline fields may contain arrays: at most 64 finite numbers/nulls in sample order. Rows share the observed y scale for that column. Nulls create gaps; a last-sample label and native value disclosure remain readable without JavaScript. Charts and scalar/inferred tables keep the flat scalar data contract.
|
|
111
|
+
|
|
112
|
+
Rich headers are plain text unless `sortBy` names a scalar field; scalar columns retain raw-value sorting. Alternatives, explicit sort keys and embedded image metadata are readable in the export. Try the fictional `examples/catalog/report.md` from a source build. See [M4 contracts](https://github.com/LoueeD/plotleaf/blob/main/docs/m4-rich-tables.md) for limits and validation details.
|
|
79
113
|
|
|
80
114
|
## Data and security boundaries
|
|
81
115
|
|
|
82
|
-
Prepare JSON arrays of flat scalar records. Charts preserve input order and do not calculate, join or aggregate data. Date/number x values must be unique and increasing; line/area nulls are gaps and bar nulls are errors. Tables sort raw typed values. Explicit table columns also select the fields exported; an inferred table includes every source field.
|
|
116
|
+
Prepare JSON arrays of flat scalar records; only explicitly declared sparkline fields permit bounded numeric/null sequences. Charts preserve input order and do not calculate, join or aggregate data. Date/number x values must be unique and increasing; line/area nulls are gaps and bar nulls are errors. Tables sort raw typed values. Explicit table columns also select the fields exported; an inferred table includes every source field.
|
|
83
117
|
|
|
84
118
|
Local JSON must stay within the report directory, including after resolving symlinks. Raw HTML, remote assets/data, executable components and report-authored code are rejected. Script/data escaping, sanitization, size limits and safe output writes are part of compilation. Invalid reports do not replace an existing export.
|
|
85
119
|
|
|
@@ -93,14 +127,14 @@ Use Bun 1.4.4 for development and Node 22+ for the published CLI/runtime checks:
|
|
|
93
127
|
bun install --frozen-lockfile
|
|
94
128
|
bun run build
|
|
95
129
|
|
|
96
|
-
node dist/cli.js examples/
|
|
130
|
+
node dist/cli.js examples/report.md
|
|
97
131
|
node dist/cli.js validate examples/storefront/report.md --json
|
|
98
132
|
node dist/cli.js build examples/storefront/report.md
|
|
99
133
|
```
|
|
100
134
|
|
|
101
|
-
The first CLI command opens a browser and watches the Markdown and
|
|
135
|
+
The first CLI command opens a browser and watches the Markdown, referenced JSON and local table images. Add `--no-open` to print the URL without launching a browser. Ctrl-C stops the server. A failed edit shows diagnostics and recovers after you fix it.
|
|
102
136
|
|
|
103
|
-
|
|
137
|
+
Use `bun run dev` for the cumulative review report in `examples/report.md`. It keeps metrics/comparisons, area/line/bar/donut charts, targets, funnel stages, scalar tables, image cells, sparklines, prose and callouts together as milestones are added. It reuses the focused examples' datasets and image assets; their separate periods and populations remain explicit. Focused examples, including the narrative report in `examples/adoption/report.md`, remain available.
|
|
104
138
|
|
|
105
139
|
## Development and verification
|
|
106
140
|
|
|
@@ -119,3 +153,5 @@ Build before running integration tests. Consumer checks need npm/registry access
|
|
|
119
153
|
Bun builds a Node-target ESM executable and browser-target IIFE assets. The browser graph contains modular ECharts and plain TypeScript, with no UI framework. TSRS is a development-only candidate; official TypeScript checking remains authoritative. Engine guidance and planning notes belong to the source checkout and are excluded from the npm artifact.
|
|
120
154
|
|
|
121
155
|
MIT licensed. Bundled chart licenses/notices are retained in the package and exported HTML.
|
|
156
|
+
|
|
157
|
+
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.
|
package/dist/assets/base.js
CHANGED
|
@@ -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],
|
|
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?"↓":"↑":"↕"})})}})();
|