Overview

Namespace: TheTechIdea.Beep.Winform.Controls.Charts
Assembly: TheTechIdea.Beep.Winform.Controls.dll
Inheritance: BaseControl

BeepChart is a full-featured charting control supporting 5 chart types (Bar, Line, Pie, Area, Bubble) with interactive viewport control (zoom/pan/auto-scale), performance optimization for datasets exceeding 10,000 points, real-time streaming, trackball with crosshair and multi-series tooltips, and 18 events with dedicated EventArgs classes. It is decomposed across 5 partial files with ~20 helper classes organized into five subsystems.

Partial File Layout (5 Files)

FileLinesContent
BeepChart.cs~80Partial class declaration. Constructor calls InitializeDefaultSettings(), InitializeDesignTimeSampleData(), InitializePainter(). DefaultSize 400x300. Defines 4 enums: ChartSelectionMode, ChartVisualPreset, ChartSeriesFillPattern, ChartSurfaceStyle.
BeepChart.Properties.cs~25080+ public properties across categories: Title (ShowTitle, ChartTitle, ChartValue, ChartSubtitle, title fonts/colors), Data (DataSeries, LegendLabels, ChartDefaultSeriesColors), Axis (BottomAxisType, LeftAxisType, X/YAxisTitle, X/YLabelAngle, X/YTimeGranularity), Viewport (ViewportXMin/Max, ViewportYMin/Max, CanResetViewport), Interaction (EnableMouseWheelZoom, MouseWheelZoomStepPercent, EnableMouseDragPan, EnableTrackball, TrackballShowCrosshair, EnablePointSelection, SelectionMode), Performance (EnablePerformanceMode, LargeDatasetThreshold, EnablePointCulling, EnableVertexSimplification, SimplificationTolerance), Appearance (ChartDrawingRect, ShowLegend, ChartType, LegendPlacement, SurfaceStyle, AccentColor, Stacked, SmoothLines, ShowMarkers), Theme colors (ChartBackColor, ChartLineColor, ChartFillColor, ChartAxisColor, ChartTitleColor, ChartTextColor, ChartLegendBackColor, ChartLegendTextColor, ChartLegendShapeColor, ChartGridLineColor), Streaming (EnableRealTimeStreaming, StreamRenderThrottleMs, MaxStreamPointsPerSeries).
BeepChart.Methods.cs~20030+ methods: ResetViewport(), AutoScaleViewport(), StartAnimation(int durationMs), ApplyVisualPreset(ChartVisualPreset), FlushStreamingRender(), AppendDataPoint(int seriesIndex, ChartDataPoint, bool flush), AppendDataPoints(int seriesIndex, IEnumerable, bool flush), GetOptimizedPointsForSeries(int), GetCulledPointsForViewport(List), ClearSimplificationCache(), GetPerformanceReport(), GetTotalPointCount(), IsLargeDataset(), ConvertXValue(ChartDataPoint), ConvertYValue(ChartDataPoint).
BeepChart.Events.cs~25018 events: CustomDrawSeries, InteractiveAreaHit, PointHit, AxisHit, LegendHit, PointHoverChanged, ViewportChanged, TrackballDataCollected, SeriesIsolationChanged, SelectionChanged, ContextMenuRequested, KeyboardFocusChanged, PerformanceOptimized, NonColorStateCommunicationChanged, LabelOptimizationApplied, StreamingDataAppended, IncrementalRenderCompleted. Plus 18 dedicated EventArgs classes (CustomDrawSeriesEventArgs, ChartPointHitEventArgs, ChartAxisHitEventArgs, ChartLegendHitEventArgs, ChartPointHoverChangedEventArgs, ChartViewportChangedEventArgs, ChartTrackballDataCollectedEventArgs with ChartTrackballDataPoint, ChartSelectionChangedEventArgs, etc.).
BeepChart.Drawing.cs~400DrawContent override, Paint(Graphics, Rectangle) method, chart render orchestration, painter integration (IChartPainter), custom draw hooks, hit area registration, Dispose (DataPointToolTip, AnimTimer, StreamRenderTimer).

Helper Subsystems (20 Classes)

