Skip to main content

Chart Rendering Reference

Advanced indicators and tools can render directly through IChartOverlayRenderer. This is the preferred API for custom visual layers such as order-flow, volume profile, bar timers, heatmaps, and advanced labels.

Overlay Renderer Interface

public class MyOverlay : Indicator, IChartOverlayRenderer
{
public ChartRenderPass RenderPass => ChartRenderPass.OverDrawings;
public bool RenderOnPricePanel => true;

public void OnRender(IChartRenderContext context)
{
// Draw with context methods.
}
}

Render Passes

PassUse case
UnderCandlesBackground zones and heatmaps.
OverCandlesOverlays that should sit above bars but below drawings.
OverDrawingsLabels, HUD elements, and top-level overlays.

Render Backends

The render context reports its backend:

  • Wpf
  • Direct2D
  • Skia

Scripts should use the abstract context methods and avoid backend-specific assumptions unless the script explicitly checks context.Backend.

IChartRenderContext

MemberPurpose
BackendCurrent render backend.
PassCurrent render pass.
IsMainPaneWhether this context is the main price pane.
PaneIdCurrent pane identifier.
VisibleFromIndexFirst visible bar index.
VisibleToIndexLast visible bar index.
VisibleCountCount of visible bars.
CandleWidthCurrent candle body width.
CandleGapGap between candles.
TickSizeCurrent instrument tick size.
PriceMinVisible low scale value for the pane.
PriceMaxVisible high scale value for the pane.
WidthRender area width.
HeightRender area height.

Coordinate Methods

double x = context.GetXByBarIndex(barIndex);
double y = context.GetYByPrice(price);
double price = context.GetPriceByY(y);
int barIndex = context.GetNearestBarIndex(x);

Use these methods instead of duplicating chart scale math.

Drawing Methods

context.DrawLine(start, end, stroke);
context.DrawRectangle(rect, fill, stroke);
context.DrawCircle(center, radius, fill, stroke);
context.DrawText(text, bounds, style);

Basic types:

  • ChartPoint
  • ChartRect
  • ChartPaint
  • ChartStroke
  • ChartTextStyle

Example

public void OnRender(IChartRenderContext context)
{
if (!context.IsMainPane || context.VisibleCount <= 0)
return;

var paint = new ChartPaint(Colors.DeepSkyBlue, 0.9);
var stroke = new ChartStroke(paint, 1.5, ChartDashStyle.Solid);

double y = context.GetYByPrice(Close[0]);
context.DrawLine(
new ChartPoint(0, y),
new ChartPoint(context.Width, y),
stroke);
}

Performance Rules

  • Keep OnRender allocation-light.
  • Do not fetch historical data from inside OnRender.
  • Precompute expensive values during script updates.
  • Use visible indexes to limit loops.
  • Use InvalidateChartVisual() when only visuals changed.
  • Use InvalidateChart() only when scale/extremum state changed.