# Architectural overview

This document provides a conceptual overview of the _[Caplin Grid](index.md)_, to help you configure and extend grids in your own application.

## Features

The image below shows a typical grid configured to display corporate bonds. It’s also showing a pop-up menu, that can be configured to perform actions on particular columns in a grid.

![grid_arch_2](../../../images/grid_arch_2.png)

### Basic Features

Superficially, a grid is quite similar to a table, comprising a _body_, which is a regular two-dimensional array of cells, and a _header bar_. The _header bar_ is a single row of cells – one for each column in the grid – which display the column titles. Each header cell is the same width as the other cells in its column. The data in all cells (header or body) are formatted, styled and displayed by a _renderer_. [_Renderers_](../renderer/index.md) are specifically designed to co-operate with the grid, listening for changing data (e.g. prices) and displaying any updates in real-time.

Just below the header cells in the example above, you can also see a row of text-boxes. Users can type expressions into these boxes, to [filter the values displayed in the column](grid-configure-sorting-and-filtering.md#filtering). This is achieved by using a _composite renderer_. Caplin supplies a set of _renderers_ that cover most common requirements, but you are free to [enhance these or add your own](../renderer/renderer-write-my-own-renderer-classes.md). Renderers are also commonly used to indicate stale data or the direction of price movements.

### Hiding and Reordering Columns with Decorators

A grid can have a large number of columns defined, but doesn’t necessarily display all of them. The above example shows a context menu that was triggered by right-clicking in a header cell. It gives users the ability to change which columns are displayed. These sorts of enhancements are added using **[grid decorators](grid-available-decorators.md)**. You can also change the order in which the columns are displayed. Again, Caplin supplies a set of _decorators_ that cover common requirements and you can [create and add your own _decorators_](grid-built-in-grid-features.md) if you need to do so.

### Windowing, Sorting and Filtering

One unique feature of the grid is its ability to display a small "window" of rows from a much larger container that is typically held on a server. In this case, a scrollbar appears to the right of the grid body, indicating the data-window’s size and relative position within the larger data-set. Initial data and updates are only sent for the window of data that is currently visible.

The grid subscribes to a data stream for each row of data that it needs to display, so that any changes in that row of data are immediately pushed to the grid. However, the grid only needs to be subscribed to the data streams that it has to display at that particular moment. When the user scrolls therefore, the grid unsubscribes from the data streams of the rows that are no longer visible, and subscribes those of the new rows. This means that users can scroll up and down tens of thousands of rows of data, with very low loading on the client and the network, making it incredibly quick and responsive.

Columns can also be [sorted or filtered](grid-configure-sorting-and-filtering.md). When this happens, a request is sent to the server, which applies the filter criteria to the server-side container. The subscriptions for the "window" of data are automatically adjusted, and the required data, flows down to the client for display. Obviously, for this to work, you require a server that supports these windowing, sorting and filtering features. Caplin achieves this by providing a fully integrated stack with _Caplin Liberator_, _Transformer_ and _Streamlink_.

Should you wish to do so, you can configure the grid to display data that is entirely cached in the browser, but such grids will not support the enhanced features.

### XML Configuration

Grids are created when the `GridGenerator` processes your grid definition XML. You never need to create a grid directly, just supply the XML and the grid is created for you. Typically you can create a grid with a few tens of lines of XML and some CSS styling. Occasionally you may have to write bespoke _renderers_ or _decorators_, which you then include in the XML configuration.

## Class Structure

A (very) simplified UML diagram of the major parts of the grid is shown below:

![grid-docs](../../../images/grid-docs.violet.png)

### The View Controller

The _view layer_ is responsible for drawing the grid on the screen. The `[GridView,opts="nofollow"](https://docs.caplin.com/developer/api/caplin_trader/3/caplin.grid.gridview)` class has overall control of this. The _view_ objects listen for changes to the _model_ objects (described below) that hold the data to be displayed. The `GridView` contains a list of all _decorators_ that have been registered. Each _decorator_ receives a reference to the `GridView` and can access its _models_ and DOM elements as required to implement the necessary functionality.

### The Model

The _model_ describes the structure and data of the grid.

Each column in the grid is described by a `[GridColumn,opts="nofollow"](https://docs.caplin.com/developer/api/caplin_trader/3/caplin.grid.gridcolumn)` object, which is accessed via the `[GridColumnModel,opts="nofollow"](https://docs.caplin.com/developer/api/caplin_trader/3/caplin.grid.gridcolumnmodel)`. The `GridColumn` contains information about (amongst other things) the column’s width, title, any filters applied to it, whether it can be sorted, etc... It also provides two methods: `createElementRender()`, which creates the renderer for every cell of the column; and `createHeaderElementRender()`, which creates the _renderer_ used in the header cell for that column. At start-up, the _view_ classes retrieve the _renderers_ from the _model_, and then use them to display the data. The `GridColumnModel` allows you to add/remove and show/hide the grid columns, dynamically.

The actual data being displayed are held in the `[GridRowModel,opts="nofollow"](https://docs.caplin.com/developer/api/caplin_trader/3/caplin.grid.gridrowmodel)`. `GridRowModel` is an interface, and as such you can provide your own implementation, and display any tabular data source. The _view_ retrieves the data to be displayed by calling the `getRowData(index)` method, which returns a single row of data, with the specified (zero based) index. It returns a map of data, keyed to the name of the column. The view sets the size of the window being displayed, by calling the method `setRowRange()`. It is then the responsibility of the `GridRowModel` to fetch the data needed for that window.

The _view_ can find out if the `GridRowModel` supports sorting and filtering by calling the `supportsFeature()` method. The model provides methods for retrieving and updating filter and sort expressions. It is possible to control data update for ``GridRowModel``s that provide streaming data, using the `pauseUpdates()`/`resumeUpdates()`/`terminateUpdates()` methods.

### DataProviders

The `[DataProviderRowModel,opts="nofollow"](https://docs.caplin.com/developer/api/caplin_trader/3/caplin.grid.dataproviderrowmodel)` is an implementation of `GridRowModel`, which is supplied by Caplin. It provides access to streaming data that will (generally) come from a COMET server. To use it, you provide an implementation of the `[GridDataProvider,opts="nofollow"](https://docs.caplin.com/developer/api/caplin_trader/3/caplin.grid.griddataprovider)` interface. If using the _Caplin Platform_ then use the data provider alias **caplin.sljs-container-grid-data-provider** to receive data from Liberator. For more information on using aliases with grids, see [Upgrade an Application to use Aliases](../base-library/base-upgrade-an-application-to-use-aliases.md). If you use another server you can create your own `GridDataProvider` implementation. The `GridDataProvider` also co-ordinates with the `GridRowModel`,ensuring that the appropriate requests are sent to the server (via the `GridDataProvider`), when a column’s configuration data is changed.
