# Visualization
Pragma visualizations is a general mechanism for displaying information allowing simple interaction with that data.

There are two parts to visualization, the first being the data manipulation and the second the display of that data.

## Data
Data is cached using the group worker with a cache id. On this cache you can define different perspectives.
Lets use a example to explain perspectives. Assuming we have a list of workorders, if we look at those records ungrouped you get a certain idea of what is going on with that data.
If you group the work orders by site and aggregate it by count we now now get a different picture of the data. 
The picture we get is how much work is performed on what asset. If we group it by staff member we get a different picture and if we group by date yet another.

To this end we can apply different groupings to the cache and register those groupings as a perspective with a proper perspective id.

## Rendering
These are the standard list of renderers for visualization. Some of them are still in progress of development.

1. Grid
1. Tree
1. List
1. Template

Others like calendar may be considered in the future.
Depending on the rendering you may need different properties.
Grids need to define columns, both tree and list need templates to define how you want to display the data.

Here are some examples of perspectives defined in the schema.

```json 
"perspectives": [
    {
        "id": 0,
        "id-field": "id",
        "data": {
            "cache": "detail-lookup",
            "aggregate": "count",
            "sorting": ["code"]
        },
        "views": [
            {
                "id": 0,
                "name": "Standard Grid Layout",
                "type":"grid",
                "columns": [
                    {
                        "field": "code",
                        "title": "Code",
                        "width": "120px"
                    },
                    {
                        "field": "description",
                        "title": "Description",
                        "width": "1fr"
                    }
                ]
            }
        ]
    },
    {
        "id": 1,
        "id-field": "id",
        "data": {
            "cache": "lookup2-cache",
            "aggregate": "count",
            "grouping": ["siteCode"]
        },
        "views": [
            {
                "id": 0,
                "name": "Standard Deail Tree Lookup",
                "type": "tree",
                "template": 2
            }
        ]
    }
],

```

Note the following:

The perspective has three properties that you need to define. 

1. id // used to identify the perspective in the schema and must be a number.
1. id-field // what field name should be used as the field when selecting a record.
1. data // what data manipulation needs to take place and of what cache.
1. views // what are the different ways we want to be able to view this perspective.

## Views
Current designs indicate that a perspective may be viewed in different ways.
The same perspective should be able to view as a chart or as a grid for example, the user being able to easily swap between them.

Because of this the views is an array and the visualization has to define what perspective to use and what view to use by default.

Some views like that of the list and the tree needs to define how you want to see the lowest branch and to be consistent with how the rest of the schema works we use a template.
When you define a tree view you need to define the template to use.

```json 
{
    "element": "visualization",
    "datasource": "model.details",
    "perspective": 1,
    "view": 2
}
```

## Grid view
The grid view has a bit more meat to the properties you need to define, specially when it comes to the properties.
The view has a columns propery that is an array of column definitions. 

Each column defines at minimum the following:
1. field // what field on the model contains the data
1. title // what is the column header
1. width // how wide is it using css width identifiers

The last column width should be 1fr so that it will take up all the remaining space.

## Using outside of schema
You can use the visualization custom element outside of the schema but you need to ensure that it has all the information.
```html
<visualization
        id="lookup-visulization"
        selected-id.two-way="selectedId"
        items.bind="items"
        perspective.bind="perspective"
        view.bind="definition.view"
        template.bind="template"
        if.bind="show == true"></visualization>
```

1. You must have a id for the visualization, this is used for input monitoring internally.
1. If you want to be informed of a final level record being selected, bind two way to the selected id.
1. Items is the list of information in the form of object literals.
1. The perspective object to use
1. The default view id to use
1. If applicable the template object to use.

Perspective, view and items need to be present at the attached lifecycle event.
If you are expect a dealy in when these properties will be set, you can use a if binding until you are ready as seen in the example.

## Context
If you use visualization as part of the schema, a context will be bound to it. This context is the viewmodel the schema is on.
This context is usefull when you want to bind to any property exposed by the view model.

## Template Renderer
You may want to have fine tuned control on what to render for a perspectives view.
Not all visualizations are part of pragma-views and if you want that custom control, you can use the template visualization.

As per all other schema templates you start by defining a template in the templates property of the schema.
On the given perspective define the view of type "template".

```json
    "perspectives": [
        {
            "id": 0,
            "id-field": "id",
            "data": {
                "cache": "visualisation_grid",
                "aggregate": "count"
            },
            "views": [
                {
                    "id": 0,
                    "name": "Standard Grid Layout",
                    "type":"grid",
                    "columns": [
                        {
                            "field": "title",
                            "title": "Title",
                            "width": "120px"
                        },
                        {
                            "field": "value",
                            "title": "Value",
                            "width": "1fr"
                        }
                    ]
                },
                {
                    "id": 1,
                    "name": "template based visulisation",
                    "type": "template",
                    "template": 1
                }
            ]
        }
    ]

```

The above example has one perspective but with two visualizations.
view 0 renders the data of this perspective as a grid and view 1 has a custom render using templates.
As you can see the template to use for this render is template 1.

The next example shows the template to use in the visualization.

```json
    "templates": [
        {
            "id": 1,
            "elements": [
                {
                    "element": "div",
                    "content": "${context.title}"
                },
                {
                    "element": "ul",
                    "elements": [
                        {
                            "element": "li",
                            "attributes": {
                                "repeat.for": "item of items.items"
                            },
                            "content": "${item.title}"
                        }
                    ]
                }
            ]
        }
    ],

```

The important thing to know here is that the current binding context is the template render.
The template renderer has a items property that is the result of the perspective data being massaged.
This examples uses normal aurelia binding to loop through the items and displayes the title.
There is also a binding to the context. This means that the template renderer class has a property called context that points back to the view model this screen is on.
See context for more details.

What this allows you to do is use visualizations outside of pragma views to render the items.
This might be chart components, or custom visualizations. The content of this template is enhanced by aurelia so you can use normal binding attributes as you would any other template.