Data Visualization
How to connect Data Ocean SQL query results to Atlas Forms chart controls — building dashboards that display live counts, trends, and breakdowns from your application data without leaving the BizFirstGO platform.
Chart Controls in Atlas Forms
Atlas Forms includes a set of chart controls that render live data from a bound data source. Unlike static charts, these controls execute a SQL query (via a workflow trigger) each time the form loads or refreshes, displaying the latest data directly from your Data Ocean tables.
Supported chart types:
Bar Chart
Grouped or stacked bars. Ideal for comparing counts or values across categories (e.g., leads by status).
Line Chart
Trend over time. Ideal for showing volume changes over days/weeks (e.g., new leads per day).
Pie / Donut Chart
Proportional breakdown. Ideal for showing share of total (e.g., leads by source).
Data Grid
Tabular display with sorting, filtering, and pagination. Ideal for list views within a dashboard form.
KPI Card
Single numeric value with label and trend indicator. Ideal for total counts, averages, and key metrics.
Binding a Chart to SQL Data
Each chart control is bound to a data source workflow — a Flow Studio workflow whose REST trigger returns the aggregated data for the chart. The chart control calls this workflow when the form loads.
Step 1: Create the Aggregate Query Workflow
// Workflow: lead-chart-by-status
// Returns lead counts grouped by status for the current tenant
SqlQueryNode config:
{
"query": "SELECT Status AS label, COUNT(*) AS value FROM Lead WHERE TenantId = @tenantId AND IsDeleted = 0 GROUP BY Status ORDER BY value DESC",
"parameters": { "tenantId": "{{workflow.tenantId}}" },
"outputVariable": "chartData"
}
// Output returned to chart control:
[
{ "label": "New", "value": 48 },
{ "label": "Contacted", "value": 31 },
{ "label": "Qualified", "value": 19 },
{ "label": "Converted", "value": 12 },
{ "label": "Disqualified","value": 7 }
]
Step 2: Bind the Chart Control
In the AtlasForms designer, select the Bar Chart control and configure its data binding:
// Chart control data binding config
{
"controlType": "BarChart",
"title": "Leads by Status",
"dataSource": {
"type": "workflow",
"workflowId": "lead-chart-by-status",
"labelField": "label",
"valueField": "value",
"refreshOnLoad": true,
"refreshIntervalSeconds": 60
},
"colors": ["#6c8cff", "#a78bfa", "#34d399", "#fbbf24", "#f87171"],
"height": 300
}
Common Dashboard Queries for Lead Management
Leads Created Per Day (Last 30 Days)
SELECT
CAST(CreatedAt AS DATE) AS label,
COUNT(*) AS value
FROM Lead
WHERE TenantId = @tenantId
AND IsDeleted = 0
AND CreatedAt >= DATEADD(DAY, -30, GETUTCDATE())
GROUP BY CAST(CreatedAt AS DATE)
ORDER BY label ASC;
Total Pipeline Value by Sales Rep
SELECT
AssignedToUserId AS label,
SUM(EstimatedValue) AS value
FROM Lead
WHERE TenantId = @tenantId
AND Status IN ('New', 'Contacted', 'Qualified')
AND IsDeleted = 0
GROUP BY AssignedToUserId
ORDER BY value DESC;
KPI: Total Qualified Leads This Month
SELECT COUNT(*) AS value
FROM Lead
WHERE TenantId = @tenantId
AND Status = 'Qualified'
AND IsDeleted = 0
AND CreatedAt >= DATEFROMPARTS(YEAR(GETUTCDATE()), MONTH(GETUTCDATE()), 1);
AI Classification Breakdown
SELECT
ISNULL(ClassificationLabel, 'Not Yet Classified') AS label,
COUNT(*) AS value
FROM Lead
WHERE TenantId = @tenantId
AND IsDeleted = 0
GROUP BY ClassificationLabel
ORDER BY value DESC;
Real-Time Dashboard Refresh
For dashboards that need to reflect data as it changes (e.g., a live operations dashboard), configure the chart controls to auto-refresh and optionally subscribe to EdgeStream events:
// Chart control with auto-refresh
{
"refreshIntervalSeconds": 30, // Poll workflow every 30 seconds
"edgeStreamSubscription": {
"channel": "data-ocean-events",
"eventType": "lead.created lead.updated",
"triggerRefresh": true // Refresh immediately on matching event
}
}
For dashboards serving many concurrent users, consider running aggregate queries on a schedule (every 5-15 minutes) and writing the results to a summary table. Chart controls then query the lightweight summary table instead of the full Lead table on every load. This pattern is called a materialized view equivalent in Data Ocean.