How It Works
Visualizables
At the core of the system is the concept of a Visualizable. A Visualizable represents a queryable piece of data in a visualization. It carries a SQL expression that gets selected from the base query and mapped to a named field. Visualizables are used across all visualization types:
- In DataGrids, columns are Visualizables
- In Charts, datasets and labels are Visualizables
- Floating Filters are also Visualizables that filter data without appearing in the output
Each Visualizable defines:
- A SQL select expression (
selectWith) — the database expression to query - A field name — the alias used in the output and referenced by filters/sorts
- Optional filter expression (
filterWith) — an alternative expression used when filtering - Metadata — arbitrary key-value data communicated to the front end
Schema and Data
Every visualization is broken up into Schema and Data. The schema contains definitions that tell the front end how to render the visualization, while data requests return the actual query results.
DataGrid Schema Example
{
"grid_key": "grids.active-users",
"columns": [
{
"field": "Name",
"header": "Name",
"type": "text",
"pin": "none",
"is_row_key": false,
"is_sortable": true,
"is_filterable": true,
"is_hidden": false,
"meta": []
}
],
"floating_filters": [
{
"field": "Registration Date",
"header": "Registration Date",
"type": "date_range",
"meta": []
}
],
"default_sorts": [],
"bulk_actions": [],
"inline_actions": []
}Chart Schema Example
{
"chart_key": "charts.revenues",
"label": {
"field": "Month",
"header": "Month",
"meta": []
},
"datasets": [
{
"field": "Total Revenue",
"header": "Total Revenue",
"type": "bar",
"meta": []
}
],
"floating_filters": []
}Query Generation
The GenerateVisualizationQuery class takes a base query and a collection of Visualizables, then:
- Adds each Visualizable as a
selectRawexpression on the query - Applies any filter sets from the request by matching filter fields to Visualizables
- Applies any sorts from the request by matching sort fields to Visualizables
This shared query generation is used by both DataGrids and Charts, ensuring consistent filtering and sorting behavior across all visualization types.
Requesting Data
The front end requests data by sending filter sets and sorts through a RESTful API. Both DataGrids and Charts accept the same filter/sort structure:
Sample Request
{
"sorts": [
{
"field": "Name",
"sort_operator": "asc"
}
],
"filter_sets": [
{
"filter_set_operator": "and",
"filters": [
{
"field": "Name",
"filter_operator": "stringContains",
"value": "Andrew"
}
]
}
]
}Server Response
The server applies the filters and sorts to the query, then returns the results. The response format varies by visualization type — DataGrids support pagination while Charts return the full result set.
DataGrid Response Example
{
"data": [
{
"ID": 1,
"Name": "Andrew",
"Email": "andrew@leachcreative.com"
}
],
"first": 0,
"last": 100
}Chart Response Example
[
{
"Month": "January",
"Total Revenue": 15000
},
{
"Month": "February",
"Total Revenue": 18500
}
]