eleventy-plugin-uncharted 0.2.1 → 0.3.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 +11 -2
- package/css/uncharted.css +102 -68
- package/package.json +1 -1
- package/src/renderers/donut.js +5 -0
package/README.md
CHANGED
|
@@ -253,11 +253,20 @@ Override the default color palette and sizing:
|
|
|
253
253
|
--chart-bg: rgba(128, 128, 128, 0.15);
|
|
254
254
|
--chart-height: 12rem; /* Height of bar/column/dot/scatter charts */
|
|
255
255
|
--chart-column-width: 1rem; /* Min width per column */
|
|
256
|
-
--chart-donut-size:
|
|
257
|
-
--chart-donut-
|
|
256
|
+
--chart-donut-size: 20rem; /* Donut chart max diameter */
|
|
257
|
+
--chart-donut-hole: 30%; /* Donut hole size (percentage of diameter) */
|
|
258
258
|
}
|
|
259
259
|
```
|
|
260
260
|
|
|
261
|
+
### Responsive Donut Charts
|
|
262
|
+
|
|
263
|
+
Donut charts automatically adapt to their container using CSS container queries:
|
|
264
|
+
|
|
265
|
+
- **Narrow containers**: Donut on top, legend wraps below horizontally
|
|
266
|
+
- **Wide containers** (24rem+): Donut and legend side by side
|
|
267
|
+
|
|
268
|
+
The donut scales to 80% of container width (minimum 8rem, maximum `--chart-donut-size`).
|
|
269
|
+
|
|
261
270
|
### Per-Chart Styling
|
|
262
271
|
|
|
263
272
|
Each chart gets a class based on its ID for targeted styling:
|
package/css/uncharted.css
CHANGED
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
--chart-gap: 0.5rem;
|
|
28
28
|
--chart-bar-height: 1.5rem;
|
|
29
29
|
--chart-column-width: 1rem;
|
|
30
|
-
--chart-donut-size:
|
|
31
|
-
--chart-donut-
|
|
30
|
+
--chart-donut-size: 20rem;
|
|
31
|
+
--chart-donut-hole: 30%;
|
|
32
32
|
--chart-dot-size: 0.75rem;
|
|
33
33
|
--chart-height: 12rem;
|
|
34
34
|
}
|
|
@@ -55,8 +55,10 @@
|
|
|
55
55
|
========================================================================== */
|
|
56
56
|
|
|
57
57
|
.chart {
|
|
58
|
-
margin: 1.5rem 0;
|
|
59
58
|
font-family: inherit;
|
|
59
|
+
display: flex;
|
|
60
|
+
flex-direction: column;
|
|
61
|
+
flex: 1;
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
.chart-title {
|
|
@@ -112,7 +114,7 @@
|
|
|
112
114
|
|
|
113
115
|
.chart-legend-item .legend-value {
|
|
114
116
|
opacity: 0.7;
|
|
115
|
-
margin-left: 0.
|
|
117
|
+
margin-left: 0.125rem;
|
|
116
118
|
}
|
|
117
119
|
|
|
118
120
|
/* ==========================================================================
|
|
@@ -122,6 +124,8 @@
|
|
|
122
124
|
.chart-body {
|
|
123
125
|
display: flex;
|
|
124
126
|
gap: 0.5rem;
|
|
127
|
+
flex: 1;
|
|
128
|
+
min-height: var(--chart-height);
|
|
125
129
|
}
|
|
126
130
|
|
|
127
131
|
.chart-y-axis {
|
|
@@ -132,7 +136,7 @@
|
|
|
132
136
|
align-items: flex-end;
|
|
133
137
|
min-width: 2rem;
|
|
134
138
|
box-sizing: border-box;
|
|
135
|
-
height: var(--chart-height);
|
|
139
|
+
min-height: var(--chart-height);
|
|
136
140
|
padding-top: 0.5rem;
|
|
137
141
|
padding-bottom: 0;
|
|
138
142
|
}
|
|
@@ -202,8 +206,10 @@
|
|
|
202
206
|
.chart-stacked-bar .chart-bars {
|
|
203
207
|
display: grid;
|
|
204
208
|
grid-template-columns: auto 1fr auto;
|
|
205
|
-
|
|
206
|
-
|
|
209
|
+
grid-auto-rows: 1fr;
|
|
210
|
+
gap: clamp(0.375rem, 1.5cqi, 1rem) 0.75rem;
|
|
211
|
+
align-items: stretch;
|
|
212
|
+
min-height: var(--chart-height);
|
|
207
213
|
}
|
|
208
214
|
|
|
209
215
|
.chart-stacked-bar .bar-row {
|
|
@@ -213,10 +219,13 @@
|
|
|
213
219
|
.chart-stacked-bar .bar-label {
|
|
214
220
|
font-size: 0.875rem;
|
|
215
221
|
text-align: right;
|
|
222
|
+
display: flex;
|
|
223
|
+
align-items: center;
|
|
224
|
+
justify-content: flex-end;
|
|
216
225
|
}
|
|
217
226
|
|
|
218
227
|
.chart-stacked-bar .bar-track {
|
|
219
|
-
height: var(--chart-bar-height);
|
|
228
|
+
min-height: var(--chart-bar-height);
|
|
220
229
|
border-radius: 3px;
|
|
221
230
|
overflow: hidden;
|
|
222
231
|
background: var(--chart-bg);
|
|
@@ -235,6 +244,8 @@
|
|
|
235
244
|
}
|
|
236
245
|
|
|
237
246
|
.chart-stacked-bar .bar-value {
|
|
247
|
+
display: flex;
|
|
248
|
+
align-items: center;
|
|
238
249
|
font-size: 0.875rem;
|
|
239
250
|
font-variant-numeric: tabular-nums;
|
|
240
251
|
min-width: 2rem;
|
|
@@ -245,36 +256,36 @@
|
|
|
245
256
|
========================================================================== */
|
|
246
257
|
|
|
247
258
|
.chart-stacked-column .chart-body {
|
|
248
|
-
|
|
259
|
+
display: grid;
|
|
260
|
+
grid-template-columns: auto 1fr;
|
|
261
|
+
grid-template-rows: 1fr auto;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.chart-stacked-column .chart-y-axis {
|
|
265
|
+
grid-row: 1;
|
|
266
|
+
grid-column: 1;
|
|
249
267
|
}
|
|
250
268
|
|
|
251
269
|
.chart-stacked-column .chart-scroll {
|
|
252
|
-
|
|
270
|
+
grid-row: 1 / -1;
|
|
271
|
+
grid-column: 2;
|
|
272
|
+
display: grid;
|
|
273
|
+
grid-template-rows: subgrid;
|
|
253
274
|
overflow-x: auto;
|
|
254
275
|
overflow-y: visible;
|
|
255
|
-
position: relative;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
.chart-stacked-column .chart-scroll::before {
|
|
259
|
-
content: '';
|
|
260
|
-
position: sticky;
|
|
261
|
-
left: 0;
|
|
262
|
-
display: block;
|
|
263
|
-
height: var(--chart-height);
|
|
264
|
-
margin-bottom: calc(-1 * var(--chart-height));
|
|
265
|
-
background: var(--chart-bg);
|
|
266
|
-
border-radius: 3px;
|
|
267
|
-
pointer-events: none;
|
|
268
276
|
}
|
|
269
277
|
|
|
270
278
|
.chart-stacked-column .chart-columns {
|
|
279
|
+
grid-row: 1;
|
|
271
280
|
position: relative;
|
|
272
281
|
display: flex;
|
|
273
|
-
gap: 0.
|
|
282
|
+
gap: clamp(0.375rem, 1.5cqi, 1rem);
|
|
274
283
|
align-items: stretch;
|
|
275
|
-
height: var(--chart-height);
|
|
284
|
+
min-height: var(--chart-height);
|
|
276
285
|
padding: 0.5rem 0.5rem 0 0.5rem;
|
|
277
286
|
box-sizing: border-box;
|
|
287
|
+
background: var(--chart-bg);
|
|
288
|
+
border-radius: 3px;
|
|
278
289
|
}
|
|
279
290
|
|
|
280
291
|
.chart-stacked-column .column-track {
|
|
@@ -282,7 +293,6 @@
|
|
|
282
293
|
flex-direction: column-reverse;
|
|
283
294
|
flex: 1;
|
|
284
295
|
min-width: var(--chart-column-width);
|
|
285
|
-
max-width: calc(var(--chart-column-width) * 2);
|
|
286
296
|
border-radius: 3px 3px 0 0;
|
|
287
297
|
overflow: hidden;
|
|
288
298
|
}
|
|
@@ -295,15 +305,15 @@
|
|
|
295
305
|
}
|
|
296
306
|
|
|
297
307
|
.chart-stacked-column .column-labels {
|
|
308
|
+
grid-row: 2;
|
|
298
309
|
display: flex;
|
|
299
|
-
gap: 0.
|
|
310
|
+
gap: clamp(0.375rem, 1.5cqi, 1rem);
|
|
300
311
|
padding: 0.25rem 0.5rem 0;
|
|
301
312
|
}
|
|
302
313
|
|
|
303
314
|
.chart-stacked-column .column-label {
|
|
304
315
|
flex: 1;
|
|
305
316
|
min-width: var(--chart-column-width);
|
|
306
|
-
max-width: calc(var(--chart-column-width) * 2);
|
|
307
317
|
font-size: 0.7rem;
|
|
308
318
|
opacity: 0.6;
|
|
309
319
|
text-align: center;
|
|
@@ -332,11 +342,6 @@
|
|
|
332
342
|
========================================================================== */
|
|
333
343
|
|
|
334
344
|
.chart-donut {
|
|
335
|
-
display: flex;
|
|
336
|
-
flex-direction: row;
|
|
337
|
-
flex-wrap: wrap;
|
|
338
|
-
align-items: flex-start;
|
|
339
|
-
gap: 1rem;
|
|
340
345
|
--donut-1: var(--chart-color-1);
|
|
341
346
|
--donut-2: var(--chart-color-2);
|
|
342
347
|
--donut-3: var(--chart-color-3);
|
|
@@ -351,34 +356,48 @@
|
|
|
351
356
|
--donut-12: var(--chart-color-12);
|
|
352
357
|
}
|
|
353
358
|
|
|
354
|
-
.chart-donut
|
|
355
|
-
|
|
359
|
+
.chart-donut .donut-body {
|
|
360
|
+
container-type: inline-size;
|
|
361
|
+
container-name: donut;
|
|
362
|
+
display: flex;
|
|
363
|
+
flex-wrap: wrap;
|
|
364
|
+
align-items: center;
|
|
365
|
+
align-content: center;
|
|
366
|
+
gap: 1rem;
|
|
367
|
+
flex: 1;
|
|
356
368
|
}
|
|
357
369
|
|
|
358
370
|
.chart-donut .donut-container {
|
|
359
371
|
position: relative;
|
|
360
372
|
display: flex;
|
|
361
373
|
justify-content: center;
|
|
374
|
+
/* Size based on container width, clamped */
|
|
375
|
+
width: clamp(8rem, 80cqi, var(--chart-donut-size));
|
|
376
|
+
aspect-ratio: 1;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/* In portrait, legend takes full width to wrap below */
|
|
380
|
+
.chart-donut .donut-body > .chart-legend {
|
|
381
|
+
flex: 0 0 100%;
|
|
362
382
|
}
|
|
363
383
|
|
|
364
384
|
.chart-donut .donut-ring {
|
|
365
|
-
width:
|
|
366
|
-
height:
|
|
385
|
+
width: 100%;
|
|
386
|
+
height: 100%;
|
|
367
387
|
border-radius: 50%;
|
|
368
388
|
display: flex;
|
|
369
389
|
align-items: center;
|
|
370
390
|
justify-content: center;
|
|
371
391
|
/* Radial mask punches out the center hole */
|
|
372
|
-
--_hole-size: calc((var(--chart-donut-size) - var(--chart-donut-thickness) * 2) / 2);
|
|
373
392
|
mask-image: radial-gradient(
|
|
374
393
|
circle at center,
|
|
375
|
-
transparent var(--
|
|
376
|
-
black var(--
|
|
394
|
+
transparent var(--chart-donut-hole, 30%),
|
|
395
|
+
black var(--chart-donut-hole, 30%)
|
|
377
396
|
);
|
|
378
397
|
-webkit-mask-image: radial-gradient(
|
|
379
398
|
circle at center,
|
|
380
|
-
transparent var(--
|
|
381
|
-
black var(--
|
|
399
|
+
transparent var(--chart-donut-hole, 30%),
|
|
400
|
+
black var(--chart-donut-hole, 30%)
|
|
382
401
|
);
|
|
383
402
|
}
|
|
384
403
|
|
|
@@ -406,12 +425,29 @@
|
|
|
406
425
|
}
|
|
407
426
|
|
|
408
427
|
.chart-donut .chart-legend {
|
|
409
|
-
|
|
410
|
-
|
|
428
|
+
/* Default (portrait): horizontal legend below donut */
|
|
429
|
+
flex-direction: row;
|
|
430
|
+
flex-wrap: wrap;
|
|
431
|
+
gap: 0.5rem 1rem;
|
|
411
432
|
}
|
|
412
433
|
|
|
413
434
|
.chart-donut .chart-legend-item {
|
|
414
|
-
min-width:
|
|
435
|
+
min-width: 8rem;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/* Wide container: row layout with legend beside donut */
|
|
439
|
+
@container donut (min-width: 24rem) {
|
|
440
|
+
.donut-container,
|
|
441
|
+
.chart-donut .donut-body > .chart-legend {
|
|
442
|
+
flex: 0 0 auto;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.chart-donut .donut-body > .chart-legend {
|
|
446
|
+
flex-direction: column;
|
|
447
|
+
flex-wrap: nowrap;
|
|
448
|
+
justify-content: center;
|
|
449
|
+
gap: 0.5rem;
|
|
450
|
+
}
|
|
415
451
|
}
|
|
416
452
|
|
|
417
453
|
/* Donut legend uses same variables as gradient for consistent overrides */
|
|
@@ -428,41 +464,38 @@
|
|
|
428
464
|
.chart-donut .chart-color-11 { --color: var(--donut-11, var(--chart-color-11)); }
|
|
429
465
|
.chart-donut .chart-color-12 { --color: var(--donut-12, var(--chart-color-12)); }
|
|
430
466
|
|
|
431
|
-
.chart-donut .chart-legend-item .legend-label {
|
|
432
|
-
flex: 1;
|
|
433
|
-
}
|
|
434
467
|
|
|
435
468
|
/* ==========================================================================
|
|
436
469
|
Dot Chart (Categorical - columns with dots at Y positions)
|
|
437
470
|
========================================================================== */
|
|
438
471
|
|
|
439
472
|
.chart-dot .chart-body {
|
|
440
|
-
|
|
473
|
+
display: grid;
|
|
474
|
+
grid-template-columns: auto 1fr;
|
|
475
|
+
grid-template-rows: 1fr auto;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.chart-dot .chart-y-axis {
|
|
479
|
+
grid-row: 1;
|
|
480
|
+
grid-column: 1;
|
|
441
481
|
}
|
|
442
482
|
|
|
443
483
|
.chart-dot .chart-scroll {
|
|
444
|
-
|
|
484
|
+
grid-row: 1 / -1;
|
|
485
|
+
grid-column: 2;
|
|
486
|
+
display: grid;
|
|
487
|
+
grid-template-rows: subgrid;
|
|
445
488
|
overflow-x: auto;
|
|
446
489
|
overflow-y: visible;
|
|
447
|
-
position: relative;
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
.chart-dot .chart-scroll::before {
|
|
451
|
-
content: '';
|
|
452
|
-
position: sticky;
|
|
453
|
-
left: 0;
|
|
454
|
-
display: block;
|
|
455
|
-
height: var(--chart-height);
|
|
456
|
-
margin-bottom: calc(-1 * var(--chart-height));
|
|
457
|
-
background: var(--chart-bg);
|
|
458
|
-
border-radius: 3px;
|
|
459
|
-
pointer-events: none;
|
|
460
490
|
}
|
|
461
491
|
|
|
462
492
|
.chart-dot .dot-chart {
|
|
493
|
+
grid-row: 1;
|
|
463
494
|
position: relative;
|
|
464
|
-
height: var(--chart-height);
|
|
495
|
+
min-height: var(--chart-height);
|
|
465
496
|
box-sizing: border-box;
|
|
497
|
+
background: var(--chart-bg);
|
|
498
|
+
border-radius: 3px;
|
|
466
499
|
}
|
|
467
500
|
|
|
468
501
|
/* Inner field sized to content area - dots position relative to this */
|
|
@@ -501,6 +534,7 @@
|
|
|
501
534
|
}
|
|
502
535
|
|
|
503
536
|
.chart-dot .dot-labels {
|
|
537
|
+
grid-row: 2;
|
|
504
538
|
display: flex;
|
|
505
539
|
gap: 6px;
|
|
506
540
|
padding: 0 0.5rem;
|
|
@@ -545,7 +579,8 @@
|
|
|
545
579
|
|
|
546
580
|
.chart-scatter .dot-area {
|
|
547
581
|
position: relative;
|
|
548
|
-
|
|
582
|
+
flex: 1;
|
|
583
|
+
min-height: var(--chart-height);
|
|
549
584
|
background: var(--chart-bg);
|
|
550
585
|
border-radius: 3px;
|
|
551
586
|
box-sizing: border-box;
|
|
@@ -684,13 +719,12 @@
|
|
|
684
719
|
}
|
|
685
720
|
|
|
686
721
|
.chart-animate .donut-ring {
|
|
687
|
-
--_hole-size: calc((var(--chart-donut-size) - var(--chart-donut-thickness) * 2) / 2);
|
|
688
722
|
mask-image:
|
|
689
|
-
radial-gradient(circle at center, transparent var(--
|
|
723
|
+
radial-gradient(circle at center, transparent var(--chart-donut-hole, 30%), black var(--chart-donut-hole, 30%)),
|
|
690
724
|
conic-gradient(from 0deg, black var(--donut-reveal), transparent var(--donut-reveal));
|
|
691
725
|
mask-composite: intersect;
|
|
692
726
|
-webkit-mask-image:
|
|
693
|
-
radial-gradient(circle at center, transparent var(--
|
|
727
|
+
radial-gradient(circle at center, transparent var(--chart-donut-hole, 30%), black var(--chart-donut-hole, 30%)),
|
|
694
728
|
conic-gradient(from 0deg, black var(--donut-reveal), transparent var(--donut-reveal));
|
|
695
729
|
-webkit-mask-composite: source-in;
|
|
696
730
|
animation: donut-clockwise 0.8s ease-out 0.1s forwards;
|
package/package.json
CHANGED
package/src/renderers/donut.js
CHANGED
|
@@ -77,6 +77,9 @@ export function renderDonut(config) {
|
|
|
77
77
|
html += `</figcaption>`;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
// Donut body wrapper (for container queries)
|
|
81
|
+
html += `<div class="donut-body">`;
|
|
82
|
+
|
|
80
83
|
// Donut visual
|
|
81
84
|
html += `<div class="donut-container">`;
|
|
82
85
|
html += `<div class="donut-ring" style="background: ${gradient}"></div>`;
|
|
@@ -117,6 +120,8 @@ export function renderDonut(config) {
|
|
|
117
120
|
});
|
|
118
121
|
html += `</ul>`;
|
|
119
122
|
|
|
123
|
+
html += `</div>`; // Close donut-body
|
|
124
|
+
|
|
120
125
|
html += `</figure>`;
|
|
121
126
|
|
|
122
127
|
return html;
|