plotleaf 0.4.1 → 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 +3 -1
- package/dist/assets/base.js +1 -1
- package/dist/assets/charts.js +1 -1
- package/dist/assets/styles.css +14 -0
- package/dist/cli.js +475 -109
- package/examples/m6/prepared-subtotals.json +24 -0
- package/examples/m6/report.md +17 -0
- package/examples/m6/summary.json +16 -0
- package/examples/report.md +14 -0
- package/package.json +3 -1
- package/schema/components.json +260 -1
- package/skills/plotleaf/SKILL.md +33 -2
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"scope": "All regions, January–March",
|
|
4
|
+
"groups": [
|
|
5
|
+
{
|
|
6
|
+
"id": "north",
|
|
7
|
+
"label": "North",
|
|
8
|
+
"rows": [
|
|
9
|
+
{ "product": "Notebook", "orders": 35 },
|
|
10
|
+
{ "product": "Lamp", "orders": 18 }
|
|
11
|
+
],
|
|
12
|
+
"subtotal": { "product": "North subtotal", "orders": 53 }
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "south",
|
|
16
|
+
"label": "South",
|
|
17
|
+
"rows": [
|
|
18
|
+
{ "product": "Notebook", "orders": 24 },
|
|
19
|
+
{ "product": "Lamp", "orders": 41 }
|
|
20
|
+
],
|
|
21
|
+
"subtotal": { "product": "South subtotal", "orders": 65 }
|
|
22
|
+
}
|
|
23
|
+
]
|
|
24
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Regional order summary
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Regional order summary
|
|
6
|
+
|
|
7
|
+
A fictional report using a reusable metric definition and agent-prepared subtotals. Values are illustrative.
|
|
8
|
+
|
|
9
|
+
:::grid{columns="2"}
|
|
10
|
+
::component{src="./summary.json" label="North orders" value="53"}
|
|
11
|
+
::component{src="./summary.json" label="South orders" value="65"}
|
|
12
|
+
:::
|
|
13
|
+
|
|
14
|
+
:::table{data="./prepared-subtotals.json" title="Orders by region" prepared="grouped"}
|
|
15
|
+
::column{field="product" label="Product"}
|
|
16
|
+
::column{field="orders" label="Orders" format="number"}
|
|
17
|
+
:::
|
package/examples/report.md
CHANGED
|
@@ -104,3 +104,17 @@ findings and the earlier examples above stay fixed. All values remain fictional.
|
|
|
104
104
|
::explore{data="./interactions/regional-views.json" title="Regional performance explorer"}
|
|
105
105
|
|
|
106
106
|
::explore{data="./interactions/control-views.json" title="Prepared catalogue scenarios"}
|
|
107
|
+
|
|
108
|
+
## Reusable regional summary
|
|
109
|
+
|
|
110
|
+
The same declarative metric definition is reused for both regions. The table's subtotals are prepared by the author and apply to the stated scope; sorting keeps each subtotal with its group.
|
|
111
|
+
|
|
112
|
+
:::grid{columns="2"}
|
|
113
|
+
::component{src="./m6/summary.json" label="North orders" value="53"}
|
|
114
|
+
::component{src="./m6/summary.json" label="South orders" value="65"}
|
|
115
|
+
:::
|
|
116
|
+
|
|
117
|
+
:::table{data="./m6/prepared-subtotals.json" title="Orders by region" prepared="grouped"}
|
|
118
|
+
::column{field="product" label="Product"}
|
|
119
|
+
::column{field="orders" label="Orders" format="number"}
|
|
120
|
+
:::
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "plotleaf",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Beautiful, interactive reports from Markdown and JSON. Built for agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
"dist/assets/notices.txt",
|
|
28
28
|
"schema/components.json",
|
|
29
29
|
"examples/report.md",
|
|
30
|
+
"examples/m6/*.md",
|
|
31
|
+
"examples/m6/*.json",
|
|
30
32
|
"examples/interactions/*.md",
|
|
31
33
|
"examples/interactions/*.json",
|
|
32
34
|
"examples/storefront/*.md",
|
package/schema/components.json
CHANGED
|
@@ -29,6 +29,189 @@
|
|
|
29
29
|
"timeZone": "UTC"
|
|
30
30
|
},
|
|
31
31
|
"components": {
|
|
32
|
+
"component": {
|
|
33
|
+
"description": "A declarative composition from a local JSON definition.",
|
|
34
|
+
"forms": [
|
|
35
|
+
"leaf"
|
|
36
|
+
],
|
|
37
|
+
"children": [],
|
|
38
|
+
"props": {
|
|
39
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
40
|
+
"type": "object",
|
|
41
|
+
"properties": {
|
|
42
|
+
"src": {
|
|
43
|
+
"type": "string",
|
|
44
|
+
"minLength": 1,
|
|
45
|
+
"maxLength": 1000
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"required": [
|
|
49
|
+
"src"
|
|
50
|
+
],
|
|
51
|
+
"additionalProperties": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"maxLength": 1000
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
"example": "::component{src=\"./components/summary.json\" label=\"Orders\" value=\"1284\"}",
|
|
57
|
+
"dataRules": {
|
|
58
|
+
"schema": {
|
|
59
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
60
|
+
"type": "object",
|
|
61
|
+
"properties": {
|
|
62
|
+
"version": {
|
|
63
|
+
"type": "number",
|
|
64
|
+
"const": 1
|
|
65
|
+
},
|
|
66
|
+
"props": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"propertyNames": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
|
|
71
|
+
},
|
|
72
|
+
"additionalProperties": {
|
|
73
|
+
"oneOf": [
|
|
74
|
+
{
|
|
75
|
+
"type": "object",
|
|
76
|
+
"properties": {
|
|
77
|
+
"type": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"const": "string"
|
|
80
|
+
},
|
|
81
|
+
"default": {
|
|
82
|
+
"type": "string",
|
|
83
|
+
"maxLength": 1000
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
"required": [
|
|
87
|
+
"type"
|
|
88
|
+
],
|
|
89
|
+
"additionalProperties": false
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"type": "object",
|
|
93
|
+
"properties": {
|
|
94
|
+
"type": {
|
|
95
|
+
"type": "string",
|
|
96
|
+
"const": "number"
|
|
97
|
+
},
|
|
98
|
+
"default": {
|
|
99
|
+
"type": "number"
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"required": [
|
|
103
|
+
"type"
|
|
104
|
+
],
|
|
105
|
+
"additionalProperties": false
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"type": "object",
|
|
109
|
+
"properties": {
|
|
110
|
+
"type": {
|
|
111
|
+
"type": "string",
|
|
112
|
+
"const": "boolean"
|
|
113
|
+
},
|
|
114
|
+
"default": {
|
|
115
|
+
"type": "boolean"
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"required": [
|
|
119
|
+
"type"
|
|
120
|
+
],
|
|
121
|
+
"additionalProperties": false
|
|
122
|
+
}
|
|
123
|
+
]
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"components": {
|
|
127
|
+
"minItems": 1,
|
|
128
|
+
"maxItems": 512,
|
|
129
|
+
"type": "array",
|
|
130
|
+
"items": {
|
|
131
|
+
"$ref": "#/$defs/__schema0"
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
"required": [
|
|
136
|
+
"version",
|
|
137
|
+
"props",
|
|
138
|
+
"components"
|
|
139
|
+
],
|
|
140
|
+
"additionalProperties": false,
|
|
141
|
+
"$defs": {
|
|
142
|
+
"__schema0": {
|
|
143
|
+
"type": "object",
|
|
144
|
+
"properties": {
|
|
145
|
+
"name": {
|
|
146
|
+
"type": "string",
|
|
147
|
+
"pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
|
|
148
|
+
},
|
|
149
|
+
"props": {
|
|
150
|
+
"type": "object",
|
|
151
|
+
"propertyNames": {
|
|
152
|
+
"type": "string",
|
|
153
|
+
"pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
|
|
154
|
+
},
|
|
155
|
+
"additionalProperties": {
|
|
156
|
+
"anyOf": [
|
|
157
|
+
{
|
|
158
|
+
"anyOf": [
|
|
159
|
+
{
|
|
160
|
+
"type": "string",
|
|
161
|
+
"maxLength": 1000
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"type": "number"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"type": "boolean"
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"type": "object",
|
|
173
|
+
"properties": {
|
|
174
|
+
"prop": {
|
|
175
|
+
"type": "string",
|
|
176
|
+
"pattern": "^[A-Za-z][A-Za-z0-9_-]{0,63}$"
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"required": [
|
|
180
|
+
"prop"
|
|
181
|
+
],
|
|
182
|
+
"additionalProperties": false
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"children": {
|
|
188
|
+
"maxItems": 512,
|
|
189
|
+
"type": "array",
|
|
190
|
+
"items": {
|
|
191
|
+
"$ref": "#/$defs/__schema0"
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
"required": [
|
|
196
|
+
"name",
|
|
197
|
+
"props"
|
|
198
|
+
],
|
|
199
|
+
"additionalProperties": false
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
"limits": {
|
|
204
|
+
"depth": 16,
|
|
205
|
+
"definitions": 64,
|
|
206
|
+
"nodes": 512,
|
|
207
|
+
"rows": 20000,
|
|
208
|
+
"dataBytes": 8388608,
|
|
209
|
+
"parameters": 32,
|
|
210
|
+
"jsonDepth": 32,
|
|
211
|
+
"jsonContainers": 10000
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
},
|
|
32
215
|
"explore": {
|
|
33
216
|
"description": "Scoped native controls select complete agent-prepared views. No analytics or report JavaScript.",
|
|
34
217
|
"forms": [
|
|
@@ -411,6 +594,7 @@
|
|
|
411
594
|
],
|
|
412
595
|
"children": [
|
|
413
596
|
"metric",
|
|
597
|
+
"component",
|
|
414
598
|
"line",
|
|
415
599
|
"area",
|
|
416
600
|
"bar",
|
|
@@ -821,6 +1005,12 @@
|
|
|
821
1005
|
"type": "string",
|
|
822
1006
|
"minLength": 1,
|
|
823
1007
|
"maxLength": 1000
|
|
1008
|
+
},
|
|
1009
|
+
"prepared": {
|
|
1010
|
+
"type": "string",
|
|
1011
|
+
"enum": [
|
|
1012
|
+
"grouped"
|
|
1013
|
+
]
|
|
824
1014
|
}
|
|
825
1015
|
},
|
|
826
1016
|
"required": [
|
|
@@ -828,7 +1018,76 @@
|
|
|
828
1018
|
],
|
|
829
1019
|
"additionalProperties": false
|
|
830
1020
|
},
|
|
831
|
-
"example": ":::table{data=\"./plans.json\" title=\"By plan\"}\n::column{field=\"plan\" label=\"Plan\"}\n::column{field=\"change\" label=\"Δ QoQ\" format=\"percent\" sign=\"always\"}\n:::"
|
|
1021
|
+
"example": ":::table{data=\"./plans.json\" title=\"By plan\"}\n::column{field=\"plan\" label=\"Plan\"}\n::column{field=\"change\" label=\"Δ QoQ\" format=\"percent\" sign=\"always\"}\n:::",
|
|
1022
|
+
"dataRules": {
|
|
1023
|
+
"grouped": {
|
|
1024
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
1025
|
+
"type": "object",
|
|
1026
|
+
"properties": {
|
|
1027
|
+
"version": {
|
|
1028
|
+
"type": "number",
|
|
1029
|
+
"const": 1
|
|
1030
|
+
},
|
|
1031
|
+
"scope": {
|
|
1032
|
+
"type": "string",
|
|
1033
|
+
"minLength": 1,
|
|
1034
|
+
"maxLength": 1000
|
|
1035
|
+
},
|
|
1036
|
+
"groups": {
|
|
1037
|
+
"maxItems": 1000,
|
|
1038
|
+
"type": "array",
|
|
1039
|
+
"items": {
|
|
1040
|
+
"type": "object",
|
|
1041
|
+
"properties": {
|
|
1042
|
+
"id": {
|
|
1043
|
+
"type": "string",
|
|
1044
|
+
"minLength": 1,
|
|
1045
|
+
"maxLength": 1000
|
|
1046
|
+
},
|
|
1047
|
+
"label": {
|
|
1048
|
+
"type": "string",
|
|
1049
|
+
"minLength": 1,
|
|
1050
|
+
"maxLength": 1000
|
|
1051
|
+
},
|
|
1052
|
+
"rows": {
|
|
1053
|
+
"minItems": 1,
|
|
1054
|
+
"maxItems": 1000,
|
|
1055
|
+
"type": "array",
|
|
1056
|
+
"items": {
|
|
1057
|
+
"type": "object",
|
|
1058
|
+
"propertyNames": {
|
|
1059
|
+
"type": "string"
|
|
1060
|
+
},
|
|
1061
|
+
"additionalProperties": {}
|
|
1062
|
+
}
|
|
1063
|
+
},
|
|
1064
|
+
"subtotal": {
|
|
1065
|
+
"type": "object",
|
|
1066
|
+
"propertyNames": {
|
|
1067
|
+
"type": "string"
|
|
1068
|
+
},
|
|
1069
|
+
"additionalProperties": {}
|
|
1070
|
+
}
|
|
1071
|
+
},
|
|
1072
|
+
"required": [
|
|
1073
|
+
"id",
|
|
1074
|
+
"label",
|
|
1075
|
+
"rows",
|
|
1076
|
+
"subtotal"
|
|
1077
|
+
],
|
|
1078
|
+
"additionalProperties": false
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
},
|
|
1082
|
+
"required": [
|
|
1083
|
+
"version",
|
|
1084
|
+
"scope",
|
|
1085
|
+
"groups"
|
|
1086
|
+
],
|
|
1087
|
+
"additionalProperties": false
|
|
1088
|
+
},
|
|
1089
|
+
"sorting": "Details sort within groups; prepared subtotals stay at the end of their group. Scope is supplied explicitly."
|
|
1090
|
+
}
|
|
832
1091
|
},
|
|
833
1092
|
"column": {
|
|
834
1093
|
"description": "A scalar, local image or bounded sparkline column. Omitted kind means scalar.",
|
package/skills/plotleaf/SKILL.md
CHANGED
|
@@ -11,9 +11,9 @@ Use an installed `plotleaf` CLI or `npx plotleaf`. The CLI requires Node 22 or n
|
|
|
11
11
|
|
|
12
12
|
## Discover the contract
|
|
13
13
|
|
|
14
|
-
Run `plotleaf schema` (or `npx plotleaf schema`) for the current machine-readable component/prop specifications, rules and input limits. Prefer that output over remembered syntax. Supported components include `grid`, `metric`, `line`, `area`, `bar`, `donut`, `funnel`, `table`, `column` and `callout`. Donut and funnel require plotleaf 0.2.0 or newer; check the installed CLI's schema when using an older version.
|
|
14
|
+
Run `plotleaf schema` (or `npx plotleaf schema`) for the current machine-readable component/prop specifications, rules and input limits. Prefer that output over remembered syntax. Supported components include `component`, `grid`, `metric`, `line`, `area`, `bar`, `donut`, `funnel`, `table`, `column` and `callout`. Donut and funnel require plotleaf 0.2.0 or newer; check the installed CLI's schema when using an older version.
|
|
15
15
|
|
|
16
|
-
Use ordinary Markdown for headings, prose, findings, emphasis, lists, links and dividers. Headings provide sections. Design is built in; do not add custom CSS, raw HTML or framework components. Image/sparkline column kinds require 0.3.0 or newer; check the installed CLI version and schema. Scoped prepared-view controls are available since 0.4.0; maps
|
|
16
|
+
Use ordinary Markdown for headings, prose, findings, emphasis, lists, links and dividers. Headings provide sections. Design is built in; do not add custom CSS, raw HTML or framework components. Image/sparkline column kinds require 0.3.0 or newer; check the installed CLI version and schema. Scoped prepared-view controls are available since 0.4.0. Declarative reusable components and prepared subtotals require 0.5.0 or newer; maps and executable/custom components remain future capabilities.
|
|
17
17
|
|
|
18
18
|
## Author prepared content
|
|
19
19
|
|
|
@@ -153,3 +153,34 @@ empty data, keyboard access, narrow widths and both themes. Export and interact
|
|
|
153
153
|
offline after removing source files. The fictional interactions example and the
|
|
154
154
|
browser playground demonstrate all six control types. No URL state, persistence,
|
|
155
155
|
remote fetch, free-form row query or analytics engine is implied.
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
## Reusable compositions and prepared subtotals (0.5.0 or newer)
|
|
159
|
+
|
|
160
|
+
Use `::component{src="./summary.json" label="Orders" value="1284"}` to reuse a local definition. Its attributes are literal parameters declared by the definition. For example:
|
|
161
|
+
|
|
162
|
+
```json
|
|
163
|
+
{
|
|
164
|
+
"version": 1,
|
|
165
|
+
"props": {"label": {"type": "string"}, "value": {"type": "number"}},
|
|
166
|
+
"components": [{"name": "metric", "props": {"label": {"prop": "label"}, "value": {"prop": "value"}}}]
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Parameters have type `string`, `number` or `boolean`, and may declare a typed `default`; others are required. Reference a complete parameter value with `{ "prop": "name" }`. Definitions may contain registered components, nested `component` definitions and valid component children. They cannot contain expressions, executable code or arbitrary HTML. Static dataset and nested-definition paths resolve relative to the defining JSON file. Caller-provided paths resolve relative to the caller. All references remain within the report directory. Unknown parameters and components, cycles and oversized expansions are errors. Export includes expanded output and requires no definition files. See `plotleaf schema` for the full machine-readable contract and limits.
|
|
171
|
+
|
|
172
|
+
For prepared subtotals, use `:::table{data="./groups.json" title="Orders" prepared="grouped"}` and ordinary `::column` directives. The JSON is an explicit versioned bundle:
|
|
173
|
+
|
|
174
|
+
```json
|
|
175
|
+
{
|
|
176
|
+
"version": 1,
|
|
177
|
+
"scope": "All regions, January–March",
|
|
178
|
+
"groups": [{
|
|
179
|
+
"id": "north", "label": "North",
|
|
180
|
+
"rows": [{"product": "Lamp", "orders": 18}],
|
|
181
|
+
"subtotal": {"product": "North subtotal", "orders": 18}
|
|
182
|
+
}]
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The scope is visible. Supply every detail and subtotal yourself; Plotleaf does not compute or infer totals. Sorting reorders detail rows within each group and keeps the prepared subtotal last. All records follow normal table validation and column projection. For an exploration, each view must refer to the corresponding prepared bundle and scope; never reuse a full-report subtotal to describe a subset.
|