eleventy-plugin-uncharted 0.1.1 → 0.1.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Uncharted
2
2
 
3
- A CSS-based charting plugin for Eleventy. Renders charts as pure HTML/CSS with no JavaScript dependencies.
3
+ A CSS-based chart plugin for Eleventy. Renders charts as pure HTML/CSS with no JavaScript dependencies.
4
4
 
5
5
  ## Installation
6
6
 
@@ -110,10 +110,10 @@ charts:
110
110
 
111
111
  ## CSV Format
112
112
 
113
- CSV files use the first column as labels and subsequent columns as data series:
113
+ CSV files use the first column as labels and subsequent columns as data series. The column names can be anything descriptive:
114
114
 
115
115
  ```csv
116
- label,existing,new
116
+ department,existing,new
117
117
  Finance,11,11
118
118
  Sales,16,2
119
119
  Core,8,0
@@ -135,7 +135,7 @@ Stacked column, dot, and scatter charts support negative values. When negative v
135
135
  For stacked columns, positive values stack upward from zero and negative values stack downward:
136
136
 
137
137
  ```csv
138
- label,Cost,Profit
138
+ quarter,Cost,Profit
139
139
  Q1,20,10
140
140
  Q2,25,-10
141
141
  Q3,15,25
package/css/uncharted.css CHANGED
@@ -201,6 +201,7 @@
201
201
  height: 100%;
202
202
  width: var(--value);
203
203
  transition: width 0.3s ease;
204
+ background-color: var(--color);
204
205
  }
205
206
 
206
207
  .chart-stacked-bar .bar-value {
@@ -243,6 +244,7 @@
243
244
  width: 100%;
244
245
  height: var(--value);
245
246
  transition: height 0.3s ease;
247
+ background-color: var(--color);
246
248
  }
247
249
 
248
250
  .chart-stacked-column .column-labels {
@@ -381,6 +383,7 @@
381
383
  bottom: var(--value);
382
384
  transform: translate(-50%, 50%);
383
385
  cursor: default;
386
+ background-color: var(--color);
384
387
  }
385
388
 
386
389
  .chart-dot .dot[title]:hover {
@@ -443,6 +446,7 @@
443
446
  bottom: var(--value);
444
447
  transform: translate(-50%, 50%);
445
448
  cursor: default;
449
+ background-color: var(--color);
446
450
  }
447
451
 
