Overview
FireMonkey (FMX) enables true cross-platform development with a single codebase that runs on Windows, macOS, iOS, and Android. This guide covers platform-specific considerations and best practices for TeeChart FMX applications.
TeeChart FMX automatically scales and adapts to different screen sizes and resolutions, but you’ll need to handle platform-specific UI adjustments and feature availability.
Windows Full feature support with desktop optimization
macOS Native macOS application with Cocoa framework
iOS iPhone and iPad with touch optimization
Android Mobile and tablet with Material Design support
Conditional Compilation
Use compiler directives to include platform-specific code:
uses
System.SysUtils, FMXTee.Engine, FMXTee.Chart,
{$IFNDEF IOS}
FireDAC.Phys.ODBCBase, // Not available on iOS
{$ENDIF}
{$IFDEF MSWINDOWS}
Winapi.Windows,
{$ENDIF MSWINDOWS}
FMXTee.Editor.Series.WorldMap;
Common compiler directives:
{$IFDEF MSWINDOWS}
// Windows-specific code
{$ENDIF}
{$IFDEF MACOS}
// macOS-specific code
{$ENDIF}
{$IFDEF IOS}
// iOS-specific code
{$ENDIF}
{$IFDEF ANDROID}
// Android-specific code
{$ENDIF}
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
// Mobile platforms (iOS or Android)
{$ENDIF}
{$IF DEFINED(MACOS) and not DEFINED(IOS)}
// macOS only (not iOS)
{$ENDIF}
UI Adaptations
Font Sizing
Adjust font sizes for different platforms and screen densities:
procedure TDashForm.Init ;
begin
// Desktop platforms
{$IFDEF MACOS}
Layout4.Height := 192 ;
LBTotalSales.TextSettings.Font.Size := 14 ;
Label5.TextSettings.Font.Size := 14 ;
LBTotalItemsSold.TextSettings.Font.Size := 14 ;
{$ELSE}
Layout4.Height := 256 ;
LBTotalSales.TextSettings.Font.Size := 18 ;
Label5.TextSettings.Font.Size := 18 ;
LBTotalItemsSold.TextSettings.Font.Size := 18 ;
{$ENDIF}
// Mobile platforms
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
LBTotalSales.TextSettings.Font.Size := 10 ;
Label5.TextSettings.Font.Size := 10 ;
LBTotalItemsSold.TextSettings.Font.Size := 10 ;
LBTotalSalesCountry.TextSettings.Font.Size := 10 ;
LBTotalSalesCountryValue.TextSettings.Font.Size := 10 ;
{$ENDIF}
end ;
Legend and Mark Sizing
procedure ConfigureChart ;
begin
{$IFDEF IOS}
BarChart.Legend.Font.Size := 10 ;
DonutSeries.Marks.Visible := False ; // Too small on iPhone
{$ENDIF}
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
// Larger touch targets on mobile
Chart1.Legend.Symbol.Width := 30 ;
Chart1.Legend.Symbol.Height := 20 ;
{$ENDIF}
end ;
Create device-specific form layouts:
Layout File Structure
MainFrm.fmx # Default layout
MainFrm.iPad.fmx # iPad-specific layout
MainFrm.XLgXhdpiTb.fmx # Large tablet layout
MainFrm.iPhone.fmx # iPhone-specific layout
FireMonkey automatically loads the appropriate layout file based on:
Device type (phone/tablet)
Screen size
Orientation
Platform (iOS/Android)
Create platform-specific layouts by right-clicking the form in the IDE and selecting “Add View” → “Device View”.
Feature Availability
Chart Editor
The visual chart editor is not available on iOS:
procedure TDashForm.AreaChartDblClick (Sender: TObject);
{$IFNDEF IOS}
var
ChartEditor: TChartEditor;
{$ENDIF}
begin
{$IFNDEF IOS}
ChartEditor := TChartEditor.Create(Self);
ChartEditor.Chart := TChart(Sender);
ChartEditor.Execute;
{$ENDIF}
end ;
Database Drivers
Some database drivers are platform-specific:
uses
FireDAC.Stan.Intf,
FireDAC.Phys.Intf,
{$IFNDEF IOS}
FireDAC.Phys.ODBCBase, // ODBC not available on iOS
FireDAC.Phys.MSSQL, // SQL Server not on mobile
{$ENDIF}
FireDAC.Phys.SQLite; // SQLite available on all platforms
File System Access
procedure SaveChartToFile ;
var
FilePath: string ;
begin
{$IFDEF MSWINDOWS}
FilePath := 'C:\Temp\chart.tee' ;
{$ENDIF}
{$IFDEF MACOS}
FilePath := GetHomePath + '/Documents/chart.tee' ;
{$ENDIF}
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
FilePath := TPath.GetDocumentsPath + PathDelim + 'chart.tee' ;
{$ENDIF}
Chart1.SaveToFile(FilePath);
end ;
Touch vs Mouse Interaction
Touch Optimization
procedure TForm1.FormCreate (Sender: TObject);
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
// Larger touch targets
Chart1.Legend.Symbol.Width := 40 ;
// Disable hover effects (no mouse)
Chart1.Hover.Visible := False ;
// Enable touch gestures
Chart1.Touch.GestureManager := GestureManager1;
Chart1.Touch.InteractiveGestures :=
[TInteractiveGesture.Zoom, TInteractiveGesture.Pan];
{$ELSE}
// Desktop: enable hover and mouse wheel zoom
Chart1.Hover.Visible := True ;
Chart1.AllowZoom := True ;
Chart1.Zoom.MouseWheel := pmwNormal;
{$ENDIF}
end ;
Click vs Touch Events
procedure ChartClickSeries (Sender: TCustomChart; Series: TChartSeries;
ValueIndex: Integer ; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer );
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
// Provide visual feedback for touch
ShowSelectionIndicator(ValueIndex);
{$ELSE}
// Desktop: show tooltip
ShowTooltip(X, Y, Series.Labels[ValueIndex]);
{$ENDIF}
end ;
Mobile-Specific Optimizations
procedure OptimizeForMobile ;
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
// Reduce quality for better performance
Chart1.AntiAlias := False ;
Chart1.View3D := False ; // 3D rendering is slower on mobile
// Simplify gradients
Chart1.Gradient.Visible := False ;
Series1.Gradient.Visible := False ;
// Reduce animation duration
Animation1.Duration := 500 ; // Faster on mobile
// Disable shadows
Chart1.Shadow.Visible := False ;
{$ENDIF}
end ;
Fast Line for Large Datasets
procedure CreateLargeDataChart ;
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
// Use FastLine for better performance
var FastLineSeries := TFastLineSeries.Create(Self);
Chart1.AddSeries(FastLineSeries);
{$ELSE}
// Desktop can handle regular line series
var LineSeries := TLineSeries.Create(Self);
Chart1.AddSeries(LineSeries);
{$ENDIF}
end ;
Screen Orientation
Handling Rotation
procedure TForm1.FormResize (Sender: TObject);
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
if Width > Height then
begin
// Landscape orientation
Chart1.Legend.Alignment := laRight;
Chart1.Legend.TextStyle := ltsPlain;
end
else
begin
// Portrait orientation
Chart1.Legend.Alignment := laBottom;
Chart1.Legend.TextStyle := ltsLeftValue;
end ;
{$ENDIF}
end ;
Responsive Design Patterns
Adaptive Layouts
procedure TForm1.FormShow (Sender: TObject);
begin
// Adapt to screen width
if Width < 600 then
begin
// Phone or small screen
GridPanelLayout1.ColumnCollection[ 0 ].Value := 100 ; // Single column
Chart1.Legend.Visible := False ;
Chart1.Title.Visible := False ;
end
else if Width < 1024 then
begin
// Tablet
GridPanelLayout1.ColumnCollection[ 0 ].Value := 50 ; // Two columns
Chart1.Legend.Visible := True ;
end
else
begin
// Desktop
GridPanelLayout1.ColumnCollection[ 0 ].Value := 33.3 ; // Three columns
Chart1.Legend.Visible := True ;
Chart1.Title.Visible := True ;
end ;
end ;
Resource Management
function GetResourcePath : string ;
begin
{$IFDEF MSWINDOWS}
Result := ExtractFilePath(ParamStr( 0 )) + 'Resources\\' ;
{$ENDIF}
{$IFDEF MACOS}
{$IFDEF IOS}
Result := TPath.GetDocumentsPath + '/Resources/' ;
{$ELSE}
Result := TPath.GetHomePath + '/Resources/' ;
{$ENDIF}
{$ENDIF}
{$IFDEF ANDROID}
Result := TPath.GetDocumentsPath + '/Resources/' ;
{$ENDIF}
end ;
Multi-Device Testing Checklist
Windows - Test on different DPI settings (96, 120, 144 DPI)
macOS - Test on Retina and non-Retina displays
iOS - Test on iPhone (various sizes) and iPad
Android - Test on different screen sizes and densities
Orientation - Test landscape and portrait modes
Performance - Profile on actual devices, not just simulators
procedure LogPlatformInfo ;
begin
{$IFDEF DEBUG}
Memo1.Lines. Add ( 'Platform: ' +
{$IFDEF MSWINDOWS} 'Windows' {$ENDIF}
{$IFDEF MACOS}{$IFNDEF IOS} 'macOS' {$ELSE} 'iOS' {$ENDIF}{$ENDIF}
{$IFDEF ANDROID} 'Android' {$ENDIF}
);
Memo1.Lines. Add ( 'Screen Size: ' +
Screen.Width.ToString + 'x' + Screen.Height.ToString);
Memo1.Lines. Add ( 'DPI: ' + Screen.PixelsPerInch.ToString);
{$ENDIF}
end ;
Deployment Considerations
Windows
Package TeeChart DLLs with application
Consider installer (Inno Setup, InstallShield)
Code signing for distribution
macOS
// macOS bundle structure
MyApp.app/
Contents/
MacOS/ # Executable
Resources/ # Charts, images, data
Info.plist # App metadata
iOS
App Store submission requirements
Provisioning profiles and certificates
Asset catalog for different resolutions
Android
APK/AAB packaging
Different screen densities (ldpi, mdpi, hdpi, xhdpi, xxhdpi)
Permissions in AndroidManifest.xml
Common Patterns
function IsMobilePlatform : Boolean ;
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
Result := True ;
{$ELSE}
Result := False ;
{$ENDIF}
end ;
function IsDesktopPlatform : Boolean ;
begin
{$IF DEFINED(MSWINDOWS) or (DEFINED(MACOS) and not DEFINED(IOS))}
Result := True ;
{$ELSE}
Result := False ;
{$ENDIF}
end ;
Adaptive Chart Configuration
procedure ConfigureChartForPlatform (Chart: TChart);
begin
if IsMobilePlatform then
begin
Chart.Hover.Visible := False ;
Chart.Legend.Font.Size := 10 ;
Chart.Title.Font.Size := 14 ;
Chart.View3D := False ;
Chart.AntiAlias := False ;
end
else
begin
Chart.Hover.Visible := True ;
Chart.Legend.Font.Size := 12 ;
Chart.Title.Font.Size := 18 ;
Chart.View3D := True ;
Chart.AntiAlias := True ;
end ;
end ;
Best Practices
Test on real devices - Simulators don’t show real performance
Use platform layouts - Create device-specific form layouts
Optimize for mobile - Disable expensive features on mobile
Handle rotation - Adapt layouts for landscape/portrait
Touch-friendly UI - Larger hit targets on mobile (44x44 pts minimum)
Platform-appropriate navigation - Tab bar on iOS, drawer on Android
Performance profiling - Test with realistic data volumes
unit CrossPlatformChart;
interface
uses
System.SysUtils, System.Classes, FMX.Types, FMX.Controls, FMX.Forms,
FMXTee.Engine, FMXTee.Series, FMXTee.Procs, FMXTee.Chart;
type
TFormChart = class (TForm)
Chart1: TChart;
Series1: TLineSeries;
procedure FormCreate (Sender: TObject);
procedure FormResize (Sender: TObject);
private
procedure ConfigureForPlatform ;
end ;
implementation
{$R *.fmx}
procedure TFormChart.FormCreate (Sender: TObject);
begin
ConfigureForPlatform;
Series1.FillSampleValues;
end ;
procedure TFormChart.ConfigureForPlatform ;
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
// Mobile configuration
Chart1.Hover.Visible := False ;
Chart1.View3D := False ;
Chart1.Legend.Font.Size := 10 ;
Chart1.Title.Font.Size := 14 ;
// Touch gestures
Chart1.Touch.InteractiveGestures :=
[TInteractiveGesture.Zoom, TInteractiveGesture.Pan];
{$ELSE}
// Desktop configuration
Chart1.Hover.Visible := True ;
Chart1.View3D := True ;
Chart1.Legend.Font.Size := 12 ;
Chart1.Title.Font.Size := 18 ;
Chart1.AllowZoom := True ;
{$ENDIF}
end ;
procedure TFormChart.FormResize (Sender: TObject);
begin
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
// Adapt to orientation
if Width > Height then
Chart1.Legend.Alignment := laRight
else
Chart1.Legend.Alignment := laBottom;
{$ENDIF}
end ;
end .
Next Steps
Standard Series Explore chart types
Dashboard Build cross-platform dashboards
Resources
Always test on actual devices before releasing. Simulators and emulators don’t accurately represent real-world performance and user experience.