SubsystemFilesRole
Painter ContractsIChartPainter.cs, IChartSeriesPainter.cs, IChartAxisPainter.cs, IChartLegendPainter.cs4 internal interfaces defining swappable rendering components
Painter ImplementationsCardChartPainter.cs, CartesianAxisPainter.cs, RightSideLegendPainter.cs + 5 series paintersConcrete renderers implementing each interface
SeriesSeriesPainterFactory.cs + Bar/Line/Pie/Area/Bubble series paintersChartType-to-painter resolution, 5 series rendering strategies
DataBeepChartDataHelper.csAuto-detect axis types (Numeric/Date/Text), convert X/Y values, category mapping
ViewportBeepChartViewportHelper.csAuto-scale from data, enforce limits, drawing rect calculation
PerformanceBeepChartPerformanceHelper.csPoint culling, decimation, grid density optimization, label interval recommendation, rendering cost estimation
InputChartInputHelper.cs, ChartPainterBase.csMouse hit testing, trackball crosshair interaction
MetricsChartPainterMetrics.cs, SeriesRenderOptions.csShared constants, layout padding values, series render configuration class

Painting Pipeline

DrawContent(Graphics g)
  -> Paint(Graphics g, Rectangle bounds)
       -> IChartPainter.Initialize(owner, theme)
       -> IChartPainter.AdjustLayout(drawingRect, ctx) -> ChartLayout
            |-- IChartAxisPainter.AdjustPlotRect(g, axisCtx) -> AxisLayout (48px margins)
       -> IChartPainter.DrawBackground(g, ctx)
            |-- CardChartPainter: rounded card background + border
            |-- IChartAxisPainter.DrawAxes(g, axisCtx) -> X/Y axis lines + titles
            |-- IChartAxisPainter.DrawTicks(g, axisCtx) -> numeric | date | text
       -> [foreach DataSeries, palette index]:
            IChartSeriesPainter.DrawSeries(g, plotRect, data, toX, toY,
                xMin, xMax, yMin, yMax, palette, axisColor, textColor, options)
       -> IChartLegendPainter.DrawLegend(g, chartRect, series, palette,
            font, textColor, backColor, shapeColor, owner, onToggleSeries, ...)
       -> IChartPainter.DrawForeground(g, ctx) -> title, subtitle, value
       -> IChartPainter.UpdateHitAreas(owner, ctx, notifyAreaHit)

Painter Contracts (4 Interfaces)

IChartPainter

Top-level chart painter. Handles layout adjustment, background/foreground, and hit area registration. Concrete implementation: CardChartPainter renders charts as cards with rounded corners, title bars, and value text areas.

internal interface IChartPainter
{
    void Initialize(BaseControl owner, IBeepTheme theme);
    ChartLayout AdjustLayout(Rectangle drawingRect, ChartLayout ctx);
    void DrawBackground(Graphics g, ChartLayout ctx);
    void DrawForeground(Graphics g, ChartLayout ctx);
    void UpdateHitAreas(BaseControl owner, ChartLayout ctx,
        Action<string, Rectangle> notifyAreaHit);
}

// ChartLayout data class:
// DrawingRect, PlotRect, Radius, AccentColor, TitleBottom

IChartSeriesPainter

Responsible for rendering individual chart series (bars, lines, pie slices, etc.). Five concrete implementations returned by SeriesPainterFactory.

internal interface IChartSeriesPainter
{
    void Initialize(BaseControl owner);
    void DrawSeries(Graphics g, Rectangle plotRect,
        List<ChartDataSeries> data,
        Func<ChartDataPoint, object> toX,
        Func<ChartDataPoint, object> toY,
        float xMin, float xMax, float yMin, float yMax,
        List<Color> palette, Color axisColor, Color textColor,
        SeriesRenderOptions options);
    void UpdateHitAreas(BaseControl owner, Rectangle plotRect,
        List<ChartDataSeries> data,
        Func<ChartDataPoint, PointF> toScreen,
        Action<string, Rectangle> notifyAreaHit);
}

IChartAxisPainter

Renders coordinate axes with intelligent tick calculation. Concrete implementation: CartesianAxisPainter (internal sealed). AxisLayout data class carries Bounds, PlotRect, BottomAxisType, LeftAxisType, XMin/XMax/YMin/YMax, XTitle/YTitle, XLabelAngle/YLabelAngle, AxisColor, GridLineColor, and category/date epoch data.

IChartLegendPainter

Renders a color-coded series reference panel. Concrete implementation: RightSideLegendPainter. Supports series toggle via onToggleSeries(int) callback and LegendPlacement (Right, Bottom, Top, Left). EnableLegendIsolate enables single-series isolation mode.

