eleventy-plugin-uncharted 0.4.1 → 0.4.3
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 +10 -335
- package/css/uncharted.css +24 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
A CSS-based chart plugin for Eleventy. Renders charts as pure HTML/CSS.
|
|
4
4
|
|
|
5
|
+
**[Full Documentation](https://uncharted.docs.seanlunsford.com/)**
|
|
6
|
+
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
7
9
|
```bash
|
|
@@ -19,349 +21,22 @@ export default function(eleventyConfig) {
|
|
|
19
21
|
}
|
|
20
22
|
```
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
### Options
|
|
25
|
-
|
|
26
|
-
```javascript
|
|
27
|
-
eleventyConfig.addPlugin(uncharted, {
|
|
28
|
-
dataDir: '_data', // where to find CSV files (default: '_data')
|
|
29
|
-
animate: true, // enable animations globally (default: false)
|
|
30
|
-
cssPath: '/css/uncharted.css', // output path for stylesheet (default: '/css/uncharted.css')
|
|
31
|
-
injectCss: false, // disable automatic CSS handling (default: true)
|
|
32
|
-
downloadData: true, // enable download links globally (default: false)
|
|
33
|
-
dataPassthrough: true, // copy CSV files to public path (default: false)
|
|
34
|
-
dataPath: '/data/' // public URL path for CSV files (default: '/data/')
|
|
35
|
-
});
|
|
36
|
-
```
|
|
37
|
-
|
|
38
|
-
If you set `injectCss: false`, you'll need to manually include the stylesheet in your layout:
|
|
39
|
-
|
|
40
|
-
```html
|
|
41
|
-
<link rel="stylesheet" href="/css/uncharted.css">
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
## Chart Types
|
|
45
|
-
|
|
46
|
-
| Type | Description | Negative Values |
|
|
47
|
-
|------|-------------|-----------------|
|
|
48
|
-
| `donut` | Pie/donut chart using conic-gradient | No |
|
|
49
|
-
| `stacked-bar` | Horizontal bars with stacked segments | No |
|
|
50
|
-
| `stacked-column` | Vertical columns with stacked segments | Yes |
|
|
51
|
-
| `dot` | Categorical dot chart with Y-axis positioning | Yes |
|
|
52
|
-
| `scatter` | XY scatter plot with continuous axes | Yes (X and Y) |
|
|
53
|
-
|
|
54
|
-
## Value Formatting
|
|
55
|
-
|
|
56
|
-
Format displayed numbers with thousands separators, compact notation, or currency symbols.
|
|
57
|
-
Raw values are preserved for calculations; only display output is affected.
|
|
58
|
-
|
|
59
|
-
### Options
|
|
60
|
-
|
|
61
|
-
| Option | Type | Description |
|
|
62
|
-
|--------|------|-------------|
|
|
63
|
-
| `thousands` | boolean | Add commas: `1000` → `1,000` |
|
|
64
|
-
| `compact` | boolean | Use suffixes: `1000` → `1K`, `1000000` → `1M` |
|
|
65
|
-
| `decimals` | number | Decimal places (default: 0, or 1 if compact) |
|
|
66
|
-
| `currency.symbol` | string | Currency symbol: `$`, `€`, etc. |
|
|
67
|
-
| `currency.position` | string | `prefix` (default) or `suffix` |
|
|
68
|
-
|
|
69
|
-
### Examples
|
|
70
|
-
|
|
71
|
-
**Thousands separators:**
|
|
72
|
-
|
|
73
|
-
```yaml
|
|
74
|
-
format:
|
|
75
|
-
thousands: true
|
|
76
|
-
# 1234567 → 1,234,567
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**Compact notation:**
|
|
80
|
-
|
|
81
|
-
```yaml
|
|
82
|
-
format:
|
|
83
|
-
compact: true
|
|
84
|
-
# 1500 → 1.5K, 2000000 → 2M
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
**Currency:**
|
|
88
|
-
|
|
89
|
-
```yaml
|
|
90
|
-
format:
|
|
91
|
-
thousands: true
|
|
92
|
-
currency:
|
|
93
|
-
symbol: "$"
|
|
94
|
-
# 1234 → $1,234
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**Scatter charts** support separate X/Y formatting:
|
|
98
|
-
|
|
99
|
-
```yaml
|
|
100
|
-
format:
|
|
101
|
-
x:
|
|
102
|
-
thousands: true
|
|
103
|
-
y:
|
|
104
|
-
compact: true
|
|
105
|
-
currency:
|
|
106
|
-
symbol: "$"
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Usage
|
|
24
|
+
## Quick Example
|
|
110
25
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Define charts in your page's frontmatter and reference them with the `chart` shortcode:
|
|
26
|
+
Define a chart in frontmatter and render with the shortcode:
|
|
114
27
|
|
|
115
28
|
```markdown
|
|
116
29
|
---
|
|
117
30
|
charts:
|
|
118
|
-
|
|
119
|
-
type: stacked-bar
|
|
120
|
-
title: Platform Growth
|
|
121
|
-
subtitle: Models by domain
|
|
122
|
-
max: 25
|
|
123
|
-
file: charts/platform-growth.csv
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
{% chart "growth" %}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### Global Data Files
|
|
130
|
-
|
|
131
|
-
Define charts in `_data/charts.json` or `_data/charts.yaml`:
|
|
132
|
-
|
|
133
|
-
```json
|
|
134
|
-
{
|
|
135
|
-
"releases": {
|
|
136
|
-
"type": "stacked-column",
|
|
137
|
-
"title": "Release Cadence",
|
|
138
|
-
"file": "charts/releases.csv",
|
|
139
|
-
"legend": ["Production", "Hotfix", "Beta"]
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
```markdown
|
|
145
|
-
{% chart "releases" %}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Inline Data
|
|
149
|
-
|
|
150
|
-
Embed data directly in frontmatter:
|
|
151
|
-
|
|
152
|
-
```yaml
|
|
153
|
-
charts:
|
|
154
|
-
issues:
|
|
155
|
-
type: donut
|
|
156
|
-
title: Issue Types
|
|
157
|
-
center:
|
|
158
|
-
value: total
|
|
159
|
-
label: Issues
|
|
160
|
-
data:
|
|
161
|
-
- label: Features
|
|
162
|
-
value: 33
|
|
163
|
-
- label: Bugs
|
|
164
|
-
value: 21
|
|
165
|
-
- label: Other
|
|
166
|
-
value: 4
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
## CSV Format
|
|
170
|
-
|
|
171
|
-
CSV files use the first column as labels and subsequent columns as data series. The column names can be anything descriptive:
|
|
172
|
-
|
|
173
|
-
```csv
|
|
174
|
-
department,existing,new
|
|
175
|
-
Finance,11,11
|
|
176
|
-
Sales,16,2
|
|
177
|
-
Core,8,0
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
For scatter plots, columns are positional: point label, X value, Y value, and optionally series. Column names become axis labels by default:
|
|
181
|
-
|
|
182
|
-
```csv
|
|
183
|
-
country,population,gdp,region
|
|
184
|
-
USA,330,21,Americas
|
|
185
|
-
China,1400,14,Asia
|
|
186
|
-
Germany,83,4,Europe
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
This displays "population" as the X-axis title and "gdp" as the Y-axis title. Override with explicit titles:
|
|
190
|
-
|
|
191
|
-
```yaml
|
|
192
|
-
charts:
|
|
193
|
-
my-scatter:
|
|
194
|
-
type: scatter
|
|
195
|
-
file: charts/data.csv
|
|
196
|
-
titleX: "Population (millions)"
|
|
197
|
-
titleY: "GDP (trillions)"
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
## Negative Values
|
|
201
|
-
|
|
202
|
-
Stacked column, dot, and scatter charts support negative values. When negative values are present, a zero axis line appears automatically and values are positioned relative to it.
|
|
203
|
-
|
|
204
|
-
For stacked columns, positive values stack upward from zero and negative values stack downward:
|
|
205
|
-
|
|
206
|
-
```csv
|
|
207
|
-
quarter,Cost,Profit
|
|
208
|
-
Q1,20,10
|
|
209
|
-
Q2,25,-10
|
|
210
|
-
Q3,15,25
|
|
211
|
-
Q4,30,-10
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
The chart automatically calculates the range from the maximum positive stack to the minimum negative stack, ensuring proper scaling.
|
|
215
|
-
|
|
216
|
-
## Configuration Options
|
|
217
|
-
|
|
218
|
-
| Option | Type | Description |
|
|
219
|
-
|--------|------|-------------|
|
|
220
|
-
| `type` | string | Chart type (required) |
|
|
221
|
-
| `title` | string | Chart title |
|
|
222
|
-
| `subtitle` | string | Subtitle below title |
|
|
223
|
-
| `file` | string | Path to CSV file (relative to dataDir) |
|
|
224
|
-
| `data` | array | Inline data array |
|
|
225
|
-
| `max` | number | Maximum Y value for scaling |
|
|
226
|
-
| `min` | number | Minimum Y value for scaling (column, dot) |
|
|
227
|
-
| `maxX` | number | Maximum X value (scatter only) |
|
|
228
|
-
| `maxY` | number | Maximum Y value (scatter only) |
|
|
229
|
-
| `minX` | number | Minimum X value (scatter only) |
|
|
230
|
-
| `minY` | number | Minimum Y value (scatter only) |
|
|
231
|
-
| `titleX` | string | X-axis title (scatter only, defaults to column name) |
|
|
232
|
-
| `titleY` | string | Y-axis title (scatter only, defaults to column name) |
|
|
233
|
-
| `legend` | array | Custom legend labels |
|
|
234
|
-
| `center` | object | Donut center content (`value`, `label`) |
|
|
235
|
-
| `showPercentages` | boolean | Show percentages instead of values in donut legend |
|
|
236
|
-
| `animate` | boolean | Override global animation setting |
|
|
237
|
-
| `format` | object | Number formatting options (see Value Formatting) |
|
|
238
|
-
| `rotateLabels` | boolean | Rotate X-axis labels vertically (stacked-column, dot) |
|
|
239
|
-
| `downloadData` | boolean/string | Enable download link (`true`, `false`, or custom label) |
|
|
240
|
-
|
|
241
|
-
## Download Links
|
|
242
|
-
|
|
243
|
-
Add download links below charts so users can download the source CSV data.
|
|
244
|
-
|
|
245
|
-
### Setup
|
|
246
|
-
|
|
247
|
-
Enable globally in plugin options:
|
|
248
|
-
|
|
249
|
-
```javascript
|
|
250
|
-
eleventyConfig.addPlugin(uncharted, {
|
|
251
|
-
downloadData: true, // show download links on all charts
|
|
252
|
-
dataPassthrough: true, // copy CSV files to output
|
|
253
|
-
dataPath: '/data/' // URL path for files (default)
|
|
254
|
-
});
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
### Per-Chart Override
|
|
258
|
-
|
|
259
|
-
```yaml
|
|
260
|
-
charts:
|
|
261
|
-
# Uses global setting
|
|
262
|
-
revenue:
|
|
31
|
+
sales:
|
|
263
32
|
type: stacked-bar
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
# Custom label
|
|
267
|
-
expenses:
|
|
268
|
-
type: stacked-column
|
|
269
|
-
file: charts/expenses.csv
|
|
270
|
-
downloadData: "Download expense report"
|
|
271
|
-
|
|
272
|
-
# Disable for this chart
|
|
273
|
-
internal:
|
|
274
|
-
type: donut
|
|
275
|
-
file: charts/internal.csv
|
|
276
|
-
downloadData: false
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
### Without Passthrough
|
|
280
|
-
|
|
281
|
-
If `dataPassthrough` is false, you're responsible for ensuring CSV files are available at the expected URLs. The plugin generates links based on `dataPath` + `file`.
|
|
282
|
-
|
|
283
|
-
## Styling
|
|
284
|
-
|
|
285
|
-
### CSS Custom Properties
|
|
286
|
-
|
|
287
|
-
Override the default color palette and sizing:
|
|
288
|
-
|
|
289
|
-
```css
|
|
290
|
-
:root {
|
|
291
|
-
--chart-color-1: #2196f3;
|
|
292
|
-
--chart-color-2: #4caf50;
|
|
293
|
-
--chart-color-3: #ffc107;
|
|
294
|
-
--chart-color-4: #ff7043;
|
|
295
|
-
--chart-color-5: #9c27b0;
|
|
296
|
-
--chart-color-6: #e91e63;
|
|
297
|
-
--chart-color-7: #009688;
|
|
298
|
-
--chart-color-8: #78909c;
|
|
299
|
-
--chart-bg: rgba(128, 128, 128, 0.15);
|
|
300
|
-
--chart-height: 12rem; /* Height of bar/column/dot/scatter charts */
|
|
301
|
-
--chart-column-width: 1rem; /* Min width per column */
|
|
302
|
-
--chart-donut-size: 20rem; /* Donut chart max diameter */
|
|
303
|
-
--chart-donut-hole: 30%; /* Donut hole size (percentage of diameter) */
|
|
304
|
-
}
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### Responsive Donut Charts
|
|
308
|
-
|
|
309
|
-
Donut charts automatically adapt to their container using CSS container queries:
|
|
310
|
-
|
|
311
|
-
- **Narrow containers**: Donut on top, legend wraps below horizontally
|
|
312
|
-
- **Wide containers** (24rem+): Donut and legend side by side
|
|
313
|
-
|
|
314
|
-
The donut scales to 80% of container width (minimum 8rem, maximum `--chart-donut-size`).
|
|
315
|
-
|
|
316
|
-
### Per-Chart Styling
|
|
317
|
-
|
|
318
|
-
Each chart gets a class based on its ID for targeted styling:
|
|
319
|
-
|
|
320
|
-
```yaml
|
|
321
|
-
charts:
|
|
322
|
-
sales-growth:
|
|
323
|
-
type: stacked-column
|
|
33
|
+
title: Quarterly Sales
|
|
324
34
|
file: charts/sales.csv
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
```css
|
|
328
|
-
/* Target this specific chart */
|
|
329
|
-
.chart-sales-growth {
|
|
330
|
-
--chart-height: 16rem;
|
|
331
|
-
--chart-color-1: #ff6b6b;
|
|
332
|
-
}
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
### Dual Class System
|
|
336
|
-
|
|
337
|
-
Each chart element gets two classes for styling flexibility:
|
|
338
|
-
|
|
339
|
-
1. **Ordinal**: `.chart-color-1`, `.chart-color-2`, etc.
|
|
340
|
-
2. **Semantic**: `.chart-series-{slugified-name}`
|
|
341
|
-
|
|
342
|
-
```css
|
|
343
|
-
/* Style by position */
|
|
344
|
-
.chart-color-1 { --color: #ff6b6b; }
|
|
345
|
-
|
|
346
|
-
/* Style by series name */
|
|
347
|
-
.chart-series-production { --color: #51cf66; }
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
## Animations
|
|
351
|
-
|
|
352
|
-
Animations are CSS-based with staggered reveals. Enable globally or per-chart:
|
|
35
|
+
---
|
|
353
36
|
|
|
354
|
-
|
|
355
|
-
// Global
|
|
356
|
-
eleventyConfig.addPlugin(uncharted, { animate: true });
|
|
37
|
+
{% chart "sales" %}
|
|
357
38
|
```
|
|
358
39
|
|
|
359
|
-
|
|
360
|
-
# Per-chart override
|
|
361
|
-
charts:
|
|
362
|
-
static-chart:
|
|
363
|
-
type: donut
|
|
364
|
-
animate: false
|
|
365
|
-
```
|
|
40
|
+
Chart types: `donut`, `stacked-bar`, `stacked-column`, `dot`, `scatter`
|
|
366
41
|
|
|
367
|
-
|
|
42
|
+
See the [documentation](https://uncharted.docs.seanlunsford.com/) for configuration options, styling, animations, and more.
|
package/css/uncharted.css
CHANGED
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
display: flex;
|
|
60
60
|
flex-direction: column;
|
|
61
61
|
flex: 1;
|
|
62
|
+
min-width: 16rem;
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
.chart-title {
|
|
@@ -368,8 +369,10 @@
|
|
|
368
369
|
flex-wrap: wrap;
|
|
369
370
|
align-items: center;
|
|
370
371
|
align-content: center;
|
|
372
|
+
justify-content: center;
|
|
371
373
|
gap: 2rem;
|
|
372
374
|
flex: 1;
|
|
375
|
+
min-width: 0;
|
|
373
376
|
}
|
|
374
377
|
|
|
375
378
|
.chart-donut .donut-container {
|
|
@@ -435,6 +438,7 @@
|
|
|
435
438
|
flex-wrap: wrap;
|
|
436
439
|
justify-content: center;
|
|
437
440
|
gap: 0.5rem 1rem;
|
|
441
|
+
max-width: 100%;
|
|
438
442
|
}
|
|
439
443
|
|
|
440
444
|
/* Wide container: legend beside donut, stack items vertically
|
|
@@ -569,24 +573,36 @@
|
|
|
569
573
|
========================================================================== */
|
|
570
574
|
|
|
571
575
|
.chart-scatter .chart-body {
|
|
572
|
-
|
|
576
|
+
display: grid;
|
|
577
|
+
grid-template-columns: auto 1fr;
|
|
578
|
+
grid-template-rows: 1fr auto;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
.chart-scatter .chart-y-axis {
|
|
582
|
+
grid-row: 1;
|
|
583
|
+
grid-column: 1;
|
|
573
584
|
}
|
|
574
585
|
|
|
575
586
|
.chart-scatter .scatter-container {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
587
|
+
grid-row: 1 / -1;
|
|
588
|
+
grid-column: 2;
|
|
589
|
+
display: grid;
|
|
590
|
+
grid-template-rows: subgrid;
|
|
579
591
|
}
|
|
580
592
|
|
|
581
593
|
.chart-scatter .dot-area {
|
|
594
|
+
grid-row: 1;
|
|
582
595
|
position: relative;
|
|
583
|
-
flex: 1;
|
|
584
596
|
min-height: var(--chart-height);
|
|
585
597
|
background: var(--chart-bg);
|
|
586
598
|
border-radius: 3px;
|
|
587
599
|
box-sizing: border-box;
|
|
588
600
|
}
|
|
589
601
|
|
|
602
|
+
.chart-scatter .chart-x-axis {
|
|
603
|
+
grid-row: 2;
|
|
604
|
+
}
|
|
605
|
+
|
|
590
606
|
/* Inner field sized to content area - dots position relative to this */
|
|
591
607
|
.chart-scatter .dot-field {
|
|
592
608
|
position: absolute;
|
|
@@ -867,7 +883,7 @@
|
|
|
867
883
|
background-color: currentColor;
|
|
868
884
|
opacity: 0.4;
|
|
869
885
|
pointer-events: none;
|
|
870
|
-
z-index:
|
|
886
|
+
z-index: 0;
|
|
871
887
|
}
|
|
872
888
|
|
|
873
889
|
.chart-scatter.has-negative-y .dot-field::after {
|
|
@@ -880,7 +896,7 @@
|
|
|
880
896
|
background-color: currentColor;
|
|
881
897
|
opacity: 0.4;
|
|
882
898
|
pointer-events: none;
|
|
883
|
-
z-index:
|
|
899
|
+
z-index: 0;
|
|
884
900
|
}
|
|
885
901
|
|
|
886
902
|
.chart-scatter.has-negative-x .dot-field::before {
|
|
@@ -893,7 +909,7 @@
|
|
|
893
909
|
background-color: currentColor;
|
|
894
910
|
opacity: 0.4;
|
|
895
911
|
pointer-events: none;
|
|
896
|
-
z-index:
|
|
912
|
+
z-index: 0;
|
|
897
913
|
}
|
|
898
914
|
|
|
899
915
|
/* ==========================================================================
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eleventy-plugin-uncharted",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "An Eleventy plugin that renders CSS-based charts from CSV data using shortcodes",
|
|
5
5
|
"main": "eleventy.config.js",
|
|
6
6
|
"type": "module",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"type": "git",
|
|
28
28
|
"url": "git+https://github.com/slunsford/uncharted.git"
|
|
29
29
|
},
|
|
30
|
-
"homepage": "https://
|
|
30
|
+
"homepage": "https://uncharted.docs.seanlunsford.com",
|
|
31
31
|
"bugs": {
|
|
32
32
|
"url": "https://github.com/slunsford/uncharted/issues"
|
|
33
33
|
},
|