eleventy-plugin-uncharted 0.2.1 → 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 +11 -2
- package/css/uncharted.css +105 -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,50 @@
|
|
|
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
|
+
justify-content: center;
|
|
367
|
+
gap: 1rem;
|
|
368
|
+
flex: 1;
|
|
356
369
|
}
|
|
357
370
|
|
|
358
371
|
.chart-donut .donut-container {
|
|
359
372
|
position: relative;
|
|
360
373
|
display: flex;
|
|
361
374
|
justify-content: center;
|
|
375
|
+
/* Size based on container width, clamped */
|
|
376
|
+
width: clamp(8rem, 80cqi, var(--chart-donut-size));
|
|
377
|
+
aspect-ratio: 1;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/* In portrait, legend takes full width to wrap below */
|
|
381
|
+
.chart-donut .donut-body > .chart-legend {
|
|
382
|
+
flex: 0 0 100%;
|
|
383
|
+
justify-content: center;
|
|
362
384
|
}
|
|
363
385
|
|
|
364
386
|
.chart-donut .donut-ring {
|
|
365
|
-
width:
|
|
366
|
-
height:
|
|
387
|
+
width: 100%;
|
|
388
|
+
height: 100%;
|
|
367
389
|
border-radius: 50%;
|
|
368
390
|
display: flex;
|
|
369
391
|
align-items: center;
|
|
370
392
|
justify-content: center;
|
|
371
393
|
/* Radial mask punches out the center hole */
|
|
372
|
-
--_hole-size: calc((var(--chart-donut-size) - var(--chart-donut-thickness) * 2) / 2);
|
|
373
394
|
mask-image: radial-gradient(
|
|
374
395
|
circle at center,
|
|
375
|
-
transparent var(--
|
|
376
|
-
black var(--
|
|
396
|
+
transparent var(--chart-donut-hole, 30%),
|
|
397
|
+
black var(--chart-donut-hole, 30%)
|
|
377
398
|
);
|
|
378
399
|
-webkit-mask-image: radial-gradient(
|
|
379
400
|
circle at center,
|
|
380
|
-
transparent var(--
|
|
381
|
-
black var(--
|
|
401
|
+
transparent var(--chart-donut-hole, 30%),
|
|
402
|
+
black var(--chart-donut-hole, 30%)
|
|
382
403
|
);
|
|
383
404
|
}
|
|
384
405
|
|
|
@@ -406,12 +427,30 @@
|
|
|
406
427
|
}
|
|
407
428
|
|
|
408
429
|
.chart-donut .chart-legend {
|
|
409
|
-
|
|
410
|
-
|
|
430
|
+
/* Default (portrait): horizontal legend below donut */
|
|
431
|
+
flex-direction: row;
|
|
432
|
+
flex-wrap: wrap;
|
|
433
|
+
justify-content: center;
|
|
434
|
+
gap: 0.5rem 1rem;
|
|
411
435
|
}
|
|
412
436
|
|
|
413
437
|
.chart-donut .chart-legend-item {
|
|
414
|
-
min-width:
|
|
438
|
+
min-width: 8rem;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/* Wide container: row layout with legend beside donut */
|
|
442
|
+
@container donut (min-width: 24rem) {
|
|
443
|
+
.donut-container,
|
|
444
|
+
.chart-legend {
|
|
445
|
+
flex: 0 0 auto;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
.chart-legend {
|
|
449
|
+
flex-direction: column;
|
|
450
|
+
flex-wrap: nowrap;
|
|
451
|
+
justify-content: center;
|
|
452
|
+
gap: 0.5rem;
|
|
453
|
+
}
|
|
415
454
|
}
|
|
416
455
|
|
|
417
456
|
/* Donut legend uses same variables as gradient for consistent overrides */
|
|
@@ -428,41 +467,38 @@
|
|
|
428
467
|
.chart-donut .chart-color-11 { --color: var(--donut-11, var(--chart-color-11)); }
|
|
429
468
|
.chart-donut .chart-color-12 { --color: var(--donut-12, var(--chart-color-12)); }
|
|
430
469
|
|
|
431
|
-
.chart-donut .chart-legend-item .legend-label {
|
|
432
|
-
flex: 1;
|
|
433
|
-
}
|
|
434
470
|
|
|
435
471
|
/* ==========================================================================
|
|
436
472
|
Dot Chart (Categorical - columns with dots at Y positions)
|
|
437
473
|
========================================================================== */
|
|
438
474
|
|
|
439
475
|
.chart-dot .chart-body {
|
|
440
|
-
|
|
476
|
+
display: grid;
|
|
477
|
+
grid-template-columns: auto 1fr;
|
|
478
|
+
grid-template-rows: 1fr auto;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
.chart-dot .chart-y-axis {
|
|
482
|
+
grid-row: 1;
|
|
483
|
+
grid-column: 1;
|
|
441
484
|
}
|
|
442
485
|
|
|
443
486
|
.chart-dot .chart-scroll {
|
|
444
|
-
|
|
487
|
+
grid-row: 1 / -1;
|
|
488
|
+
grid-column: 2;
|
|
489
|
+
display: grid;
|
|
490
|
+
grid-template-rows: subgrid;
|
|
445
491
|
overflow-x: auto;
|
|
446
492
|
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
493
|
}
|
|
461
494
|
|
|
462
495
|
.chart-dot .dot-chart {
|
|
496
|
+
grid-row: 1;
|
|
463
497
|
position: relative;
|
|
464
|
-
height: var(--chart-height);
|
|
498
|
+
min-height: var(--chart-height);
|
|
465
499
|
box-sizing: border-box;
|
|
500
|
+
background: var(--chart-bg);
|
|
501
|
+
border-radius: 3px;
|
|
466
502
|
}
|
|
467
503
|
|
|
468
504
|
/* Inner field sized to content area - dots position relative to this */
|
|
@@ -501,6 +537,7 @@
|
|
|
501
537
|
}
|
|
502
538
|
|
|
503
539
|
.chart-dot .dot-labels {
|
|
540
|
+
grid-row: 2;
|
|
504
541
|
display: flex;
|
|
505
542
|
gap: 6px;
|
|
506
543
|
padding: 0 0.5rem;
|
|
@@ -545,7 +582,8 @@
|
|
|
545
582
|
|
|
546
583
|
.chart-scatter .dot-area {
|
|
547
584
|
position: relative;
|
|
548
|
-
|
|
585
|
+
flex: 1;
|
|
586
|
+
min-height: var(--chart-height);
|
|
549
587
|
background: var(--chart-bg);
|
|
550
588
|
border-radius: 3px;
|
|
551
589
|
box-sizing: border-box;
|
|
@@ -684,13 +722,12 @@
|
|
|
684
722
|
}
|
|
685
723
|
|
|
686
724
|
.chart-animate .donut-ring {
|
|
687
|
-
--_hole-size: calc((var(--chart-donut-size) - var(--chart-donut-thickness) * 2) / 2);
|
|
688
725
|
mask-image:
|
|
689
|
-
radial-gradient(circle at center, transparent var(--
|
|
726
|
+
radial-gradient(circle at center, transparent var(--chart-donut-hole, 30%), black var(--chart-donut-hole, 30%)),
|
|
690
727
|
conic-gradient(from 0deg, black var(--donut-reveal), transparent var(--donut-reveal));
|
|
691
728
|
mask-composite: intersect;
|
|
692
729
|
-webkit-mask-image:
|
|
693
|
-
radial-gradient(circle at center, transparent var(--
|
|
730
|
+
radial-gradient(circle at center, transparent var(--chart-donut-hole, 30%), black var(--chart-donut-hole, 30%)),
|
|
694
731
|
conic-gradient(from 0deg, black var(--donut-reveal), transparent var(--donut-reveal));
|
|
695
732
|
-webkit-mask-composite: source-in;
|
|
696
733
|
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;
|