ChartForgeX.Markup
0.1.3
dotnet add package ChartForgeX.Markup --version 0.1.3
NuGet\Install-Package ChartForgeX.Markup -Version 0.1.3
<PackageReference Include="ChartForgeX.Markup" Version="0.1.3" />
<PackageVersion Include="ChartForgeX.Markup" Version="0.1.3" />
<PackageReference Include="ChartForgeX.Markup" />
paket add ChartForgeX.Markup --version 0.1.3
#r "nuget: ChartForgeX.Markup, 0.1.3"
#:package ChartForgeX.Markup@0.1.3
#addin nuget:?package=ChartForgeX.Markup&version=0.1.3
#tool nuget:?package=ChartForgeX.Markup&version=0.1.3
ChartForgeX - Dependency-Free Chart Rendering for .NET
ChartForgeX renders polished charts, visual blocks, topology diagrams, and static report visuals from .NET without adding runtime chart dependencies to generated output.
NuGet Package
Project Information
Author & Social
What It Does
ChartForgeX turns .NET data into deterministic static visuals: charts, chart grids, visual blocks, visual canvases, topology diagrams, and map-backed report graphics. It is meant for generated reports, documentation, email, static websites, dashboards, wallpapers, social preview images, Office-style generators, and other hosts that need polished output without a JavaScript chart dependency.
The core package renders SVG, script-free static HTML, PNG, BMP, PPM, and TIFF without runtime package dependencies. Optional browser behavior lives in adapter packages, so a static report can stay static while a dashboard can opt into tooltips, selection, zoom, pan, brush ranges, synchronized charts, and export controls.
Visual Tour
These are generated artifacts from ChartForgeX.Examples, checked into the project site assets beside their matching HTML, SVG, PNG, and source snippets. HTML links open through the Evotec preview service so readers see the rendered page instead of GitHub's source view; SVG and PNG links stay pointed at the checked-in artifacts.
<table> <tr> <td width="50%"> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/dashboard-restaurant-overview-grid.html"> <img src="Website/static/examples/generated/dashboard-restaurant-overview-grid.png" alt="Restaurant operations dashboard generated by ChartForgeX" width="100%" /> </a> <br /> <strong>Dashboard composition</strong> <br /> KPI cards, sparklines, occupancy blocks, hexbin summaries, and status panels in one static report surface. <br /> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/dashboard-restaurant-overview-grid.html">HTML</a> / <a href="Website/static/examples/generated/dashboard-restaurant-overview-grid.svg">SVG</a> / <a href="Website/static/examples/generated/dashboard-restaurant-overview-grid.png">PNG</a> </td> <td width="50%"> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/visual-geographic-topology-map.html"> <img src="Website/static/examples/generated/visual-geographic-topology-map.png" alt="Geographic topology map generated by ChartForgeX" width="100%" /> </a> <br /> <strong>Topology and geography</strong> <br /> Product-neutral topology models with map projection, route arcs, callouts, legends, and SVG metadata hooks. <br /> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/visual-geographic-topology-map.html">HTML</a> / <a href="Website/static/examples/generated/visual-geographic-topology-map.svg">SVG</a> / <a href="Website/static/examples/generated/visual-geographic-topology-map.png">PNG</a> </td> </tr> <tr> <td width="50%"> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/dashboard-saas-mrr-grid.html"> <img src="Website/static/examples/generated/dashboard-saas-mrr-grid.png" alt="SaaS MRR dashboard grid generated by ChartForgeX" width="100%" /> </a> <br /> <strong>Operational dashboard grids</strong> <br /> Trend cards, driver summaries, waterfall bars, line charts, and metric panels in a reusable grid model. <br /> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/dashboard-saas-mrr-grid.html">HTML</a> / <a href="Website/static/examples/generated/dashboard-saas-mrr-grid.svg">SVG</a> / <a href="Website/static/examples/generated/dashboard-saas-mrr-grid.png">PNG</a> </td> <td width="50%"> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/control-scorecards-grid.html"> <img src="Website/static/examples/generated/control-scorecards-grid.png" alt="Control scorecard small multiples generated by ChartForgeX" width="100%" /> </a> <br /> <strong>Report-ready small multiples</strong> <br /> Gauges, bullets, radar charts, polar areas, and shared themes rendered without a browser runtime. <br /> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/control-scorecards-grid.html">HTML</a> / <a href="Website/static/examples/generated/control-scorecards-grid.svg">SVG</a> / <a href="Website/static/examples/generated/control-scorecards-grid.png">PNG</a> </td> </tr> <tr> <td width="50%"> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/visual-replication-mesh-explorer.html"> <img src="Website/static/examples/generated/visual-replication-mesh-explorer.png" alt="Replication mesh explorer topology generated by ChartForgeX" width="100%" /> </a> <br /> <strong>Interactive topology scenarios</strong> <br /> Grouped nodes, routed edges, status encoding, scenario switching, route playback, and scoped URL state. <br /> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/visual-replication-mesh-explorer.html">HTML</a> / <a href="Website/static/examples/generated/visual-replication-mesh-explorer.svg">SVG</a> / <a href="Website/static/examples/generated/visual-replication-mesh-explorer.png">PNG</a> </td> <td width="50%"> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/theme-font-showcase-grid.html"> <img src="Website/static/examples/generated/theme-font-showcase-grid.png" alt="Theme and font showcase grid generated by ChartForgeX" width="100%" /> </a> <br /> <strong>Visual systems</strong> <br /> Themes, palettes, typography, brand treatments, and consistent SVG/PNG styling from the same chart model. <br /> <a href="https://preview.evotec.xyz/?url=https://github.com/EvotecIT/ChartForgeX/blob/main/Website/static/examples/generated/theme-font-showcase-grid.html">HTML</a> / <a href="Website/static/examples/generated/theme-font-showcase-grid.svg">SVG</a> / <a href="Website/static/examples/generated/theme-font-showcase-grid.png">PNG</a> </td> </tr> </table>
More generated examples are available in the checked-in catalog, topology demo hub, SVG/PNG comparison view, and quality dashboard.
Examples
Run the example project when changing renderers, themes, chart APIs, or gallery metadata:
dotnet run --project .\ChartForgeX.Examples\ChartForgeX.Examples.csproj -c Release
Generated output is written to ChartForgeX.Examples/bin/Release/net8.0/output/.
Useful review entry points:
index.html- full generated gallery.catalog.html- examples grouped by chart family.topology-demo.html- focused topology demo hub with the scenario route explorer.svg-png-comparison.html- side-by-side renderer parity review.quality-dashboard.html- visual health summary.
Example cards link HTML, SVG, PNG, and C# snippets when a checked source sample exists.
Install
dotnet add package ChartForgeX
ChartForgeX targets net472, netstandard2.0, net8.0, and net10.0. The core package has no runtime package dependencies. The net472 target uses Microsoft.NETFramework.ReferenceAssemblies.net472 as a private build-time reference only.
Optional interaction support is split into separate packages:
| Package | Purpose |
|---|---|
ChartForgeX |
Static SVG, HTML, PNG, BMP, PPM, and TIFF rendering. |
ChartForgeX.Interactivity |
Host-neutral interaction contracts. |
ChartForgeX.Interactivity.Html |
Self-contained HTML/SVG interaction adapter. |
ChartForgeX.Markup |
Markdown-friendly topology markup parser and C# emitter. |
Native AOT and Trimming
ChartForgeX is designed to work in trimmed and Native AOT applications on modern .NET targets. The net8.0 and net10.0 package assets declare AOT compatibility, enable trim/single-file/AOT analyzers, and avoid reflection-driven serialization or dynamic code paths in the rendering surface.
The release quality loop publishes and runs ChartForgeX.AotSmoke as a Native AOT executable. That smoke app renders SVG, static HTML, PNG, chart grids, visual blocks, topology diagrams, and the self-contained HTML interaction adapter, so AOT regressions fail before a package is published.
Output API
The output API follows one rule: To* returns content, Save* writes a file, and Write* streams bytes.
| Need | Use |
|---|---|
| SVG markup | chart.ToSvg() or chart.SaveSvg("chart.svg") |
| Static HTML | chart.ToHtmlFragment(), chart.ToHtmlPage(), or chart.SaveHtml("chart.html") |
| PNG bytes/file | chart.ToPng() or chart.SavePng("chart.png") |
| Layered visual canvas | VisualCanvas.CreateSocialPreview(), VisualCanvas.CreateDesktopWallpaper(), canvas.ToSvg(), canvas.SavePng("social-preview.png"), or canvas.Save("social-preview.jpg", rasterOptions) for fixed-size wallpaper, social image, report cover, and hero compositions |
| Reusable image composition | ImageComposition.FromFile("wallpaper.jpg").DrawImage(...).DrawText(...).Save("wallpaper-output.jpg") for dependency-free background plus overlay generation |
| Topology animated raster | topology.ToGif(options), topology.ToApng(options), topology.WriteGif(stream, options), topology.WriteApng(stream, options), topology.SaveGif("route.gif", options), or topology.SaveApng("route.apng", options) with TopologyMotionOptions.RoutePulseForScenario(...) or .RoutePulseForEdges(...) |
| Extension-inferred file output | chart.Save("chart.svg"), chart.Save("chart.html"), chart.Save("chart.png"), chart.Save("chart.jpg"), chart.Save("chart.tiff"); topology also supports topology.Save("route.gif", options) and topology.Save("route.apng", options) |
| Advanced raster output | ToRasterImage, WriteRasterImage, and SaveRasterImage for PNG, JPEG, BMP, PPM, and TIFF; plus format helpers such as ToBmp, ToPpm, and ToTiff |
Save(path) infers .svg, .html, .htm, .png, .jpg, .jpeg, .bmp, .ppm, .tiff, and .tif. Topology Save(path, options) also infers .gif and .apng when TopologyMotionOptions describes a route. Animated GIF output uses an adaptive palette, error diffusion, and cropped delta frames for compatibility-friendly previews. APNG keeps full RGBA color and also crops unchanged frame regions for high-fidelity animated raster output, while SVG remains the highest-fidelity script-free animated surface. Unsupported or empty extensions fail before a file is opened. RasterImageOptions controls JPEG quality and the background used when alpha must be flattened.
Simple Definitions
ChartForgeX.Simple is the supported lightweight construction layer for script, UI, and host libraries that should not own chart DTOs. It only carries deferred chart definitions; enums, themes, rendering options, point helpers, bubble helpers, and output still come from the core ChartForgeX API. The result is a native ChartForgeX.Core.Chart, so callers can keep customizing or rendering it with the normal fluent API.
using ChartForgeX;
using ChartForgeX.Core;
using ChartForgeX.Primitives;
using ChartForgeX.Simple;
var chart = Charts.Build(
new ChartDefinition[] {
new ChartLine("CPU", new double[] { 35, 42, 58, 61 }, ChartColor.FromHex("#22C55E"), smooth: true)
},
width: 420,
height: 260,
showGrid: true,
options: new ChartRenderOptions {
UseOverlay = true,
ShowLegend = true
});
chart.SavePng("cpu-overlay.png");
chart.SaveSvg("cpu-overlay.svg");
UseOverlay applies ChartForgeX transparent composition defaults: transparent background, no card, no plot fill, and quiet axes/grid. Explicit options still win, so callers can turn legends, axes, or data labels back on for wallpaper, report, and image-composition scenarios.
When a host does not need deferred definitions, use core helpers directly:
var direct = Chart.Create()
.AddSmoothLine("CPU", ChartPoints.FromValues(35, 42, 58, 61))
.AddBubble("Latency", ChartBubbles.FromXYSize(new[] { 1d, 2d }, new[] { 48d, 63d }, new[] { 8d, 14d }));
Project Status
ChartForgeX is pre-1.0, but the current public surface is intended to be useful and stable where it models real charting, topology, visual block, rendering, and package concepts. Active follow-up work belongs in TODO.md; release notes belong in GitHub Releases and short NuGet package notes.
Quick Start
using ChartForgeX;
using ChartForgeX.Core;
using ChartForgeX.Primitives;
using ChartForgeX.Themes;
var chart = Chart.Create()
.WithTitle("Domain Security Checks")
.WithSubtitle("Dependency-free SVG, HTML, and PNG chart rendering")
.WithXAxis("Run")
.WithYAxis("Checks")
.WithTheme(ChartTheme.ReportDark())
.WithSize(1180, 640)
.WithXLabels("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")
.AddSmoothArea("Passed", Points(820, 940, 980, 1040, 1120, 1180, 1230))
.AddSmoothLine("Warnings", Points(120, 138, 132, 110, 98, 86, 72), ChartColor.FromRgb(251, 191, 36))
.AddSmoothLine("Failed", Points(22, 30, 28, 21, 18, 15, 13), ChartColor.FromRgb(248, 113, 113));
chart.SaveSvg("chart.svg");
chart.SaveHtml("chart.html");
chart.SavePng("chart.png");
static IEnumerable<ChartPoint> Points(params double[] y) {
for (var i = 0; i < y.Length; i++) {
yield return new ChartPoint(i + 1, y[i]);
}
}
Composition
Use ChartGrid for chart-only small multiples, comparison grids, and mosaic reports. Add(chart, columnSpan, rowSpan) and WithPanelSpan(index, columnSpan, rowSpan) let a report mix hero panels with smaller supporting charts without creating a chart type just for layout.
var report = ChartGrid.Create()
.WithTitle("Control Scorecards")
.WithTheme(ChartTheme.ReportLight())
.WithColumns(2)
.WithPanelSize(520, 320)
.Add(gaugeChart, columnSpan: 2)
.Add(trendChart)
.Add(coverageChart)
.WithPanelSpan(2, columnSpan: 2);
report.SaveHtml("scorecards.html");
report.SaveSvg("scorecards.svg");
report.SavePng("scorecards.png");
report.SaveBmp("scorecards.bmp");
report.SavePpm("scorecards.ppm");
report.SaveTiff("scorecards.tiff");
Use ChartForgeX.VisualBlocks when a report needs exact facts beside charts instead of pretending tables, lists, metric cards, status panels, or infographic snippets are chart series.
using ChartForgeX.Core;
using ChartForgeX.Rendering;
using ChartForgeX.VisualBlocks;
var drives = ChartTable.Create()
.WithTitle("Drive Summary")
.AddColumn("Drive")
.AddColumn("Used", VisualTextAlignment.Right, format: "0%")
.AddColumn("Free", VisualTextAlignment.Right)
.AddColumn("Status")
.AddRow("C:", 0.72, "128 GB", "OK")
.AddRow("D:", 0.91, "34 GB", "Warning")
.WithStatusColumn("Status")
.WithDenseMode();
var snapshot = VisualGrid.CreateMetricStrip("Endpoint Snapshot", new[] {
MetricCard.Create().WithMetric("CPU Load", "38%").WithMiniSparkline(new[] { 52d, 48d, 44d, 41d, 38d }),
MetricCard.Create().WithMetric("Memory Used", "71%").WithMiniBars(new[] { 55d, 59d, 63d, 68d, 71d }, maximum: 100)
});
Segmented dashboard visuals use one generic block instead of domain-specific card classes. The same SegmentedMetricBlock can render progress rows, performance rows with exact values, balanced capsule loops, funnel columns, composition strips, or distribution rows; item colors fall back to the active theme palette unless a color or semantic status is supplied.
var performance = SegmentedMetricBlock.Create(SegmentedMetricStyle.ProgressRows)
.WithTitle("Content Performance")
.AddItem(new SegmentedMetricItem("Posts", 86)
.WithProgress(100, 44)
.WithDisplayValue(132034, "N0")
.WithDelta("+4.3%"));
var channels = SegmentedMetricBlock.Create(SegmentedMetricStyle.CapsuleLoop)
.WithTitle("Channel Share")
.AddItem("Direct", 40, displayValue: "24,000")
.AddItem("Partner", 35, displayValue: "21,000")
.AddItem("Referral", 15, displayValue: "9,000")
.AddItem("Other", 10, displayValue: "6,000");
var certificates = SegmentedMetricBlock.Create(SegmentedMetricStyle.CompositionStrip)
.WithTitle("Certificate Count")
.WithMetric("Certificates", 277)
.AddItem("Valid", 164, displayValue: "164")
.AddItem("Expiring", 48, displayValue: "48")
.AddItem("Revoked", 24, displayValue: "24")
.AddItem("Unknown", 41, displayValue: "41");
var tasks = SegmentedMetricBlock.Create(SegmentedMetricStyle.CompositionStrip)
.WithTitle("Overall Tasks")
.WithMetric("Tasks", 23, "Task")
.AddItem("On Going", 12, pattern: ChartFillPattern.DiagonalForward)
.AddItem("Under Review", 6)
.AddItem("Finish", 4);
var funnel = SegmentedMetricBlock.Create(SegmentedMetricStyle.FunnelColumns)
.WithTitle("Conversion Funnel")
.AddItem("Clicks", 82000, segments: 24, displayValue: "82,000")
.AddItem("Added to Cart", 7200, segments: 16, displayValue: "7,200")
.AddItem("Payment", 1230, segments: 12, displayValue: "1,230");
Topology Diagrams
ChartForgeX.Topology is for reusable deterministic diagrams. It owns the product-neutral model, validation, layout helpers, SVG rendering, PNG rendering, and static HTML wrapper. Host projects own dashboard shells, data collection, filters, inspectors, and product-specific calculations.
using ChartForgeX.Topology;
var topology = TopologyChart.Create()
.WithId("service-map")
.WithTitle("Service Dependency Map")
.WithLayout(TopologyLayoutMode.Layered, TopologyLayoutDirection.LeftToRight)
.WithLegend(TopologyLegend.Default()
.AddNodeKind("Service", TopologyNodeKind.Service, symbol: "API")
.AddNodeKind("Database", TopologyNodeKind.Database, symbol: "SQL")
.AddEdgeKind("Dependency", TopologyEdgeKind.Dependency))
.AddNode("api", "API", 0, 0, TopologyNodeKind.Service, TopologyHealthStatus.Healthy, symbol: "API")
.AddNode("database", "Database", 0, 0, TopologyNodeKind.Database, TopologyHealthStatus.Warning, symbol: "SQL")
.AddEdge("api-database", "api", "database", "32 ms", TopologyEdgeKind.Dependency, TopologyHealthStatus.Warning, TopologyDirection.Forward);
topology.SaveSvg("service-map.svg");
topology.SaveHtml("service-map.html");
topology.SavePng("service-map.png");
topology.SaveBmp("service-map.bmp");
topology.SavePpm("service-map.ppm");
topology.SaveTiff("service-map.tiff");
Supported topology layout modes are Manual, GroupGrid, HubAndSpoke, Layered, Matrix, DenseGrouped, and Geographic. Geographic topology uses ChartMapViewport with typed coordinates, route arcs, region hulls, and optional callouts while keeping the model reusable across infrastructure, cloud, tenant, inventory, and domain-specific hosts.
Dotted maps can render both point-to-point route arcs and ordered waypoint routes. Use AddMapRoute("label", new[] { new ChartMapPoint("Origin", lon, lat), ... }) for paths such as shipping alternatives through the Suez Canal or around the Cape of Good Hope without adding shipping-specific concepts to the renderer. Light report themes render map geography as filled outlines instead of land-dot texture so routes stay readable on white backgrounds.
Chart catalog
The catalog is broad enough for generated reports, dashboards, operational summaries, and static documentation:
| Family | APIs |
|---|---|
| Cartesian lines and areas | AddLine, AddSmoothLine, AddStepLine, AddArea, AddStepArea, AddSmoothArea, AddStackedArea, AddSmoothStackedArea, AddScatter, AddTrendLine, AddPointCallout, WithPointLabel, WithLegendEntry, WithSemanticRole, AddMeanLine, AddMedianLine, AddStandardDeviationBand, AddSlope |
| Combo charts | AddBarLineCombo, AddColumnLineCombo, AddBarAreaCombo, AddColumnAreaCombo, AddScatterLineCombo |
| Bars and distributions | AddBar, AddHistogram, AddLollipop, AddBubble, AddErrorBar, AddCandlestick, AddOhlc, AddRangeBand, AddRangeArea, AddDumbbell, AddPareto, AddRangeBar, AddBoxPlot, AddHorizontalBar, WithStackedHorizontalBars |
| Heatmaps and calendars | AddHeatmapRow, AddHeatmapRows, ChartHeatmapRow, AddHexbinHeatmapRow, AddHexbinHeatmapRows, AddCalendarHeatmap, ChartCalendarHeatmapItem |
| Maps | AddDottedMap, ChartMapPoint, ChartMapViewport, WithMapViewport, AddMapConnector, AddMapRoute, AddMapConnectorBetweenPoints, AddMapRouteBetweenPoints, AddRegionMap, AddTileMap, ChartMapCatalog, ChartMapCatalogEntry, ChartMapCatalogEntryKind, EmbeddedEntries, ExternalEntries, Load, FromAssetDirectory, ChartMapDefinition, ChartMapRegion, ChartTileMapCatalog, ChartTileMapDefinition, ChartTileMapRegion, ChartRegionMapItem, WithMapLabels, WithMapScaleLegend, WithMapScaleLegendPosition, WithMapSurface, WithMapRegionStroke, WithRegionMapBounds, WithRegionMapCoordinateBounds, AddMapBaseLayer, AddMapBoundaryLayer |
| KPI and radial visuals | AddGauge, AddCircle, AddRadialBar, AddLayeredRadial, ChartRadialLayer, ChartRadialLayerCap, AddBullet, AddWaterfall, AddRadar, AddPolarArea |
| Hierarchy and flow | AddFunnel, AddTreemap, AddSankey, ChartSankeyLink, AddTree, ChartTreeLink, AddSunburst, AddPie, AddDonut |
| Pictorial and progress | AddPictorial, ChartPictorialItem, ChartPictorialShape, ChartPictorialShape.Person, WithPictorialShape, WithPictorialColumns, WithPictorialMaximum, WithPictorialValuePerSymbol, WithPictorialValues, WithPictorialSymbolScale, WithPictorialEmptyOpacity, WithPictorialSvgPath, AddProgressBars, ChartProgressItem, WithProgressMaximum, WithProgressValues, WithProgressHandles, WithProgressBarThickness, WithProgressTrackOpacity |
| Text, labels, and legends | WithLegendPosition, WithPointLegend, ChartTextRole, ChartTextStyle, WithTextStyle, WithTitleStyle, WithSubtitleStyle, WithAxisTitleStyle, WithTickLabelStyle, WithLegendStyle, WithDataLabelStyle, WithDonutCenterLabel, WithDonutCenterText, WithDonutInnerRadiusRatio, WithRadialBarCenterLabel, WithCircleStatusLabel, WithCircleRadiusScale, WithCircleStrokeScale, WithRadialBarRadiusScale, WithRadialBarStrokeScale |
| Branding and themes | ChartBrandKit, WithBrandKit, ChartBrandKit.Executive(), PeopleInfographic(), Accessible(), ChartTheme.Aurora(), ChartTheme.Colorblind(), ChartTheme.DashboardLight(), ChartTheme.SaasDashboardLight(), ChartFontStacks, ChartPalettes.Vivid |
| Text-heavy and schedule visuals | AddWordCloud, ChartWordCloudItem, WithWordCloudFontRange, WithWordCloudAngles, WithWordCloudMaximumTerms, WithWordCloudDensity, AddTimelineItem, AddTimelineRange, AddGanttTask, AddGanttMilestone, WithGanttToday |
Renderer Contracts
- ChartForgeX validates chart data before rendering so invalid payloads fail near the caller instead of producing partial markup or malformed PNGs.
- Specialized data checks reject non-finite values, malformed trees, multiple tree roots, and cyclic Sankey flows.
- Scoped inline SVG ids are available through
chart.ToSvg("panel-a")andgrid.ToSvg("report-a"), so repeated charts can be embedded safely. - Heatmaps distinguish no-data cells through
data-cfx-status="empty"while keeping an explicit zero value as real data. - Matrix heatmaps expose
data-cfx-row-count,data-cfx-column-count,data-cfx-min, anddata-cfx-max. - Calendar heatmaps expose
data-cfx-start-dateplus filled/empty day counts. - Map outputs expose
data-cfx-label,data-cfx-projection,data-cfx-map-kind, anddata-cfx-point-count. - Unsafe
javascript:,data:, andvbscript:hrefs are skipped.
Customization cookbook
Use themes when you want a complete visual baseline:
var chart = Chart.Create()
.WithTheme(ChartTheme.Aurora())
.WithSurfaceStyle(ChartSurfaceStyle.Glass)
.WithPalette(ChartPalettes.Vivid)
.AddSmoothLine("Warnings", points);
Use brand kits when a whole report family needs consistent typography, palette, surfaces, and semantic colors:
var branded = Chart.Create()
.WithBrandKit(ChartBrandKit.Executive())
.WithTheme(theme => theme
.WithSurfaceColors("#0F172A", "#111827", "#1F2937")
.WithSemanticColors(success: "#22C55E", warning: "#F59E0B", danger: "#EF4444"));
Use pasted colors when matching an existing design system:
var palette = ChartPalettes.FromHex("#2563EB", "#14B8A6", "#F59E0B", "#EF4444");
var color = ChartColor.FromHex("#2563EB");
Use fluent series styling for a single emphasized series:
chart.Series[0]
.WithStrokeWidth(4)
.UseThemeColor();
| Report intent | Theme starting point | Brand kit starting point |
|---|---|---|
| Executive report | ChartTheme.ReportLight() |
ChartBrandKit.Executive() |
| Operational dashboard | ChartTheme.DashboardLight() |
ChartBrandKit.Accessible() |
| SaaS-style dashboard | ChartTheme.SaasDashboardLight() |
ChartBrandKit.Product() |
| People or editorial summary | ChartTheme.Aurora() |
ChartBrandKit.PeopleInfographic() |
| Accessibility-first report | ChartTheme.Colorblind() |
ChartBrandKit.Accessible() |
Output and Safety
- SVG is the highest-fidelity static target.
- HTML wraps inline SVG into static self-contained pages or fragments.
- PNG uses ChartForgeX's dependency-free raster path and supports real alpha transparency.
- BMP, PPM, and TIFF are opaque utility exports over the same raster buffer.
- JavaScript belongs in opt-in adapter packages, not in the default static renderer.
- Public APIs fail fast on invalid sizes, ranges, enum values, and specialized series payloads.
Website Pilot
Website/ contains the dedicated PowerForge.Web pilot site for ChartForgeX. The central Evotec project hub remains the registry page, while the dedicated site is meant for the richer gallery and demo experience at https://chartforgex.evotec.xyz/.
Build the examples first with ./Build.ps1, then build the site from Website/:
.\build.ps1 -Dev
.\build.ps1 -Ci
Promoted website examples should be reproducible cases, not screenshots: show the rendered preview, link the HTML/SVG/PNG artifacts, and point to the source file or builder method that generates the same output.
Repository Map
ChartForgeX
|-- ChartForgeX # core chart model and static renderers
| |-- Core # chart model, series, options
| |-- Primitives # colors, points, rects, padding
| |-- Rendering # shared rendering math and polish helpers
| |-- Svg # SVG renderer
| |-- Html # static HTML renderer
| |-- Raster # PNG/BMP/PPM/TIFF renderer and encoders
| |-- Topology # product-neutral topology model/renderers
| `-- VisualBlocks # tables, lists, metric cards, visual grids
|-- ChartForgeX.Interactivity # host-neutral interaction contracts
|-- ChartForgeX.Interactivity.Html # self-contained HTML interaction adapter
|-- ChartForgeX.Examples # generated gallery and smoke examples
|-- ChartForgeX.Tests # smoke and repository quality tests
|-- Website # dedicated PowerForge.Web pilot site
|-- docs # focused reference notes
|-- AGENTS.md # contributor/agent expectations
|-- CONTRIBUTING.md # development and release workflow
|-- TODO.md # centralized active work ledger
`-- Build.ps1 # local quality and packaging gate
Development
For fast local feedback, run the smoke suite:
dotnet test .\ChartForgeX.Tests\ChartForgeX.Tests.csproj -c Release
Before publishing a pull request, run the full quality loop:
./Build.ps1 -Configuration Release
That restores, builds, tests, regenerates examples, verifies visual manifests, packs the NuGet artifacts, and installs the freshly packed packages into a clean temporary consumer project.
Regenerate examples directly when reviewing renderer or gallery changes:
dotnet run --project .\ChartForgeX.Examples\ChartForgeX.Examples.csproj -c Release
Review the generated pages under ChartForgeX.Examples/bin/Release/net8.0/output/:
index.htmlcatalog.htmlquality-dashboard.htmlsvg-png-comparison.htmldomain-security-interactive.htmlexecutive-interactive-dashboard.html
Only refresh visual baselines after reviewing the generated gallery:
./Build.ps1 -Configuration Release -UpdateVisualBaseline
Documentation
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. 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 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 is compatible. 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. |
-
.NETFramework 4.7.2
- ChartForgeX (>= 0.1.5)
-
.NETStandard 2.0
- ChartForgeX (>= 0.1.5)
-
net10.0
- ChartForgeX (>= 0.1.5)
-
net8.0
- ChartForgeX (>= 0.1.5)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.