Configuration: Range, Layout, Division, and Interaction
This guide covers the structural settings of TTMSFNCTimeline — the time range it displays, the orientation and size of the bar, how the division marks are rendered, and what the user can interact with.
Range
The Range sub-object defines the span of time visible in the timeline.
| Property | Description |
|---|---|
RangeType |
Time unit per division: tlrDay, tlrMonth, tlrYear, tlrHour, tlrMinute, tlrSecond, tlrMilliSecond, tlrValue (numeric). Default: tlrDay. |
MinimumDate / MaximumDate |
Start and end of the displayable range as TDateTime. |
MinimumValue / MaximumValue |
Same bounds as numeric doubles (linked to date properties). |
DivisionSpace |
Pixels between division tick marks at zoom factor 1. Default: 40. |
DivisionSpan |
How many time units each division represents. E.g. DivisionSpan = 7 with tlrDay gives weekly marks. |
// Show January 2025 with one division per day, 60 px wide
TMSFNCTimeline1.Range.MinimumDate := EncodeDate(2025, 1, 1);
TMSFNCTimeline1.Range.MaximumDate := EncodeDate(2025, 1, 31);
TMSFNCTimeline1.Range.RangeType := tlrDay;
TMSFNCTimeline1.Range.DivisionSpace := 60;
Numeric ranges
Set RangeType := tlrValue and assign MinimumValue / MaximumValue directly for non-date data (e.g. version numbers, engineering values):
TMSFNCTimeline1.Range.RangeType := tlrValue;
TMSFNCTimeline1.Range.MinimumValue := 0;
TMSFNCTimeline1.Range.MaximumValue := 100;
TMSFNCTimeline1.Range.DivisionSpace := 40;
Layout
Layout controls the orientation, size, and presentation of the timeline bar.
| Property | Description |
|---|---|
Orientation |
tloHorizontal (default) or tloVertical. |
Position |
Where the timeline bar sits: tlpMiddle (default), tlpTopLeft, tlpBottomRight. |
Size |
Thickness of the timeline bar in pixels. Default: 32. |
FullSize |
True makes the bar fill the full available width/height. |
Margins |
Padding around the control content. |
ZoomFactor |
Zoom multiplier (1.0 = 100%). Affects the effective DivisionSpace. |
ShowScrollBar |
Whether the scroll bar is visible when content overflows. |
MultiSelect |
Allow selecting multiple indicators and sections simultaneously. Default: False. |
IndicatorAnnotationSpacing |
Gap between adjacent annotations when they stack. |
IndicatorHoverBehavior |
tlibBoth — hover shows both indicator and annotation; tlibAlwaysItem — always show indicator; tlibAlwaysAnnotation — always show annotation; tlibSeperate — independent hover for each. |
DrawSectionsBeneathDivisions |
Render sections below the division label area when True. Default: False. |
OverlapSections |
When True, sections can overlap; otherwise they share the space equally. |
ShowHoveredItems |
Highlight items when the cursor is over them. |
Zoom control
TMSFNCTimeline1.SetZoomFactor(1.5); // 150% zoom
TMSFNCTimeline1.IncreaseZoomFactor(10); // +10%
TMSFNCTimeline1.DecreaseZoomFactor(10); // -10%
TMSFNCTimeline1.ResetZoomFactor; // back to 100%
Scrolling to a value
// Center the view on a date
TMSFNCTimeline1.CenterValue(Now);
// Scroll so a date appears at the start of the view
TMSFNCTimeline1.ValueVisibleStart(EncodeDate(2025, 6, 1));
// Scroll so a date appears at the end of the view
TMSFNCTimeline1.ValueVisibleEnd(EncodeDate(2025, 6, 30));
Check visibility before scrolling:
if not TMSFNCTimeline1.IsValueVisible(EncodeDate(2025, 6, 15)) then
TMSFNCTimeline1.CenterValue(EncodeDate(2025, 6, 15));
Division
The Division sub-object configures the tick marks and labels drawn along the timeline.
| Property | Description |
|---|---|
Position |
tlpTopLeft, tlpMiddle (default), tlpBottomRight — which side of the bar the division sits on. |
Size |
Height of the division area. -1 = automatic. |
DrawText |
Show date/value labels. |
DrawTickMark |
Show tick marks. |
TickMarkSize |
Tick mark height in pixels. Default: 8. |
TextFormat |
Format string for division labels (e.g. 'dd/mm', 'MMM yyyy'). |
TextPosition |
gtaLeft, gtaCenter (default), gtaRight. |
TextWordWrap |
Wrap long labels. |
TextOrientation |
Rotate label text: tltoHorizontal, tltoLeft, tltoRight, tltoUpsideDown. |
Custom label text — override via OnGetValueText:
procedure TFormMain.TMSFNCTimeline1GetValueText(
Sender: TObject; AValue: Double; var AText: String);
begin
// Show only the day-of-week abbreviation
AText := FormatDateTime('ddd', AValue);
end;
Interaction
Interaction controls what the user can do with items and the timeline scrolling.
| Property | Description |
|---|---|
CanMoveIndicator |
Allow dragging indicators. |
CanMoveIndicatorWithAnnotation |
Allow dragging via the annotation label. |
CanMoveSection |
Allow moving sections (shifts start and end together). |
CanSizeSectionStart |
Allow resizing the section's start boundary. |
CanSizeSectionEnd |
Allow resizing the section's end boundary. |
InvertedMouseScroll |
Reverse mouse-wheel scroll direction. |
InvertedMouseDrag |
Reverse mouse-drag scroll direction. |
Constraining movement
Use OnIndicatorMove and OnSectionMove to validate or cancel a move before it commits:
procedure TFormMain.TMSFNCTimeline1IndicatorMove(
Sender: TObject; AIndicator: TTMSFNCTimelineIndicator;
var AValue: Double; var AAllow: Boolean);
begin
// Snap to the nearest whole day
AValue := Trunc(AValue);
end;
procedure TFormMain.TMSFNCTimeline1SectionMove(
Sender: TObject; ASection: TTMSFNCTimelineSection;
var AStartValue, AEndValue: Double; var AAllow: Boolean);
begin
// Prevent moving past the range start
if AStartValue < TMSFNCTimeline1.Range.MinimumValue then
AAllow := False;
end;
Appearance
Appearance covers the default visual style for the timeline bar and its items.
| Property | Description |
|---|---|
TimelineFill |
Background fill of the timeline bar. |
TimelineStroke |
Border of the timeline bar. |
DivisionFont |
Font for division labels. |
DivisionTickmarkStroke |
Stroke style of tick marks. |
Rounding |
Corner radius of the timeline bar. |
DefaultIndicatorAppearance |
Default shape, fill, stroke, and size for all new indicators. |
DefaultAnnotationAppearance |
Default font, fill, and stroke for all new annotations. |
DefaultSectionAppearance |
Default fill, stroke, and text settings for all new sections. |
Combining configuration, items, and appearance
uses
FMX.TMSFNCTimeline;
// Combined: date range, vertical layout, interactive sections,
// scrolling to today, and OnSectionMove constraint.
procedure TFormMain.BuildProjectTimeline;
var
sec: TTMSFNCTimelineSection;
ind: TTMSFNCTimelineIndicator;
begin
TMSFNCTimeline1.BeginUpdate;
// Range — Q1 2025, one division per week
TMSFNCTimeline1.Range.MinimumDate := EncodeDate(2025, 1, 1);
TMSFNCTimeline1.Range.MaximumDate := EncodeDate(2025, 3, 31);
TMSFNCTimeline1.Range.RangeType := tlrDay;
TMSFNCTimeline1.Range.DivisionSpan := 7; // 7 days per division mark
TMSFNCTimeline1.Range.DivisionSpace := 100;
// Layout — vertical, full size
TMSFNCTimeline1.Layout.Orientation := tloVertical;
TMSFNCTimeline1.Layout.FullSize := True;
TMSFNCTimeline1.Layout.MultiSelect := True;
// Interaction — allow moving sections, not indicators
TMSFNCTimeline1.Interaction.CanMoveSection := True;
TMSFNCTimeline1.Interaction.CanMoveIndicator := False;
TMSFNCTimeline1.Interaction.CanSizeSectionStart := True;
TMSFNCTimeline1.Interaction.CanSizeSectionEnd := True;
// Sections (project phases)
sec := TMSFNCTimeline1.Sections.Add;
sec.StartTimelineDate := EncodeDate(2025, 1, 6);
sec.EndTimelineDate := EncodeDate(2025, 1, 31);
sec.Text := 'Discovery';
sec.Appearance.Fill.Color := gcCornflowerBlue;
sec.Appearance.Fill.ColorTo := gcRoyalBlue;
sec := TMSFNCTimeline1.Sections.Add;
sec.StartTimelineDate := EncodeDate(2025, 2, 3);
sec.EndTimelineDate := EncodeDate(2025, 2, 28);
sec.Text := 'Development';
sec.Appearance.Fill.Color := gcMediumSeaGreen;
// Milestone indicator
ind := TMSFNCTimeline1.Indicators.Add;
ind.TimelineDate := EncodeDate(2025, 3, 14);
ind.Annotation.Text := 'Beta release';
ind.Appearance.Shape := tlisDiamond;
ind.Appearance.Fill.Color := gcOrange;
ind.Fixed := True;
TMSFNCTimeline1.OnSectionMove := SectionMoveConstraint;
TMSFNCTimeline1.OnIndicatorSelectionChanged := IndicatorSelected;
TMSFNCTimeline1.EndUpdate;
// Scroll to today
TMSFNCTimeline1.CenterValue(Now);
end;
procedure TFormMain.SectionMoveConstraint(
Sender: TObject; ASection: TTMSFNCTimelineSection;
var AStartValue, AEndValue: Double; var AAllow: Boolean);
begin
// Keep sections within the configured range
if AStartValue < TMSFNCTimeline1.Range.MinimumValue then
AAllow := False;
if AEndValue > TMSFNCTimeline1.Range.MaximumValue then
AAllow := False;
end;
procedure TFormMain.IndicatorSelected(
Sender: TObject; AIndicator: TTMSFNCTimelineIndicator; ASelected: Boolean);
begin
if ASelected then
StatusBar1.SimpleText := 'Selected: ' + AIndicator.Annotation.Text;
end;