Perspectives define how to manipulate data in order to better visualize it.
This includes actions such as:
- Grouping
- Sorting
- Calculating aggregates
You can read more about perspectives as one of the four pillars of data exploration.
Schema example
{
"perspectives": [
{
"id": "site_perspective",
"sorting": [ ... ],
"groupings": [ ... ]
}
],
"body": {
"elements": [ ... ]
}
}
A schema can define various perspectives. The visualizations specify which data to display and the particular perspective to apply. There needs to be a correlation between the data being fetched and the defined perspective. For instance, if sorting or grouping is specified, the relevant fields should exist in the data being retrieved.
Both sorting and grouping are structured as collections to facilitate conditional sorting and grouping. These conditional definitions are only activated if their respective conditions are met. The first condition that is satisfied will be the one that is implemented.
Sorting and grouping are optional properties but you should at least have one of them defined in a perspective.
Sorting examples
{
"perspectives": [
{
"id": "site_perspective",
"sorting": [
{
"fields": [
{
"field": "code",
"value": "ascending"
}
]
}
],
}
]
}
In the above example we have a perspective that sorts the records by the “code” field and sorts it “ascending”. There are two directions you can sort in.
- “ascending” – from lowest value to highest value.
- “descending” – from highest value to lowest value.
Since this sorting does not have a condition, it will always be applied.
If you want to sorting to only apply if a condition is met then you can add a condition property to the sorting definition.
{
"perspectives": [
{
"id": "site_perspective",
"sorting": [
{
"condition": "isActive == true",
"fields": [
{
"field": "code",
"value": "ascending"
}
]
}
]
}
]
}
Let’s outline a series of conditional sorting steps. It’s important to remember that in such scenarios, the sorting corresponding to the first condition that is successfully met will be the one implemented.
{
"perspectives": [
{
"id": "site_perspective",
"sorting": [
{
"condition": "value == 'a'",
"fields": [
{
"field": "code",
"value": "ascending"
}
]
},
{
"condition": "value == 'b'",
"fields": [
{
"field": "code",
"value": "descending"
}
]
}
]
}
]
}
The above principle can be used to re-order a flat list of records based on multiple conditions. First example I might have three different sort conditions that is defined in the sorting. What will happen is that the records will be sorted in batches based on it’s condition.
Scenario:
I have a field called “entityName” and I want to reorder the data such that:
- First show me all the records where “entityName” is either “RegularAssetTypeComponent” or “PlaceholderAssetTypeComponent”
- Then show me all the records where “entityName” is “RegularAssetType”
- Then show me all the records where the “entityName” is either “InPlaceAssetType” or “PlaceholderAssetType”
- After that just show the rest in the order they came.
{
"sorting": [
{
"title": "Components",
"fields": {
"record.code": "ascending"
},
"condition": "entityName == 'RegularAssetTypeComponent' ||
entityName == 'PlaceholderAssetTypeComponent'"
},
{
"title": "Regular Asset Types",
"fields": {
"record.code": "ascending"
},
"condition": "entityName == 'RegularAssetType'"
},
{
"title": "Sub Asset Types",
"fields": {
"record.code": "ascending"
},
"condition": "entityName == 'InPlaceAssetType' ||
entityName == 'PlaceholderAssetType'"
}
]
}
In the aforementioned example, there’s a “title” field included. While this field is not mandatory, it is added to provide human-readable debug data, aiding in understanding what the sorting definition accomplishes.
Grouping examples
Grouping organizes records into collections based on common values in a specified field. Additionally, aggregate functions are calculated for each group, as it comprises a subset of the records. This technique is frequently utilized in various visualizations, such as:
- Data grids
- Tree views
- Charting
In the following examples, aggregates will be incorporated as part of the grouping strategy. It’s important to note that including aggregates is optional. If your grouping doesn’t necessitate aggregates, you can omit the aggregates property. A variety of aggregate functions are supported and can be used as needed.
- count – Calculates the number of records that share a particular value.
- sum – Totals the values of a specified numeric field across all records.
- min – Identifies the smallest value within a specified numeric field.
- max – Determines the highest value within a specified numeric field.
- ave – Computes the average of all values in a specified numeric field.
The ‘aggregate
‘ property is a collection, allowing you to define multiple aggregates for calculation within the same grouping.
{
"perspectives": [
{
"id": "site_perspective",
"groupings": [
{
"field": "code",
"aggregate": ["count"]
}
]
}
]
}
Considering the dynamic nature of data, where the availability of a specific field can’t always be guaranteed, you can enhance the field definitions for groups by incorporating OR statements. If a field is not found, the system progresses to the next field specified in the OR statement, continuing until it locates an available field. This approach represents a more advanced scenario and should be used judiciously, not as a substitute for disciplined scenario planning.
{
"perspectives": [
{
"id": "site_perspective",
"groupings": [
{
"field": "code || item.code",
"aggregate": ["count"]
}
]
}
]
}
Groupings can be based on conditions. In such instances, conditions are evaluated and the groupings are applied based on the first condition that is met. Moreover, these conditions are hierarchical, allowing for the definition of sub-groupings, each of which can also be governed by its own set of conditions.
Conditional grouping example
{
"perspectives": [
{
"id": "perspective",
"groupings": [
{
"field": "code",
"aggregate": ["count"],
"condition": "entityName == 'RegularAssetTypeTask'"
}
]
}
]
}
In the above example the grouping is only applied if the condition is met.
{
"perspectives": [
{
"id": "perspective",
"groupings": [
{
"field": "code",
"aggregate": ["count"],
"condition": "entityName == 'RegularAssetTypeTask'"
},
{
"field": "taskCode",
"aggregate": ["count"],
"condition": "entityName == 'AuxiliaryAssetTypeTask'"
}
]
}
]
}
In the given example, the first condition is assessed. If this condition is met, the corresponding grouping is applied. If it is not met, then the second grouping condition is evaluated. Should the second condition be satisfied, it is then applied. If neither condition passes, no grouping occurs.
Nested grouping
Nested grouping involves performing a grouping action, followed by executing another grouping action on the records within that initial group. This process can be repeated multiple times. Additionally, conditions can be set for these sub-groups. This approach offers an unprecedented level of flexibility and freedom.
{
"perspectives": [
{
"id": "perspective",
"groupings": [
{
"field": "siteCode",
"aggregate": ["count"],
"groupings": [
{
"field": "tradeCode",
"aggregate": ["count"],
}
]
}
]
}
]
}
Nested groupings function similarly to perspective groupings, with the primary difference being that they operate on a subset of data as determined by the parent grouping. This flexibility allows you to tailor the complexity of your grouping strategy as needed. If conditions are required for the nested grouping, they can be added; if not, they can be omitted. You have the freedom to nest these groupings to any depth and create a grouping intent as complex as necessary.