Skip to main content
Table of Contents

Events

Chart events cover virtual data, custom formatting, custom drawing, interaction, persistence filtering, and adapter conversion. Prefer events when the chart needs dynamic behavior that cannot be expressed as static series or appearance settings.

Virtual Data Events

Use virtual data events when values remain outside the chart:

Event Use
OnGetNumberOfPoints Return the number of points for a series.
OnGetPoint Fill a virtual point record for the requested index.
OnGetNumberOfAnnotations Return the number of annotations for a virtual point.
OnGetAnnotation Fill a virtual annotation record.

Handling these events switches the chart to virtual mode for the whole control — you do not add anything to the Series collection. OnGetNumberOfPoints and OnGetPoint are the minimum needed; add OnGetNumberOfAnnotations and OnGetAnnotation when virtual points should also carry annotations. The handler below serves five values from a plain array and annotates only the peak points:

Pascal
{ ── Virtual data: serve points and annotations from your own storage ────── }
{ Handling these events enables virtual mode for the whole chart; no points  }
{ are added to the Series collection.                                        }
const
  PointValues: array[0..4] of Double = (12, 28, 31, 26, 37);

procedure TForm1.TMSFNCChart1GetNumberOfPoints(Sender: TObject;
  ASerie: TTMSFNCChartSerie; var ANumberOfPoints: Integer);
begin
  ANumberOfPoints := Length(PointValues);
end;

procedure TForm1.TMSFNCChart1GetPoint(Sender: TObject;
  ASerie: TTMSFNCChartSerie; AIndex: Integer;
  var APoint: TTMSFNCChartPointVirtual);
begin
  APoint.XValue := AIndex + 1;
  APoint.YValue := PointValues[AIndex];
  APoint.XValueText := Format('P%d', [AIndex + 1]);
end;

{ Annotate only the peak points whose value clears the threshold. }
procedure TForm1.TMSFNCChart1GetNumberOfAnnotations(Sender: TObject;
  ASerie: TTMSFNCChartSerie; APoint: TTMSFNCChartPointVirtual;
  var ANumberOfAnnotations: Integer);
begin
  if APoint.YValue > 30 then
    ANumberOfAnnotations := 1
  else
    ANumberOfAnnotations := 0;
end;

procedure TForm1.TMSFNCChart1GetAnnotation(Sender: TObject;
  ASerie: TTMSFNCChartSerie; APoint: TTMSFNCChartPointVirtual; AIndex: Integer;
  var AAnnotation: TTMSFNCChartAnnotationVirtual);
begin
  AAnnotation.Visible := True;
  AAnnotation.Text := Format('Peak: %.0f', [APoint.YValue]);
end;

See Series and points for a points-only virtual example with a screenshot.

Formatting Events

Assign OnGetSerieXValue to replace the calculated x-axis label text. Use it to convert numeric x-values into meaningful strings — dates, categories, or units.

Event Use
OnGetSerieXValue Customize x-axis value text.
OnGetSerieYValue Customize y-axis value text.
OnGetSerieLabel Customize labels for collection-based points.
OnGetSerieLabelVirtual Customize labels for virtual points.
OnGetSerieLegendText Customize legend text.
Pascal
{ ── Formatting: custom x-axis labels from a date offset ─────────────────── }

procedure TForm1.TMSFNCChart1GetSerieXValue(Sender: TObject;
  ASerie: TTMSFNCChartSerie; AIndex: Integer;
  AKind: TTMSFNCChartDrawXYValueKind; AValue: Double;
  var AValueString: String);
var
  BaseDate: TDate;
begin
  BaseDate := EncodeDate(2024, 1, 1);
  AValueString := FormatDateTime('d mmm', BaseDate + AValue);

Drawing Events

Drawing events are paired as OnBeforeDraw... and OnAfterDraw... events. Use them to customize chart background, title, axes, grid lines, labels, legend items, bars, lines, markers, slices, and crosshair elements. Set custom stroke or fill properties in the before-draw handler and leave ADefaultDraw := True so the chart draws the styled element, or set it to False to take over completely.

Examples include OnBeforeDrawSerieLine, OnAfterDrawSerieMarker, OnBeforeDrawSerieSlice, and OnAfterDrawTitle.

Pascal

{ ── Drawing: colour a line segment above a threshold differently ──────────── }

procedure TForm1.TMSFNCChart1BeforeDrawSerieLine(Sender: TObject;
  AGraphics: TTMSFNCGraphics; ASerie: TTMSFNCChartSerie;
  var ADrawLine: TTMSFNCChartDrawLine; var ADefaultDraw: Boolean);