448
452
  .chart-scatter .dot[title]:hover {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eleventy-plugin-uncharted",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
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",
package/src/index.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { renderers } from './renderers/index.js';
2
2
  export { loadCSV, parseCSV } from './csv.js';
3
- export { slugify, calculatePercentages, getSeriesNames, escapeHtml } from './utils.js';
3
+ export { slugify, calculatePercentages, getLabelKey, getValueKey, getSeriesNames, escapeHtml } from './utils.js';
@@ -1,4 +1,4 @@
1
- import { slugify, escapeHtml } from '../utils.js';
1
+ import { slugify, escapeHtml, getLabelKey, getValueKey, getSeriesNames } from '../utils.js';
2
2
 
3
3
  /**
4
4
  * Render a donut/pie chart using conic-gradient
@@ -22,18 +22,22 @@ export function renderDonut(config) {
22
22
 
23
23
  const animateClass = animate ? ' chart-animate' : '';
24
24
 
25
- // Extract values - support both {label, value} format and series format
25
+ // Get column keys positionally
26
+ const labelKey = getLabelKey(data);
27
+ const valueKey = getValueKey(data);
28
+ const seriesKeys = getSeriesNames(data);
29
+
30
+ // Extract values - support both label/value format and series format
26
31
  let segments = [];
27
- if (data[0].value !== undefined) {
28
- // Direct {label, value} format
32
+ if (seriesKeys.length === 1) {
33
+ // Two columns: first is label, second is value (multiple rows)
29
34
  segments = data.map(item => ({
30
- label: item.label,
31
- value: typeof item.value === 'number' ? item.value : parseFloat(item.value) || 0
35
+ label: item[labelKey],
36
+ value: typeof item[valueKey] === 'number' ? item[valueKey] : parseFloat(item[valueKey]) || 0
32
37
  }));
33
38
  } else {
34
- // Series format - first row only for donut
35
- const seriesNames = Object.keys(data[0]).filter(k => k !== 'label');
36
- segments = seriesNames.map(name => ({
39
+ // Series format - first row only, columns after the first are series
40
+ segments = seriesKeys.map(name => ({
37
41
  label: name,
38
42
  value: typeof data[0][name] === 'number' ? data[0][name] : parseFloat(data[0][name]) || 0
39
43
  }));
@@ -1,4 +1,4 @@
1
- import { slugify, escapeHtml, getSeriesNames } from '../utils.js';
1
+ import { slugify, escapeHtml, getLabelKey, getSeriesNames } from '../utils.js';
2
2
 
3
3
  /**
4
4
  * Render a categorical dot chart (columns with dots at different Y positions)
@@ -20,7 +20,8 @@ export function renderDot(config) {
20
20
  return `<!-- Dot chart: no data provided -->`;
21
21
  }
22
22
 
23
- // Get series keys from data columns (excluding 'label')
23
+ // Get label key (first column) and series keys (remaining columns)
24
+ const labelKey = getLabelKey(data);
24
25
  const seriesKeys = getSeriesNames(data);
25
26
  const legendLabels = legend ?? seriesKeys;
26
27
  const animateClass = animate ? ' chart-animate' : '';
@@ -82,7 +83,7 @@ export function renderDot(config) {
82
83
 
83
84
  // Each row becomes a column with dots for each series
84
85
  data.forEach(row => {
85
- const label = row.label ?? '';
86
+ const label = row[labelKey] ?? '';
86
87
 
87
88
  html += `<div class="dot-col">`;
88
89
 
@@ -110,7 +111,7 @@ export function renderDot(config) {
110
111
  // X-axis labels
111
112
  html += `<div class="dot-labels">`;
112
113
  data.forEach(row => {
113
- const label = row.label ?? '';
114
+ const label = row[labelKey] ?? '';
114
115
  html += `<span class="dot-label">${escapeHtml(label)}</span>`;
115
116
  });
116
117
  html += `</div>`;
@@ -1,4 +1,4 @@
1
- import { slugify, calculatePercentages, getSeriesNames, escapeHtml } from '../utils.js';
1
+ import { slugify, calculatePercentages, getLabelKey, getSeriesNames, escapeHtml } from '../utils.js';
2
2
 
3
3
  /**
4
4
  * Render a stacked bar chart (horizontal)
@@ -18,7 +18,8 @@ export function renderStackedBar(config) {
18
18
  return `<!-- Stacked bar chart: no data provided -->`;
19
19
  }
20
20
 
21
- // Get actual data keys from the first row (excluding 'label')
21
+ // Get label key (first column) and series keys (remaining columns)
22
+ const labelKey = getLabelKey(data);
22
23
  const seriesKeys = getSeriesNames(data);
23
24
  // Use legend for display labels, fall back to data keys
24
25
  const legendLabels = legend ?? seriesKeys;
@@ -49,7 +50,7 @@ export function renderStackedBar(config) {
49
50
  html += `<div class="chart-bars">`;
50
51
 
51
52
  data.forEach(row => {
52
- const label = row.label ?? '';
53
+ const label = row[labelKey] ?? '';
53
54
  const values = seriesKeys.map(key => {
54
55
  const val = row[key];
55
56
  return typeof val === 'number' ? val : parseFloat(val) || 0;
@@ -1,4 +1,4 @@
1
- import { slugify, getSeriesNames, escapeHtml } from '../utils.js';
1
+ import { slugify, getLabelKey, getSeriesNames, escapeHtml } from '../utils.js';
2
2
 
3
3
  /**
4
4
  * Render a stacked column chart (vertical)
@@ -19,7 +19,8 @@ export function renderStackedColumn(config) {
19
19
  return `<!-- Stacked column chart: no data provided -->`;
20
20
  }
21
21
 
22
- // Get actual data keys from the first row (excluding 'label')
22
+ // Get label key (first column) and series keys (remaining columns)
23
+ const labelKey = getLabelKey(data);
23
24
  const seriesKeys = getSeriesNames(data);
24
25
  // Use legend for display labels, fall back to data keys
25
26
  const legendLabels = legend ?? seriesKeys;
@@ -90,7 +91,7 @@ export function renderStackedColumn(config) {
90
91
  html += `<div class="chart-columns"${columnsStyle}>`;
91
92
 
92
93
  data.forEach(row => {
93
- const label = row.label ?? '';
94
+ const label = row[labelKey] ?? '';
94
95
  html += `<div class="column-track" title="${escapeHtml(label)}">`;
95
96
 
96
97
  if (hasNegativeY) {
@@ -173,7 +174,7 @@ export function renderStackedColumn(config) {
173
174
  // X-axis labels
174
175
  html += `<div class="column-labels">`;
175
176
  data.forEach(row => {
176
- const label = row.label ?? '';
177
+ const label = row[labelKey] ?? '';
177
178
  html += `<span class="column-label">${escapeHtml(label)}</span>`;
178
179
  });
179
180
  html += `</div>`;
package/src/utils.js CHANGED
@@ -25,13 +25,33 @@ export function calculatePercentages(values, max) {
25
25
  }
26
26
 
27
27
  /**
28
- * Extract series names from CSV data (all columns except 'label')
28
+ * Get the label key (first column name) from CSV data
29
+ * @param {Object[]} data - Array of data objects
30
+ * @returns {string|undefined} - The first column name, or undefined if no data
31
+ */
32
+ export function getLabelKey(data) {
33
+ if (!data || data.length === 0) return undefined;
34
+ return Object.keys(data[0])[0];
35
+ }
36
+
37
+ /**
38
+ * Get the value key (second column name) from CSV data
39
+ * @param {Object[]} data - Array of data objects
40
+ * @returns {string|undefined} - The second column name, or undefined if no data
41
+ */
42
+ export function getValueKey(data) {
43
+ if (!data || data.length === 0) return undefined;
44
+ return Object.keys(data[0])[1];
45
+ }
46
+
47
+ /**
48
+ * Extract series names from CSV data (all columns except the first)
29
49
  * @param {Object[]} data - Array of data objects
30
50
  * @returns {string[]} - Array of series names
31
51
  */
32
52
  export function getSeriesNames(data) {
33
53
  if (!data || data.length === 0) return [];
34
- return Object.keys(data[0]).filter(key => key !== 'label');
54
+ return Object.keys(data[0]).slice(1);
35
55
  }
36
56
 
37
57
  /**