Overview
The Dashboard samples demonstrate professional, data-driven applications with multiple synchronized charts, database integration, and cross-platform responsive design.
Sample Location: FMX/Dashboard/
The Dashboard sample is a comprehensive example of real-world business intelligence application, featuring interactive charts, data filtering, and web export capabilities.
Dashboard Application Architecture
Project Structure
Dashboard/
├── Home.pas # Main dashboard form
├── Home.fmx # Dashboard layout
├── DataModule.pas # Database connection
├── FileLauncher.pas # Cross-platform file handling
└── LinkingCharts.dpr # Project file
Key Features
Interactive Charts Multiple chart types working together
Database Integration FireDAC queries with live data binding
Cross-Chart Linking Click events synchronize related charts
Web Export Export dashboard data to HTML/JSON
Dashboard Components
The dashboard includes multiple synchronized chart types:
1. World Map Series
Interactive world map showing sales by country.
MapSeries: TWorldSeries;
MapChart: TDBChart;
procedure TDashForm.ConfigureMapChart ;
begin
MapChart.ColorPaletteIndex := 3 ;
MapChart.Hover.Visible := False ;
// Add tooltip on hover
MapChart.Tools. Add (TMarksTipTool);
(MapChart.Tools[ 0 ] as TMarksTipTool).Style := smsLabelValue;
(MapChart.Tools[ 0 ] as TMarksTipTool).Font.Size := 20 ;
(MapChart.Tools[ 0 ] as TMarksTipTool).Font.Color := TAlphaColorRec.Royalblue;
FillCountryData;
end ;
procedure TDashForm.FillCountryData ;
var
aCountry: string ;
aValue: double ;
i: integer ;
begin
FDQuery1.Close;
FDQuery1.Open();
FDQuery1.First;
while ( not FDQuery1.Eof) do
begin
aValue := FDQuery1.Fields[ 0 ].AsFloat;
aCountry := FDQuery1.FieldByName( 'Country_name' ).AsString;
// Set values on map
for i := 0 to MapSeries.Count- 1 do
begin
if UpperCase(MapSeries.Labels[i]) = UpperCase(aCountry) then
MapSeries.ZValue[i] := aValue;
end ;
FDQuery1.Next;
end ;
end ;
2. Donut Chart
Display sales breakdown by country or region.
DonutSeries: TDonutSeries;
DonutChart: TDBChart;
procedure TDashForm.ConfigureDonutChart ;
begin
DonutChart.Hover.Visible := False ;
DonutSeries.Marks.FontSeriesColor := True ;
{$IFDEF IOS}
DonutSeries.Marks.Visible := False ;
{$ENDIF}
end ;
// Handle donut slice clicks
procedure TDashForm.DonutChartClickSeries (Sender: TCustomChart;
Series: TChartSeries; ValueIndex: Integer ; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer );
begin
ValueIndexCountry := ValueIndex;
// Update area chart for selected country
FillAreaSeriesBySelectedCountry(ValueIndexCountry);
// Trigger animations
TotalSalesIconAnimation.Start;
ColorAnimation1.Start;
AreaAnimation.Play;
end ;
3. Bar Chart
Sales by continent with custom bar styling.
BarChart: TDBChart;
Series4: TBarSeries;
Series5: TBarSeries;
procedure TDashForm.ConfigureBarChart ;
begin
BarChart.Hover.Visible := False ;
_salesbycontinentView.Active := True ;
{$IFDEF IOS}
BarChart.Legend.Font.Size := 10 ;
{$ENDIF}
end ;
// Custom bar styling based on selection
procedure TDashForm.Series4GetBarStyle (Sender: TCustomBarSeries;
ValueIndex: Integer ; var TheBarStyle: TBarStyle);
var
oldColor: TAlphaColor;
begin
oldColor := Sender.Color;
if (ValueIndex = IndexBarClicked) and (BarSeriesClicked = Sender) then
begin
TheBarStyle := bsBevel;
Sender.NormalBarColor := TAlphaColor(BluesPalette[ 5 ]);
end
else begin
TheBarStyle := bsRectangle;
Sender.NormalBarColor := oldColor;
end ;
end ;
Time-series data with interactive range selection.
AreaChart: TDBChart;
AreaSeries: TAreaSeries;
ChartTool3: TScrollPagerTool;
procedure TDashForm.ConfigureAreaChart ;
begin
AreaChart.Hover.Visible := False ;
AreaChart.AllowZoom := False ;
// Configure scroll pager subchart
ChartTool3.SubChartTool.Charts.Items[ 0 ].Chart.Hover.Visible := False ;
ChartTool3.SubChartTool.Charts.Items[ 0 ].Chart.Series[ 0 ].Color :=
BarChart.Series[ 1 ].Color;
end ;
// Handle scroll events
procedure TDashForm.ChartTool3Scrolled (Sender: TObject);
begin
Scrolled := true ;
end ;
procedure TDashForm.AreaChartMouseUp (Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Single );
begin
if Scrolled then
begin
if AStartYear <> - 1 then
begin
if DoScroll then
begin
// Refresh data based on selected range
AStartYear := ChartTool3.ColorBandTool.StartValue;
AEndYear := ChartTool3.ColorBandTool.EndValue;
RefreshBarChart(Round(AStartYear), Round(AEndYear));
RefreshGrid(Round(AStartYear), Round(AEndYear));
UpdateTotalSalesByCountryBetweenLabels(
DonutSeries.Labels.Labels[ValueIndexCountry],
AStartYear, AEndYear);
end ;
end ;
Scrolled := False ;
end ;
end ;
5. TeeGrid Integration
Tabular data display synchronized with charts.
TeeGrid1: TTeeGrid;
procedure TDashForm.RefreshGrid (AStartValue, AEndValue: Integer );
begin
Fact_ordersqueryView.Active := False ;
Fact_ordersqueryView.Close;
if (AStartValue <> - 1 ) and (AEndValue <> - 1 ) then
begin
Fact_ordersqueryView.SQL.Text :=
'SELECT * FROM (SELECT Fact_Orders.ID, Fact_Orders.Cod_Customer, ' +
'Fact_Orders.Orderdate, Fact_Orders.Invoice_year, ' +
'Fact_Orders.Invoice_num, Fact_Orders.Product_code, ' +
'Fact_Orders.Pack_code FROM Fact_Orders) ' +
'WHERE Invoice_year >= ' + AStartValue.ToString +
' AND Invoice_year <= ' + AEndValue.ToString;
end ;
Fact_ordersqueryView.Open;
Fact_ordersqueryView.Active := True ;
end ;
Database Integration
FireDAC Configuration
uses
FireDAC.Stan.Intf, FireDAC.Stan.Option, FireDAC.Stan.Error,
FireDAC.UI.Intf, FireDAC.Phys.Intf, FireDAC.Stan.Def,
FireDAC.Stan.Pool, FireDAC.Stan. Async , FireDAC.Phys,
FireDAC.FMXUI.Wait, FireDAC.Stan.Param, FireDAC.DatS,
FireDAC.DApt.Intf, FireDAC.DApt, Data.DB,
FireDAC. Comp .DataSet, FireDAC. Comp .Client, FMXTee.DBChart;
procedure TDashForm.Init ;
begin
DataModule1.TechproducssqliteConnection.Connected := true ;
// Configure data sources
_salesbycountryView.Active := true ;
_salesbyyearcontinentView.Active := true ;
end ;
Data Queries
_salesbycountryView: TFDQuery;
_salesbyyearcountryView: TFDQuery;
_salesbycontinentView: TFDQuery;
_salesbyyearcontinentView: TFDQuery;
procedure TDashForm.FillAreaSeriesBySelectedCountry (AValueIndex: integer );
begin
// Clear and reassign data source
AreaSeries.Clear;
AreaSeries.DataSources.Clear;
AreaSeries.DataSource := _salesbyyearcountryView;
// Refresh query with country filter
_salesbyyearcountryView.Close;
_salesbyyearcountryView. Params .Items[ 0 ].AsString :=
DonutSeries.Labels.Labels[AValueIndex];
_salesbyyearcountryView.Open();
// Update chart title
AreaChart.Title.Text.Text :=
'Sales by Country : ' + DonutSeries.Labels.Labels[AValueIndex];
end ;
Animation Orchestration
procedure TDashForm.CreateAnimations ;
begin
// Bar Chart Animation
BarAnimation := TSeriesAnimationTool.Create(Self);
BarChart.Animations. Add (BarAnimation);
BarAnimation.StartAtMin := False ;
BarAnimation.DrawEvery := 1 ;
BarAnimation.OnStop := StopBarAnimation;
// Area Chart Animation
AreaAnimation := TSeriesAnimationTool.Create(Self);
AreaChart.Animations. Add (AreaAnimation);
AreaAnimation.StartAtMin := False ;
AreaAnimation.DrawEvery := 1 ;
AreaAnimation.OnStop := StopAreaAnimation;
// Donut Chart Animation
DonutAnimation := TSeriesAnimationTool.Create(Self);
DonutChart.Animations. Add (DonutAnimation);
DonutAnimation.StartAtMin := False ;
DonutAnimation.DrawEvery := 1 ;
DonutAnimation.OnStop := StopDonutAnimation;
end ;
// Animation chain: Donut → Bar → Area
procedure TDashForm.StopDonutAnimation (Sender: TObject);
begin
AnimateBarChart;
end ;
procedure TDashForm.StopBarAnimation (Sender: TObject);
begin
AnimateAreaChart;
end ;
procedure TDashForm.StopAreaAnimation (Sender: TObject);
begin
// Update indicators after animation completes
UpdateTotalSalesByCountryBetweenLabels(
DonutSeries.Labels.Labels[ValueIndexCountry],
ChartTool3.ColorBandTool.StartValue,
ChartTool3.ColorBandTool.EndValue);
end ;
Web Export
Export dashboard data to web formats (HTML, JSON).
procedure TDashForm.BExportToWebClick (Sender: TObject);
var
GridDataAsStr, epath, appPath, URL: String ;
begin
// Export MapChart manually to JSON
ExportMapSeries(epath + '\MapChart.JSON' );
// Export DonutChart
with TSeriesDataJSON.Create(DonutChart, nil ) do
try
IncludeIndex := True ;
SaveToFile(epath + '\DonutChart.JSON' );
finally
Free;
end ;
// Export BarChart
with TSeriesDataJSON.Create(BarChart, nil ) do
try
IncludeIndex := True ;
SaveToFile(epath + '\BarChart.JSON' );
finally
Free;
end ;
// Export AreaChart
with TSeriesDataJSON.Create(AreaChart, nil ) do
try
IncludeIndex := True ;
SaveToFile(epath + '\AreaChart.JSON' );
finally
Free;
end ;
// Export TeeGrid data
GridDataAsStr := TJSONData. From (TeeGrid1.Grid, nil , True );
ExportTeeGridData(epath + '\TeeGrid.JSON' , GridDataAsStr);
// Export indicators
ExportIndicatorsData(epath + '\Variables.js' );
// Open in browser
URL := 'http://localhost/dashboard/reports/index.html' ;
{$IFDEF MSWINDOWS}
TFileLauncher.Open(url);
{$ENDIF MSWINDOWS}
end ;
Font Size Adjustments
procedure TDashForm.Init ;
begin
{$IFDEF MACOS}
Layout4.Height := 192 ;
LBTotalSales.TextSettings.Font.Size := 14 ;
Label5.TextSettings.Font.Size := 14 ;
{$ELSE}
Layout4.Height := 256 ;
LBTotalSales.TextSettings.Font.Size := 18 ;
Label5.TextSettings.Font.Size := 18 ;
{$ENDIF}
{$IF DEFINED(iOS) or DEFINED(ANDROID)}
LBTotalSales.TextSettings.Font.Size := 10 ;
Label5.TextSettings.Font.Size := 10 ;
{$ENDIF}
end ;
Conditional Features
// Chart Editor (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 ;
Color Palette
Custom color schemes for consistent branding.
const
BluesPalette: Array [ 0 . .8 ] of TAlphaColor =
(
$FFD6E1FA ,
$FF7797D1 ,
$FF4466a3 ,
$FF3b548c ,
$FF3B548C ,
$FF2B406B ,
$FF1C2A47 ,
$FF121C2F ,
$FF0C121F
);
procedure ApplyColorPalette ;
var
idx: integer ;
begin
idx := AnsiIndexStr(Continent, [ 'AF' , 'AS' , 'EU' , 'NA' , 'OC' , 'SA' ]);
MapSeries.ValueColor[i] := TAlphaColor(BluesPalette[idx]);
end ;
Best Practices
Synchronize charts - Use click events to link related visualizations
Optimize queries - Use parameterized queries for dynamic filtering
Handle animations - Chain animations for smooth visual flow
Platform adaptation - Adjust UI for different screen sizes
Data caching - Cache query results when possible
User feedback - Show loading states during data refresh
Layout Patterns
Grid Panel Layout
GridPanelLayout1: TGridPanelLayout;
// Organize multiple charts in responsive grid
GridPanelLayout1.ControlCollection.AddControl(Chart1);
GridPanelLayout1.ControlCollection.AddControl(Chart2);
GridPanelLayout1.ControlCollection.AddControl(Chart3);
Next Steps
Cross-Platform Guide Optimize for all platforms
Database Samples More database examples
Resources
The Dashboard sample is production-ready code that demonstrates enterprise-level features including database integration, export capabilities, and cross-platform compatibility.