Skip to content
This repository has been archived by the owner on Jan 5, 2022. It is now read-only.

Components Development

Eric Jackson edited this page Jun 5, 2015 · 32 revisions

Front-End Framework Overview

One of the design goals for the GBE was to allow contributors to develop new visualization and other components for the platform without having to become familiar with the entire GBE architecture. The front-end framework is designed to realize that goal. This is the first iteration, so ideas for improving are welcome!

GBE public sites are implemented using a ReactJS/Flux-based framework that delivers the site as a single-page app (SPA). The framework takes care of laying out all elements of the page, including display components, and also provides an interface for accessing data associated with a component without the need to work directly with server APIs. The server side component registration ensures that proper data is packaged and delivered for use by individual components.

The code for the framework (as well as for built-in components) is located in the gbe/resources/js directory, starting with app.js, which creates the top-level Site React component. The platform uses Gulp to compile, consolidate and minify JSX, JS and CSS files. Just run gulp in the gbe directory to recompile everything into the public directory (or run gulp watch while developing to have it automatically re-process as you change files).

The framework tries to follow a fairly pure (perhaps extreme) version of the React/Flux philosophy briefly described here. In particular:

  1. All state changes are initiated by components (never by stores)
  2. All state changes pass through the dispatcher and are stored in a state store outside the components
  3. Re-rendering is controlled by a single component at the top and the entire app is re-rendered on any state change (although components may optimize performance through judicious use of shouldComponentUpdate).

An advantage of the last item is that components need not register for change events from any of the stores - only the Site component at the top of the hierarchy registers.

The framework also makes use of another idea alluded to in the presentation linked above, but not detailed. Components do not work directly with datasets downloaded from the server. Rather they work with a derived structure called a DataModel that transforms the dataset into a form more usable directly by components. The DataModel also takes care of caching "assets" to avoid expensive recomputation whenever possible, as well as managing the process of integrating multiple datasets into a single structure as they arrive asynchronously from the server.

Component Hierarchy

The component hierarchy is straightforward. The Site component is currently very bare bones - it includes a simple navigation menu with all the published pages of the site and a BootstrapLayout component.

The BootstrapLayout component uses the layout definition for the current page to create a Bootstrap-based grid, then creates and places React components in the grid cells to which they have been assigned in the layout.

Stores

Before instantiating the Site, app.js also sets up 5 stores that the React components can use (following the Flux paradigm):

  • ConfigStore - A read-only store containing any configuration information for the Site or its presentation components.
  • StateStore - A store for component state information.
  • CardStore - A store for card data.
  • DatasetStore - A read-only store for budget datasets. Components do not interact directly with this, rather they access datasets through the next store.
  • DataModelStore - A store for DataModels, which provide a representation of datasets and sets of datasets that are more easily consumable by components.

See the Client-Side Component Implementation section for further details on their use.

Creating a New Display Component

Creating a new display component is, in principle, quite simple, consisting of just two steps:

Here too are some important design considerations for developing components.