Features
Animations, downloads, icons, image generation, and negative values
Animations
Charts support CSS-based animations with staggered reveals. Enable globally or per-chart.
Global Enable
eleventyConfig.addPlugin(uncharted, {
animate: true
});
Per-Chart Override
charts:
# Disable for this chart
static-chart:
type: donut
animate: false
file: charts/data.csv
# Enable for this chart (if global is false)
animated-chart:
type: stacked-bar
animate: true
file: charts/data.csv
Scroll-Triggered Animations
For animations that trigger when scrolled into view, add an Intersection Observer that toggles the .chart-animate class:
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('chart-animate');
}
});
}, { threshold: 0.2 });
document.querySelectorAll('.chart').forEach(chart => {
observer.observe(chart);
});
Download Links
Let users download the source CSV data for any chart.
Setup
Enable globally in plugin options:
eleventyConfig.addPlugin(uncharted, {
downloadData: true, // show download links
dataPassthrough: true, // copy CSV files to output
dataPath: '/data/' // URL path for files
});
This adds a download link below each chart that loads data from a file.
Per-Chart Override
charts:
# Uses global setting
revenue:
type: stacked-bar
file: charts/revenue.csv
# Custom download label
expenses:
type: stacked-column
file: charts/expenses.csv
downloadData: "Download expense report"
# Disable for this chart
internal:
type: donut
file: charts/internal.csv
downloadData: false
Without Passthrough
If dataPassthrough is false, ensure CSV files are available at the expected URLs. The plugin generates links based on dataPath + file:
/data/charts/revenue.csv
Image Download Links
When image generation is enabled, you can also add download links for the generated PNG images:
eleventyConfig.addPlugin(uncharted, {
image: { enabled: true },
downloadImage: true
});
This adds a download link below each chart that has image generation enabled. Like downloadData, you can override per-chart:
charts:
# Uses global setting
hero:
type: stacked-column
file: data.csv
# Custom download label
infographic:
type: donut
file: stats.csv
downloadImage: "Download chart image"
# Disable for this chart
internal:
type: line
file: metrics.csv
downloadImage: false
Negative Values
Stacked column, line, and scatter charts support negative values. When present, a zero axis line appears automatically.
Stacked Columns
Positive values stack upward from zero, negative values stack downward:
quarter,Cost,Profit
Q1,20,10
Q2,25,-10
Q3,15,25
Q4,30,-10
The chart calculates the range from maximum positive stack to minimum negative stack automatically.
Line Charts
Points position above or below the zero line:
month,Change
Jan,5
Feb,-3
Mar,8
Apr,-2
Scatter Charts
Both X and Y axes can display negative values:
charts:
scatter:
type: scatter
x:
min: -100
max: 100
y:
min: -50
max: 50
Manual Scaling with Negatives
Set explicit ranges that include negative values:
charts:
performance:
type: stacked-column
y:
min: -50
max: 100
file: charts/performance.csv
Or using global defaults:
charts:
performance:
type: stacked-column
min: -50
max: 100
file: charts/performance.csv
The zero line positions proportionally between min and max.
Icon Support
Line, time-series, and scatter charts can display Font Awesome icons instead of default circular dots. Icons inherit series colors automatically.
Prerequisites
Include Font Awesome in your site:
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/7.0.1/css/all.min.css">
Single Icon for All Series
Use a string to apply the same icon to all data points:
charts:
stars:
type: line
file: data.csv
icons: "fa-solid fa-star"
Per-Series Icons
Use an object to assign different icons to each series:
charts:
development:
type: line
file: adoption.csv
y:
columns:
prs: Pull Requests
commits: Commits
icons:
prs: "fa-solid fa-code-merge"
commits: "fa-solid fa-code-commit"
Scatter Charts
For scatter charts, icons are keyed by series value:
charts:
metrics:
type: scatter
file: data.csv
series:
column: group
icons:
alpha: "fa-solid fa-circle"
beta: "fa-solid fa-square"
Icons also appear in the legend, replacing the default colored dot marker.
Image Generation Beta
Generate PNG images of charts for use in RSS feeds, social sharing, or fallback content. Images are rendered using Puppeteer during the build process.
Note: This feature requires v1.0.0-beta.1 or later. The cacheDir option requires v1.0.0-beta.3.
Prerequisites
Install Puppeteer as a peer dependency:
npm install puppeteer
Plugin Configuration
Enable image generation globally:
eleventyConfig.addPlugin(uncharted, {
image: {
enabled: true,
outputDir: '/images/charts/', // URL path for images
cacheDir: 'images/charts/', // source directory for cached images
width: 800, // default width in pixels
height: 400, // default height in pixels
scale: 2, // device scale (2 for retina)
background: '#ffffff', // background color
skipDev: true // skip during --serve/--watch
}
});
When enabled, charts automatically include data-chart-image and data-chart-alt attributes for use with the chartToImage filter.
Per-Chart Configuration
Override global settings for individual charts:
charts:
hero-chart:
type: stacked-column
file: data.csv
alt: "Quarterly revenue showing growth trend"
image:
enabled: true
width: 1200
height: 600
The alt option sets the chart's aria-label for accessibility. It's also used as image alt text when image generation is enabled. If not specified, the chart title or ID is used.
Some chart types (such as stacked bars and Sankey diagrams) may need larger width or height values to be fully visible in the generated image.
Getting Image URLs
Use the chartImageUrl shortcode to get the root-relative URL of a chart's generated image:
{% chartImageUrl "hero-chart" %}
<!-- outputs: /images/charts/hero-chart.png -->
For absolute URLs (required for Open Graph), prepend your site URL:
<meta property="og:image" content="{{ site.url }}{% chartImageUrl "hero-chart" %}">
RSS Feeds
Use the chartToImage filter to replace chart HTML with <img> tags in feed content:
{{ post.content | chartToImage }}
For absolute URLs in feeds, pass a base URL:
{{ post.content | chartToImage: "https://example.com" }}
This replaces any chart <figure> elements that have image data with simple <img> tags, which work in RSS readers that don't support complex HTML/CSS.
Caching for Vercel and Other Hosts
Puppeteer requires Chromium, which doesn't work in some build environments like Vercel. Use the cacheDir option to cache generated images in your repository.
When cacheDir is set:
- Images are written to the cache directory (e.g.,
images/charts/) - Passthrough copies cached images to the output
- If Puppeteer is unavailable, cached images are used silently
Generate images locally or in a CI step (like GitHub Actions) that has Puppeteer, then commit them. On Vercel (or any host without Puppeteer), the cached images are used automatically.
Accessibility
Charts are rendered as <figure> elements with proper semantic structure:
<figcaption>contains the title and subtitle- Chart data is represented in HTML, not canvas
- Legend items are readable by screen readers
Use the alt option to add an accessible description to a chart:
charts:
sales:
type: stacked-column
file: sales.csv
alt: "Quarterly sales showing 25% growth year over year"
This sets aria-label on the chart's <figure> element. If not specified, the chart title or ID is used as a fallback.
For additional accessibility, consider:
- Providing a data table alternative for complex charts
- Ensuring sufficient color contrast in custom palettes