Series Painters (5 Types)

SeriesPainterFactory.Get(ChartType) resolves the chart type to its painter. LineSeriesPainter is the default fallback.

ChartTypePainterRendering Style
BarBarSeriesPainterVertical bars with configurable width (BarWidth=0.8) and padding (BarPadding=0.2). Supports stacked mode and data labels on top. Negative values extend downward.
LineLineSeriesPainterConnected line segments with optional cubic Bezier smoothing (SmoothLines). Supports point markers: Circle, Square, Diamond, Triangle at configurable size (default 6px).
PiePieSeriesPainterProportional pie/donut slices. Donut mode when InnerRadius > 0. Exploded slice on hover. Hit areas are pie-slice-shaped polygons.
AreaAreaSeriesPainterFilled polygon below each line to baseline. Semi-transparent (FillOpacity=0.3). Stacked mode accumulates vertically.
BubbleBubbleSeriesPainterProportional circles at XY coordinates. Circle area (not radius) proportional to Size value.

Axis & Legend System

CartesianAxisPainter

Implements IChartAxisPainter. Three-phase rendering:

  • AdjustPlotRect -- Adds 48px margins on all sides of the chart area
  • DrawAxes -- Renders X/Y axis lines and titles (titles drawn rotated)
  • DrawTicks -- Dispatches to three sub-renderers based on axis type:
    • NumericTicks -- "Nice" step sizes: 1, 2, 5, 10, 20, 50, 100, etc. No unnecessary decimal places.
    • DateTicks -- Auto-granularity: < 1h -> minutes, < 24h -> hours, < 30d -> days, < 365d -> months, >= 1y -> years
    • TextTicks -- Category-indexed labels from Dictionary<string,int> map, centered in each column

RightSideLegendPainter

Renders a compact color-coded legend on the right side. Shows colored square + series name per entry. Click toggles visibility. Hidden series crossed-out. Supports overflow scrolling. Colors from ChartDefaultSeriesColors palette.

Viewport & Performance

BeepChartViewportHelper (internal static)

MethodDescription
AutoScaleViewport(chart)Scans all DataSeries points, computes min/max X and Y, adds 10% padding
EnforceViewportLimits(chart)Clamps values, prevents inverted ranges (min > max)
UpdateChartDrawingRectBase(chart)Sets private drawing rect with 40px margins via reflection

BeepChartPerformanceHelper (public static)

MethodReturnsDescription
CullPointsOutsideViewport(...)List<ChartDataPoint>Filters to visible points only (always keeps first + last)
DecimatePoints(points, factor)List<ChartDataPoint>Reduces by taking every Nth (always includes last)
EstimateDecimationFactor(count, target=200)intComputes factor to reach target point count
OptimizeGridDensity(size, zoom)intRecommended grid interval based on dataset + zoom
RecommendLabelInterval(size, range%)intSkip factor to avoid label overcrowding
EstimateRenderingCost(points, pixels)float0.0-1.0 cost estimate (points per pixel ratio)
ShouldOptimizePerformance(count, threshold)boolTrue when count exceeds threshold (default 10,000)

Data Pipeline

BeepChartDataHelper (internal static)

// DetectAxisTypes(chart) -- reads first point of first series:
//   float.TryParse -> AxisType.Numeric
//   DateTime.TryParse -> AxisType.Date
//   else -> AxisType.Text (with Dictionary category map)

// ConvertXValue(chart, point) / ConvertYValue(chart, point):
//   Numeric: float.TryParse(value)
//   Date: (DateTime.Parse(value) - dateMin).TotalDays
//   Text: categoryMap[value] index

SeriesRenderOptions

PropertyTypeDefaultEffect
BarWidthfloat0.8Bar fraction of cell width
BarPaddingfloat0.2Gap between bars
ShowDataLabelsboolfalseValue text on bars/slices
SmoothLinesboolfalseCubic Bezier interpolation
ShowMarkersbooltruePoint markers on lines
MarkerShapeMarkerStyleCircleCircle/Square/Diamond/Triangle
MarkerSizeint6Marker radius in px
FillOpacityfloat0.3Area transparency (0-1)
InnerRadiusfloat0Pie donut hole (0=full pie)
StackedboolfalseAccumulate bars/areas vertically

Interaction & Trackball

