Aioros.Graphs
0.1.0-preview.2
dotnet add package Aioros.Graphs --version 0.1.0-preview.2
NuGet\Install-Package Aioros.Graphs -Version 0.1.0-preview.2
<PackageReference Include="Aioros.Graphs" Version="0.1.0-preview.2" />
<PackageVersion Include="Aioros.Graphs" Version="0.1.0-preview.2" />
<PackageReference Include="Aioros.Graphs" />
paket add Aioros.Graphs --version 0.1.0-preview.2
#r "nuget: Aioros.Graphs, 0.1.0-preview.2"
#:package Aioros.Graphs@0.1.0-preview.2
#addin nuget:?package=Aioros.Graphs&version=0.1.0-preview.2&prerelease
#tool nuget:?package=Aioros.Graphs&version=0.1.0-preview.2&prerelease
Aioros.Graphs
Preview. Aioros.Graphs is in public preview: its APIs can change between versions, and it is not ready for production yet.
The chart engine of the Aioros ecosystem, as three packages:
Aioros.Graphs,Aioros.Graphs.SvgandAioros.Graphs.Avalonia.
What charts need, in C#: arrays, scales, shapes, curves, paths, number and time formats, following d3, the reference its tests compare with. It has no UI dependency: shapes write path commands into a sink, and two sinks ship with it, SVG path data in UTF-8 for the web (Aioros records self-drawn controls as SVG) and native geometry for the desktop. Chart libraries are built on it in their own repositories: Aioros.Pictor, charts in pure XAML, first.
Aioros.Graphs is an independent port and is not affiliated with or endorsed by the d3 project. d3 (ISC) and d3-sankey (BSD-3-Clause) keep their notices in THIRD-PARTY-NOTICES.md, which every package carries.
Two goals, in this order:
- The same output as d3. Every ported function is tested against fixtures generated by d3 itself
(
tools/golden): ticks, scale values and tick labels bit for bit, SVG path data byte for byte. - Performance. Structs and spans on the hot paths, shapes specialized at compile time for their curve and sink
(no virtual calls, no closures, no LINQ), pooled buffers, no allocation per point (
bench).
var x = LinearScale.Create([0, data.Length - 1], [0, 960]);
var y = LinearScale.Create([min, max], [500, 0]).Nice();
x.Map(index, xs);
y.Map(values, ys);
var buffer = new ArrayBufferWriter<byte>();
var svg = new SvgPathWriter(buffer);
Line.Write(ref svg, Curve.MonotoneX, xs, ys);
// buffer.WrittenSpan is d3's line().curve(curveMonotoneX)(data), byte for byte
var geometry = new StreamGeometry();
using (var context = geometry.Open())
{
var sink = new GeometrySink(context);
Line.Write(ref sink, Curve.MonotoneX, xs, ys);
sink.Complete();
}
// the same path as a StreamGeometry
What is ported
| d3 module | Ported |
|---|---|
| d3-array | ticks, tickIncrement, tickStep, nice, bisectors (bisectLeft/Right/Center, bisector on struct key selectors), extent, bin (thresholds sturges, scott, freedmanDiaconis, counts and arrays), quantile/quantileSorted/quantileIndex, sum, mean, median, min, max, minIndex, maxIndex, variance, deviation, fsum, cumsum, range, group/rollup (one or several key levels), flatGroup, flatRollup, index, fcumsum, Adder |
| d3-scale | scaleLinear (piecewise, clamp, rangeRound, invert, ticks, nice, tickFormat), scaleLog, scalePow, scaleSqrt, scaleSymlog, scaleRadial, scaleBand, scalePoint, scaleOrdinal, scaleQuantize, scaleQuantile, scaleThreshold, scaleSequential (+Log/Pow/Sqrt/Symlog/Quantile), scaleDiverging (+Log/Pow/Sqrt/Symlog), scaleUtc, scaleTime (local time in any TimeZoneInfo) |
| d3-shape | line, area, arc (padding, corners), pie, stack (all orders and offsets), symbol (all fill and stroke types), link/linkHorizontal/linkVertical/linkRadial, lineRadial, areaRadial, pointRadial; curves linear, linearClosed, monotoneX/Y, natural, step/stepBefore/stepAfter, basis/basisClosed/basisOpen, bundle, cardinal/cardinalClosed/cardinalOpen, catmullRom/catmullRomClosed/catmullRomOpen, bumpX/bumpY |
| d3-path | path, pathRound (moveTo, lineTo, quadratic and cubic curves, arc, arcTo, rect, closePath) |
| d3-format | format, formatPrefix, formatSpecifier, precisionFixed/Prefix/Round, formatLocale (all 59 locales d3 ships, as NumberLocale), locale-aware tick formats |
| d3-time | UTC and local intervals (millisecond to year, utcSunday to utcSaturday, timeSunday to timeSaturday, every, range, count) over an injectable time zone, utcTicks/timeTicks, utcTickInterval/timeTickInterval |
| d3-time-format | utcFormat and local timeFormat with every directive (including %U %W %V %g %G %c %x %X), utcParse and local timeParse with every directive d3 parses, in every locale, timeFormatLocale (all 34 locales d3 ships, as TimeLocale), the time scales' multi-scale tick formats |
| d3-color | rgb, hsl, lab, hcl/lch, cubehelix, gray: CSS parsing, conversions, brighter/darker, displayable, clamp, formatHex/Hex8/Rgb/Hsl (span writers) |
| d3-interpolate | number, round, hue, basis/basisClosed, discrete, numberArray, rgb (gamma), rgbBasis/rgbBasisClosed, hsl/hslLong, lab, hcl/hclLong, cubehelix/cubehelixLong (gamma), piecewise, quantize, zoom, string, date, the generic interpolate over a typed value union (InterpolationValue: numbers, colors, strings, dates, number arrays, arrays, objects) |
| d3-scale-chromatic | all categorical, ColorBrewer diverging and sequential schemes and interpolators, viridis/magma/inferno/plasma, cividis, turbo, warm, cool, rainbow, sinebow, cubehelixDefault |
| d3-hierarchy | hierarchy (Hierarchy.FromNested), stratify by ids and by path (Stratify, StratifyPaths; FromParents over parent indices), sum, count (CountLeaves), sort, descendants, leaves, ancestors, path, links, the eachBefore/eachAfter orders; layouts tree and cluster (size, node size, default and radial separation), treemap (squarify with any ratio, resquarify, binary, dice, slice, sliceDice; inner, outer, top, right, bottom and left padding; round), pack (size, padding, leaf radii), packSiblings, packEnclose, partition |
| d3-chord | chord, chordDirected, chordTranspose (pad angle, groups, subgroups and chords sorted ascending or descending) as ChordLayout; ribbon and ribbonArrow (source and target radii, pad angle, head radius) as Ribbon over any IPathSink |
| d3-force | forceSimulation stepped explicitly (tick, a Run that ticks until alpha falls below alphaMin as d3's timer does, find, alpha, alphaMin, alphaDecay, alphaTarget, velocityDecay, fixed nodes, d3's seeded LCG and phyllotaxis placement), forceLink, forceManyBody (Barnes–Hut over a d3-quadtree port), forceCenter, forceCollide, forceX, forceY: bit-identical to d3 |
| d3-sankey (0.12.3) | sankey() as SankeyLayout.Compute (nodes by index or string id, fixed node values, extent, nodeWidth, nodePadding, nodeAlign justify/left/right/center, nodeSort and linkSort as breadth, input order or a comparison, iterations), sankeyLinkHorizontal (SankeyLayout.WriteLink) |
| d3-axis | axisTop/Right/Bottom/Left as data (Axis, AxisLayout: tick positions, labels, tick lines, label offsets, domain path) and as d3's markup (SvgAxisWriter), for linear, log, pow, symlog, band, point, UTC and local time scales |
The rest is listed in docs/roadmap.md; precedents and decisions are in docs/decisions.md.
Layout
| Project | Role |
|---|---|
src/Aioros.Graphs |
The engine. No package and no project reference. |
src/Aioros.Graphs.Svg |
SvgPathWriter: path data as d3 writes it, to an IBufferWriter<byte>; SvgAxisWriter: an axis as d3-axis's markup. |
src/Aioros.Graphs.Avalonia |
GeometrySink: paths into Avalonia 12 geometry (StreamGeometryContext or any IGeometryContext). |
tests/Aioros.Graphs.Tests |
One test per acceptance criterion, most against the golden fixtures. |
tests/Aioros.Graphs.ArchitectureTests |
Criteria coverage and the code rules. |
bench/Aioros.Graphs.Benchmarks |
BenchmarkDotNet micro-benchmarks; bench/d3 measures d3 on the same work. |
samples/Demo |
The demo site: nineteen d3 gallery charts drawn by the engine on each request beside d3's output for the same data, and the latest lab benchmarks (samples/Demo/serve.sh, then http://localhost:5180). The bench's samples/Demo/run.sh also writes a static page, samples/Demo/out/index.html. Not shipped. |
tests/Aioros.Graphs.Demo.Tests |
The demo site's criteria (docs/acceptance/demo.md), over an in-memory host. |
tools/golden |
Generates the fixtures from a pinned d3 (Node; not needed to build or test). |
dotnet build Aioros.Graphs.slnx
dotnet test --solution Aioros.Graphs.slnx
dotnet run -c Release --project bench/Aioros.Graphs.Benchmarks -- --filter '*'
Using a local build
Until the engine is published to nuget.org, the repositories built on it (Aioros.Pictor, and any later chart library) consume it from a local package folder:
- Pack it:
eng/pack.shwritesAioros.Graphs,Aioros.Graphs.SvgandAioros.Graphs.Avalonia(with their.snupkgsymbols) toartifacts/packages/and prints the copy command.eng/pack.sh dev.3packs a distinct prerelease (0.1.0-dev.3) so a consumer picks up a new build without clearing its cache. - Copy the
.nupkgfiles into the consumer'spackages/folder (committed or ignored, as that repository decides). - List the folder in the consumer's
nuget.config:
<configuration>
<packageSources>
<add key="local" value="packages" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>
- Reference the packages as usual (
<PackageReference Include="Aioros.Graphs" Version="0.1.0-preview.2" />).
Once the engine is finished and published, the consumers drop the local source and take the packages from nuget.org.
The version has one source, VersionPrefix and VersionSuffix in Directory.Build.props.
License and attribution
The ported code follows d3 by Mike Bostock, ISC-licensed, and d3-sankey, BSD-3-Clause; its notice is in THIRD-PARTY-NOTICES.md. The engine itself is MIT-licensed, as the whole Aioros ecosystem: see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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. |
-
net10.0
- No dependencies.
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Aioros.Graphs:
| Package | Downloads |
|---|---|
|
Aioros.Graphs.Avalonia
Draws Aioros.Graphs' paths through Avalonia's StreamGeometryContext. |
|
|
Aioros.Graphs.Svg
Writes Aioros.Graphs' paths as SVG path data in UTF-8, byte for byte as d3 writes them. |
|
|
Aioros.Pictor
Recharts' cartesian charts as a layout and a painter over Aioros.Graphs, with the SVG writer Aioros calls at request time; no Avalonia. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.1.0-preview.2 | 76 | 11/9/2026 |