TerraFluent.Chart.Reporting
2.1.0
Prefix Reserved
dotnet add package TerraFluent.Chart.Reporting --version 2.1.0
NuGet\Install-Package TerraFluent.Chart.Reporting -Version 2.1.0
<PackageReference Include="TerraFluent.Chart.Reporting" Version="2.1.0" />
<PackageVersion Include="TerraFluent.Chart.Reporting" Version="2.1.0" />
<PackageReference Include="TerraFluent.Chart.Reporting" />
paket add TerraFluent.Chart.Reporting --version 2.1.0
#r "nuget: TerraFluent.Chart.Reporting, 2.1.0"
#:package TerraFluent.Chart.Reporting@2.1.0
#addin nuget:?package=TerraFluent.Chart.Reporting&version=2.1.0
#tool nuget:?package=TerraFluent.Chart.Reporting&version=2.1.0
TerraFluent.Chart.Reporting
A fluent C# library for generating SVG charts server-side — zero JavaScript dependency, zero external NuGet dependencies.
- Zero dependencies — pure Base Class Library, nothing added to your dependency graph.
- Zero JavaScript required — Static and Animated modes are pure SVG, CSS, and SMIL.
- 26 chart types — line, bar, pie, financial, flow, and specialist types, all through one fluent API.
- Three render modes — Static (PDF/email-safe), Animated (SMIL), Interactive (JS, browser-only).
- 18 built-in themes plus a
ChartTheme.Custom(...)factory for fully custom palettes. - Readable by default — collision-free data labels, width-aware axis-label thinning, and a 10px minimum text size.
- Multi-target —
netstandard2.0,netstandard2.1,net6.0,net8.0,net10.0from one codebase.
What's New in 2.1
- Multi-colour bars:
ColorByPoint()gives every column or bar its own colour, from the theme palette or your own list. - Collision-aware data labels: labels steer clear of each other, of lines and of markers. Bar labels slide within their segment; line labels move above, below or beside their point.
- Cleaner bars: bars are at most 64px thick, and rounded corners sit only on the free end. In a stack, only the outermost segment is rounded.
- More readable text: 12px axis labels, 13px axis titles and 11px data labels, never below 10px. Date-axis labels are thinned by width, so long formats such as
dd-MMM-yyyydon't overlap. - Fixed: the left Y-axis now matches the bars on charts with a secondary axis or stacking.
- Faster: dense labelled charts render up to 60× faster, with far less memory.
2.1 adds API without breaking any, but default visuals change. See the Changelog for details.
Table of Contents
- What's New in 2.1
- Supported Targets
- Installation
- Quick Start
- Documentation
- AI Agent Skill
- Chart Types
- Render Modes
- Themes
- Pie / Donut Chart
- Axis Shortcuts
- Markers
- Tooltip Customisation
- Legend Position Shortcuts
- Fork — Chart Variants
- Dependency Injection
- Async Rendering
- Input Validation
- Building from Source
- License
Supported Targets
| Framework | Version |
|---|---|
| .NET Standard | 2.0, 2.1 |
| .NET | 6.0, 8.0, 10.0 |
Installation
Via NuGet:
dotnet add package TerraFluent.Chart.Reporting
Via project reference (building from source):
<ItemGroup>
<ProjectReference Include="..\src\TerraFluent.Chart.Reporting\TerraFluent.Chart.Reporting.csproj" />
</ItemGroup>
Quick Start
string svg = ChartBuilder.Create()
.Title("Monthly Revenue")
.Size(700, 400)
.XAxis("Month", "Jan", "Feb", "Mar", "Apr", "May", "Jun")
.YAxis("Revenue ($)", min: 0)
.Series(s => s.AddLine("2024", new double[] { 120, 145, 110, 190, 170, 210 }))
.RenderToSvg();
Documentation
The full guide lives in docs/:
| Guide | What it covers |
|---|---|
| Getting Started | Install, first chart, ASP.NET Core / Blazor integration |
| Chart Showcase | Live visual gallery of every chart type and feature |
| Chart Types | All 26 chart types with full code + SVG output |
| Themes & Styling | Built-in themes, modern styling, custom themes, colour catalogue |
| Advanced Features | Render modes, output methods, axes, stacking, Fork, DI |
| API Reference | Complete method reference for every builder, enum, and data type |
| Troubleshooting & FAQ | Common issues, exceptions, and integration answers |
| Changelog | What changed in each release |
AI Agent Skill
skills/terrafluent-chart/ is an Agent Skill that teaches coding agents (Claude Code, GitHub Copilot, and other agents that support SKILL.md) to turn a prompt such as "make a donut chart of revenue by region for our PDF report" into working TerraFluent code, and then check the SVG it produces.
The skill includes:
SKILL.md: the workflow the agent follows: extract a chart spec from the prompt, choose the chart type, choose the render mode, write the code, and verify the result.references/: a guide for mapping prompts to chart types, an API cheatsheet checked against the source, recipes for console, ASP.NET Core, Blazor, HTML report, email, and DI, and a list of common mistakes.scripts/check-svg.cs: a validator with no dependencies (dotnet run --file …, .NET 10 SDK). It checks that the SVG is well-formed, that the chart is not empty, and that the output is safe for the render mode.
To install it, copy the folder into your agent's skills directory:
# Claude Code (this project only, or ~/.claude/skills/ for all projects)
cp -r skills/terrafluent-chart <your-repo>/.claude/skills/
# GitHub Copilot
cp -r skills/terrafluent-chart <your-repo>/.github/skills/
For other agents, see their documentation for where skills go. Agents load the skill automatically when a request mentions charts or graphs in a .NET project.
Chart Types
26 chart types are supported. See the Chart Types guide for full examples.
| Type | Method | Type | Method |
|---|---|---|---|
| Line | AddLine |
Bubble | AddBubble |
| Spline | AddSpline |
Heatmap | AddHeatmap |
| Area | AddArea |
ColumnRange | AddColumnRange |
| Column | AddColumn |
AreaRange | AddAreaRange |
| Bar | AddBar |
Funnel | AddFunnel |
| Pie / Donut | AddPie |
Treemap | AddTreemap |
| Scatter | AddScatter |
Radar | AddRadar |
| Waterfall | AddWaterfall |
BoxPlot | AddBoxPlot |
| Gauge | AddGauge |
ErrorBar | AddErrorBar |
| DataRing | AddDataRing |
Candlestick | AddCandlestick |
| Dumbbell | AddDumbbell |
OHLC | AddOhlc |
| Stream | AddStream |
Gantt | AddGantt |
| Sankey | AddSankey |
Parliament | AddParliament |
Multi-Colour Bars
Give every column or bar its own colour:
.Series(s => s.AddColumn("Sales", data, cfg => cfg.ColorByPoint())) // theme palette
.Series(s => s.AddBar("Sales", data, cfg => cfg.ColorByPoint("#0EA5E9", "#22C55E", "#F59E0B"))) // custom, cycled
See Multi-Colour Bars.
Render Modes
| Mode | CSS Hover | JS | Safe for |
|---|---|---|---|
Static |
No | No | PDF, email |
Animated (default) |
Yes | No | Browser, Blazor |
Interactive |
Yes | Yes | Browser only |
Themes
18 built-in themes are included — Default, Dark, Pastel, Monochrome, Ocean, Sunset, Forest, Neon, Minimal, Warm, Arctic, Business, Material, TrafficLight, Accessible, Vivid, HighContrast, and Modern. See Themes & Styling for the full catalogue.
// Built-in themes
.Theme(ChartTheme.Dark)
.Theme(ChartTheme.Pastel)
.Theme(ChartTheme.Monochrome)
.Theme(ChartTheme.Default)
// Custom theme — all parameters optional
.Theme(ChartTheme.Custom(
backgroundColor: "#1e1e2e",
plotBackgroundColor: "#2a2a3d",
textColor: "#cdd6f4",
fontFamily: "JetBrains Mono",
colors: new[] { "#89b4fa", "#a6e3a1", "#fab387" }))
// Ad-hoc palette
.Colors("#e63946", "#457b9d", "#2a9d8f")
Every theme ships with ModernStyle on — rounded bar ends, gradient fills, hollow-ring markers, and (in Interactive mode) hover bands. Clone a theme and set ModernStyle = false for the classic flat look; see Modern Styling.
Pie / Donut Chart
string svg = ChartBuilder.Create()
.Title("Browser Share")
.AsPie()
.Labels("Chrome", "Safari", "Edge", "Firefox")
.Series(s => s
.Add("Shares", new double[] { 61, 25, 9, 5 }, cfg =>
{
cfg.DonutHole(0.5); // hole radius as a fraction (0–1)
cfg.DonutCenter.Show().Title("Browsers"); // caption above the auto total
}))
.RenderToSvg();
Axis Shortcuts
.XAxisFormat("{value} kg") // label format string
.XAxisTickInterval(5) // tick interval in data units (> 0)
.YAxisTickInterval(10)
Markers
.Series(s => s.AddLine("Sales", data, cfg => cfg
.MarkerSize(6) // radius in px (default 4-5)
.MarkerEnabled(false) // hide dots entirely
))
Tooltip Customisation
.Tooltip(t => t
.HeaderFormat("Week: {label}")
.PointFormat("Value: {value}"))
Legend Position Shortcuts
.Legend(l => l.TopLeft())
.Legend(l => l.TopCenter())
.Legend(l => l.TopRight())
.Legend(l => l.BottomLeft())
.Legend(l => l.BottomCenter())
.Legend(l => l.BottomRight())
Fork — Chart Variants
Create a deep copy of a builder to produce related charts without mutation:
var baseChart = ChartBuilder.Create()
.Title("Revenue")
.Size(700, 400)
.Series(s => s.AddLine("2024", data));
var darkVariant = baseChart.Fork()
.Theme(ChartTheme.Dark);
string lightSvg = baseChart.RenderToSvg();
string darkSvg = darkVariant.RenderToSvg();
Dependency Injection (IChartBuilder)
// Register
services.AddTransient<IChartBuilder>(_ => ChartBuilder.Create());
// Use
public class ReportService(IChartBuilder chart)
{
public string Build() => chart
.Title("Revenue")
.Series(s => s.AddLine("2024", data))
.RenderToSvg();
}
Async Rendering
// .NET 6+
await chart.RenderToFileAsync("report.svg");
await chart.RenderToStreamAsync(responseStream);
Input Validation
| Scenario | Exception |
|---|---|
Size(0, 400) |
ArgumentOutOfRangeException |
YAxis("Y", min: 100, max: 50) |
ArgumentException |
Animate(0) |
ArgumentOutOfRangeException |
FillOpacity(1.5) |
ArgumentOutOfRangeException |
MarkerSize(0) |
ArgumentOutOfRangeException |
XAxisFormat(" ") |
ArgumentException |
ChartTheme.Custom(colors: []) |
ArgumentException |
RenderToFile with missing directory |
DirectoryNotFoundException |
Building from Source
git clone https://github.com/sahebansari/TerraFluent.Chart.Reporting.git
cd TerraFluent.Chart.Reporting
dotnet build TerraFluent.Chart.Reporting.sln
dotnet test tests/TerraFluent.Chart.Reporting.Tests/TerraFluent.Chart.Reporting.Tests.csproj
The library targets netstandard2.0, netstandard2.1, net6.0, net8.0, and net10.0 from a single project — building it requires the .NET 10 SDK (which includes the earlier runtimes needed to build the older targets).
Benchmarks
Rendering performance is tracked in tests/TerraFluent.Chart.Reporting.Benchmarks:
# Quick before/after check (seconds)
dotnet run -c Release --project tests/TerraFluent.Chart.Reporting.Benchmarks -- quick
# Full BenchmarkDotNet run (minutes) — pick a suite, or pass --filter
dotnet run -c Release --project tests/TerraFluent.Chart.Reporting.Benchmarks
License
Released under the MIT License — free for commercial and personal use, modification, and redistribution. See LICENSE for the full text.
Project website: terrafluent.dev/chart
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- No dependencies.
-
.NETStandard 2.1
- No dependencies.
-
net10.0
- No dependencies.
-
net6.0
- No dependencies.
-
net8.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
2.1.0 — Multi-colour bars (ColorByPoint), collision-aware data labels, 64px bar thickness cap, rounded corners on the free bar end only, larger default text with a 10px minimum, width-aware date-axis label thinning. Fixes left Y-axis range with a secondary axis or stacking. Up to 60× faster rendering of dense labelled charts. Full notes: https://github.com/sahebansari/TerraFluent.Chart.Reporting/blob/master/CHANGELOG.md