ChartForgeX.Markup 0.1.3

dotnet add package ChartForgeX.Markup --version 0.1.3
                    
NuGet\Install-Package ChartForgeX.Markup -Version 0.1.3
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ChartForgeX.Markup" Version="0.1.3" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ChartForgeX.Markup" Version="0.1.3" />
                    
Directory.Packages.props
<PackageReference Include="ChartForgeX.Markup" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ChartForgeX.Markup --version 0.1.3
                    
#r "nuget: ChartForgeX.Markup, 0.1.3"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ChartForgeX.Markup@0.1.3
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ChartForgeX.Markup&version=0.1.3
                    
Install as a Cake Addin
#tool nuget:?package=ChartForgeX.Markup&version=0.1.3
                    
Install as a Cake Tool

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

nuget downloads nuget version

Project Information

top language license quality

Author & Social

Twitter follow Blog LinkedIn Threads Discord

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") and grid.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, and data-cfx-max.
  • Calendar heatmaps expose data-cfx-start-date plus filled/empty day counts.
  • Map outputs expose data-cfx-label, data-cfx-projection, data-cfx-map-kind, and data-cfx-point-count.
  • Unsafe javascript:, data:, and vbscript: 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.html
  • catalog.html
  • quality-dashboard.html
  • svg-png-comparison.html
  • domain-security-interactive.html
  • executive-interactive-dashboard.html

Only refresh visual baselines after reviewing the generated gallery:

./Build.ps1 -Configuration Release -UpdateVisualBaseline

Documentation

Product 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.1.3 43 6/5/2026
0.1.2 97 5/30/2026
0.1.1 93 5/26/2026
0.1.0 97 5/21/2026