const
  Threshold = 50.0;
begin
  if Assigned(ADrawLine.StartReference)
    and (ADrawLine.StartReference.YValue > Threshold) then
  begin
    AGraphics.Stroke.Color := $FFFF6600;   { orange above threshold }
    AGraphics.Stroke.Width := 2.5;
  end
  else
  begin
    AGraphics.Stroke.Color := ASerie.Stroke.Color;
    AGraphics.Stroke.Width := ASerie.Stroke.Width;

The handler above recolours each line segment whose start value is above a threshold, leaving the rest in the series' default stroke — the orange segments below are drawn entirely by the event:

Line chart whose segments above a threshold are recoloured by OnBeforeDrawSerieLine Line chart whose segments above a threshold are recoloured by OnBeforeDrawSerieLine in dark theme

Interaction Events

Use click and hit-test events to react to chart elements. OnSeriePointClick receives the TTMSFNCChartPoint that was clicked — read YValue, XValueText, and DataObject to display details or drive selection logic.

Event Use
OnSeriePointClick A collection-based point was clicked.
OnSeriePointClickVirtual A virtual point was clicked.
OnSerieBarClick A bar was clicked.
OnSeriesliceClick A pie or slice element was clicked.
OnSerieAreaClick The filled body of an area or bar series was clicked.
OnSerieAreaVirtualClick The filled body of a virtual-data series was clicked.
OnLegendItemClick A chart legend item was clicked.
OnTitleClick The title area was clicked.
Pascal
{ ── Interaction: respond to a point click ──────────────────────────────── }

procedure TForm1.TMSFNCChart1SeriePointClick(Sender: TObject;
  APoint: TTMSFNCChartPoint);
begin
  ShowMessage(Format('Series %d  X=%s  Y=%.2f',
    [APoint.Collection.Owner.Index,
     APoint.XValueText,
     APoint.YValue]));
end;

OnSeriePointClick reacts to a single point or bar, while OnSerieAreaClick reacts to a click anywhere on a series' filled body — useful for selecting or drilling into a whole area/bar series rather than one value. Its handler receives the TTMSFNCChartSerie that was hit; use the virtual variant when the series is driven by virtual-data events.

Pascal
procedure TForm1.TMSFNCChart1SerieAreaClick(Sender: TObject;
  ASerie: TTMSFNCChartSerie);
begin
  // The older release note called this OnAreaClick; in the current API the
  // event is OnSerieAreaClick for collection-backed series.
  // Fires when the filled body of an area/bar series is clicked (not just a
  // point or bar). ASerie identifies which series was hit - select it, toggle
  // its visibility, or drill into its data.
  ShowMessage('Area clicked: ' + ASerie.LegendText);
end;

Persistence Events

Use OnCanSaveProperty and OnCanLoadProperty to keep specific properties out of persisted settings. Both handlers receive the property name and type and expose a var flag — set it to False to exclude the property. Mirror the same condition in both handlers so a property dropped on save is also ignored on load:

Pascal
{ ── Persistence: keep runtime-only properties out of saved settings ──────── }
{ Return False from OnCanSaveProperty to drop a property from persisted state, }
{ and mirror it in OnCanLoadProperty so the same property is ignored on load.  }

procedure TForm1.TMSFNCChart1CanSaveProperty(Sender: TObject; AObject: TObject;
  APropertyName: string; APropertyType: TTypeKind; var ACanSave: Boolean);
begin
  if SameText(APropertyName, 'Name') then
    ACanSave := False;
end;

procedure TForm1.TMSFNCChart1CanLoadProperty(Sender: TObject; AObject: TObject;
  APropertyName: string; APropertyType: TTypeKind; var ACanLoad: Boolean);
begin
  if SameText(APropertyName, 'Name') then
    ACanLoad := False;
end;

Combining drawing and interaction events

Wire OnBeforeDrawSerieLine for threshold-based colour changes and OnSeriePointClick for point details simultaneously — they compose without conflict because each fires at a different phase of chart rendering and user input.

Pascal
end;

{ ── Combined: threshold colouring + click info side-by-side ─────────────── }
{ Wire both OnBeforeDrawSerieLine and OnSeriePointClick to the same chart.   }
API Purpose
TTMSFNCChart Event owner.
TTMSFNCChartPoint Point data accessed in click events.
TTMSFNCChartPointVirtual Virtual point data.
TTMSFNCChartAnnotationVirtual Virtual annotation data.

See Also