ChartInputHelper supports:

  • Trackball -- Crosshair overlay with multi-series tooltip values. Configurable colors and width.
  • MouseWheelZoom -- Ctrl+Wheel zooms in/out (configurable step percent)
  • MouseDragPan -- Click-drag pans the viewport (configurable factor)
  • KeyboardNavigation -- Arrow keys for pan, +/- for zoom, configurable step percent
  • PointHover -- DataPointToolTip on hover with point details
  • PointSelection -- Click to select with visual highlight, configurable selection color/marker
  • LegendIsolate -- Click legend item to isolate single series. Click again to restore all.

18 dedicated events enable full integration: CustomDrawSeries, InteractiveAreaHit, PointHit, AxisHit, LegendHit, PointHoverChanged, ViewportChanged, TrackballDataCollected, SeriesIsolationChanged, SelectionChanged, ContextMenuRequested, KeyboardFocusChanged, PerformanceOptimized, NonColorStateCommunicationChanged, LabelOptimizationApplied, StreamingDataAppended, IncrementalRenderCompleted.

Key Enums & EventArgs

EnumValues
ChartSelectionModeSingle, Multiple
ChartVisualPresetDashboard (compact, embedded), Analytical (full, exploration), HighContrast (accessibility), Print (B&W safe), Presentation (large fonts)
ChartSeriesFillPatternSolid, Horizontal, Vertical, Diagonal, BackDiagonal, Cross, DiagonalCross, Dots
ChartSurfaceStyleClassic (flat), Card (rounded, shadow), Outline (border-only), Glass (transparency)

18 EventArgs classes in BeepChart.Events.cs: CustomDrawSeriesEventArgs (Graphics, series index), ChartPointHitEventArgs (series, index, point, screen location), ChartAxisHitEventArgs (axis, value, label), ChartLegendHitEventArgs (series index, toggle), ChartPointHoverChangedEventArgs (old/new point), ChartViewportChangedEventArgs (xMin/xMax/yMin/yMax), ChartTrackballDataCollectedEventArgs (screen point, data points list with ChartTrackballDataPoint), ChartSelectionChangedEventArgs (selected points list), ChartPerformanceOptimizedEventArgs (before/after point counts), ChartStreamingDataAppendedEventArgs (series index, new point count), ChartIncrementalRenderCompletedEventArgs (render time).

Code Examples

Basic Bar Chart

var chart = new BeepChart();
chart.ChartType = ChartType.Bar;
chart.ChartTitle = "Quarterly Revenue";
chart.ShowLegend = true;
chart.LegendPlacement = LegendPlacement.Right;

chart.DataSeries.Add(new ChartDataSeries
{
    SeriesName = "Q1 Revenue",
    DataPoints = new List<ChartDataPoint>
    {
        new ChartDataPoint { X = "Product A", Y = "1200" },
        new ChartDataPoint { X = "Product B", Y = "800" },
        new ChartDataPoint { X = "Product C", Y = "1500" }
    }
});

Large Dataset with Performance Mode

chart.EnablePerformanceMode = true;
chart.LargeDatasetThreshold = 50000;
chart.EnablePointCulling = true;
chart.EnableVertexSimplification = true;
chart.ResetViewport();

if (BeepChartPerformanceHelper.ShouldOptimizePerformance(
    chart.GetTotalPointCount(), chart.LargeDatasetThreshold))
{
    float cost = BeepChartPerformanceHelper.EstimateRenderingCost(
        chart.GetTotalPointCount(), chart.Width);
    Console.WriteLine($"Rendering cost: {cost:P0}");
}

Real-Time Streaming

chart.EnableRealTimeStreaming = true;
chart.StreamRenderThrottleMs = 50;   // render batch interval
chart.MaxStreamPointsPerSeries = 1000; // rolling window

chart.StreamingDataAppended += (s, e) =>
    Console.WriteLine($"Stream: {e.NewPointCount} points");

chart.AppendDataPoint(0, new ChartDataPoint
    { X = DateTime.Now.ToString("o"), Y = sensorValue.ToString() });

Interactive Zoom/Pan with Trackball

chart.EnableMouseWheelZoom = true;
chart.EnableMouseDragPan = true;
chart.EnableTrackball = true;
chart.TrackballShowCrosshair = true;
chart.TrackballShowMultiSeriesValues = true;

chart.ViewportChanged += (s, e) =>
    Console.WriteLine($"Viewport: {e.XMin}-{e.XMax}, {e.YMin}-{e.YMax}");