# ZenPlot **Repository Path**: AscendLiu/ZenPlot ## Basic Information - **Project Name**: ZenPlot - **Description**: ZenPlot 是一个基于 .NET 10 + SkiaSharp 的高性能时序数据可视化库,以 ScottPlot 5 架构为参考,专注万亿级数据点的实时渲染与交互。核心特性包括:Signal 双模式渲染(低密度逐点路径 + 高密度像素列聚合)、SegmentedTree O(log n) 范围查询、MinMaxCache 并行预构建缓存、DataStreamer 实时流环形缓冲(Scroll/ - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-05-31 - **Last Updated**: 2026-06-01 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ZenPlot High-performance time-series data visualization library for .NET, built on SkiaSharp. Inspired by ScottPlot 5, optimized for real-time signal rendering and billion-scale data points. ```csharp var plot = new Plot(); plot.Add.Signal(data); plot.SavePng("chart.png", 800, 400); ``` ## Packages | Package | NuGet | Description | |---------|-------|-------------| | `ZenPlot` | [![NuGet](https://img.shields.io/nuget/v/ZenPlot)](https://www.nuget.org/packages/ZenPlot/) | Core library — Signal rendering, DataStreamer, MinMaxCache, full chart pipeline | | `ZenPlot.Avalonia` | [![NuGet](https://img.shields.io/nuget/v/ZenPlot.Avalonia)](https://www.nuget.org/packages/ZenPlot.Avalonia/) | Avalonia UI control with interactive pan/zoom | ## Quick Start ```bash dotnet add package ZenPlot dotnet add package ZenPlot.Avalonia ``` ### Console — save to PNG ```csharp using ZenPlot; int n = 10_000; var ys = new double[n]; for (int i = 0; i < n; i++) ys[i] = Math.Sin(2 * Math.PI * 5 * i / 1000); var plot = new Plot(); plot.Add.Signal(ys).Label = "sin(5t)"; plot.Axes.AutoScale(plot.Plottables); plot.SavePng("chart.png", 1200, 600); ``` ### Avalonia — interactive chart ```xml ``` ```csharp var signal = MyPlot.Plot.Add.Signal(ys); signal.Label = "sin(5t)"; MyPlot.Plot.Axes.AutoScale(MyPlot.Plot.Plottables); MyPlot.Refresh(); ``` ### Avalonia — real-time streaming ```csharp var streamer = MyPlot.Plot.Add.DataStreamer(capacity: 500); // Push data at 100 Hz var timer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(10) }; timer.Tick += (_, _) => { streamer.Data.Add(Math.Sin(2 * Math.PI * 3 * t)); MyPlot.Refresh(); }; timer.Start(); ``` ## Features ### Rendering Pipeline | Step | Description | |------|-------------| | ClearCanvas | Clear background to white | | RenderBackground | Fill data area with light gray | | ExecutePlottableAxisManagers | Auto-update axes for DataStreamer | | RegenerateTicks | Compute nice-number tick positions | | RenderGrids | Draw major grid lines | | RenderPlottables | Draw all plottables (clipped to data area) | | RenderAxes | Draw border, tick marks, tick labels | | RenderLegend | Draw legend box with colored swatches | ### Signal Dual-Mode Rendering ZenPlot automatically selects the optimal rendering mode based on zoom level: | Mode | Condition | Method | |------|-----------|--------| | **Low Density** | < 1 point/pixel | Connect all visible points with a path | | **High Density** | ≥ 1 point/pixel | Per-pixel column min/max aggregation via `Parallel.For` | ### Data Sources | Source | Index | Query Speed | Build Cost | Use Case | |--------|-------|-------------|------------|----------| | `SignalSource` | None | O(n) per column | None | Small datasets, one-shot renders | | `SignalSourceCached` | MinMaxCache (parallel) | O(chunk) per column | `Parallel.For` O(n) | Large datasets, fast first render | | `SignalConstSource` | SegmentedTree | O(log n) per column | O(n) synchronous | Large datasets, frequent renders | ### DataStreamer Ring-buffer based real-time streaming with two display modes: | View | Behavior | |------|----------| | **ScrollView** | New data appears on the right, old data scrolls left | | **WipeView** | New data overwrites from left to right | ### Interaction (Avalonia) - **Drag** — Pan X/Y axes - **Scroll wheel** — Zoom in/out - **Double-click** — Auto-scale all axes - **Legend** — Automatically shown for plottables with a `Label` ## Performance Targets | Scenario | Target | |----------|--------| | Low density render (10k points) | < 5ms | | High density render (10M points) | < 30ms | | SegmentedTree range query (any scale) | O(log n) | | Real-time streaming | 60+ fps | ## Architecture ``` ┌─────────────────────────────────────────────────┐ │ ZenPlot (Core) │ │ ┌───────┐ ┌──────────┐ ┌──────────────────┐ │ │ │ Plot │→│RenderMgr │→│ IRenderAction x8 │ │ │ │───────│ │──────────│ │──────────────────│ │ │ │Axes │ │LayoutMgr │ │ ClearCanvas │ │ │ │Add.Sig│ │Plottables│ │ RenderBackground │ │ │ │Add.Str│ │Sync │ │ RegenerateTicks │ │ │ └───────┘ └──────────┘ │ RenderGrids │ │ │ │ RenderPlottables │ │ │ ┌──────────────────┐ │ RenderAxes │ │ │ │ IPlottable │ │ RenderLegend │ │ │ │ Signal │ └──────────────────┘ │ │ │ DataStreamer │ │ │ └──────────────────┘ │ ├─────────────────────────────────────────────────┤ │ ZenPlot.Avalonia (AvaPlot Control) │ │ ICustomDrawOperation → SkiaSharp → GPU │ ├─────────────────────────────────────────────────┤ │ SkiaSharp (GPU-accelerated 2D) │ └─────────────────────────────────────────────────┘ ``` ## Build & Publish ```bash # Build dotnet build # Run benchmarks dotnet run --project tests/ZenPlot.Benchmarks --configuration Release # Create NuGet packages ./pack.sh # Pack and publish to nuget.org ./pack.sh push ``` ## Dependencies - **SkiaSharp 3.x** — Cross-platform GPU-accelerated 2D graphics - **Avalonia 12.x** *(optional, ZenPlot.Avalonia only)* — Desktop UI framework - **BenchmarkDotNet 0.14.x** *(tests only)* — Performance benchmarking Zero additional runtime dependencies. ## License MIT