# Linked dashboard A VCL program, with the form created in code, that binds a `TAtlasDashboard` to one `TAtlasTable` and shows six widgets from the same snapshot: three KPI cards (revenue, average sale, order count), two bar charts (revenue by region, units by product) and a detail grid. A region combo box filters every widget at once, a button appends a row to the table so the widgets refresh through the table's change notification, and two buttons save and reload the layout as JSON. ## What it demonstrates - `TAtlasDashboard.Source` and `AddWidget` with `TAtlasWidgetDefinition.Create` for `awKPI`, `awChart` and `awGrid` widgets, including a count KPI with an empty field. - `SetFilters` applying one filter to all widgets without touching the source table's own filter. - Automatic refresh when the source table changes (`AddRow`), and `LastError` when a refresh fails. - `ToJSON`/`LoadJSON` of widget definitions and dashboard filters. - Reading `Widgets[I].Definition` and `Widgets[I].Data` for a status line. - The shared `Atlas.TestVcl.SaveFormImage` helper: `LinkedDashboard --image out.png` renders the form off screen into a PNG and exits. ## Build and run Open `LinkedDashboard.dpr` in Delphi 13; the IDE creates the project file. Add the Atlas Analytics `src` folder, the Atlas VCL `src` folder and the `shared` folder to the project's search path, then build and run for Win32 or Win64. No packages need to be installed. The `shared` folder is part of the sample download. It holds `Atlas.TestVcl.pas`, which the optional snapshot mode uses to save a picture of the window. ## Expected output A 1200 by 860 window with a dark header and a two-column card layout. The status line reads `6 source rows, 6 widgets, Revenue 73300, Average sale 12216.6666666667, Orders 6`. Choosing `West` changes the revenue KPI to `32,100`, leaves one bar in the region chart and two rows in the grid. `Add a sale` appends a West/Service row and every widget updates. `Save layout` writes `dashboard-layout.json` next to the executable; `Load layout` rebuilds the widgets from it. ## Adapting it Replace `SalesTable` with your own table and change the widget definitions: the `Field` of a KPI or chart must be an `ackNumber` column unless the measure is `amCount`, and a chart needs a `Dimension`. The dashboard has no property that reads back its filters, so keep the current selection in your own code (this sample keeps it in the combo box) if you need it after `LoadJSON`.