Lightstreamer :: Dojo Toolkit :: Stock-List Demo Documentation

The Lightstreamer :: Dojo Toolkit :: Stock-List Demo demonstrates the integration between the Lightstreamer Server and the Dojo Toolkit v.1.6. The description of this demo assumes a basic understanding of both Lightstreamer and Dojo Toolkit components, along with the dependent JavaScript, HTML and HTTP technologies.

The following diagram depicts the major elements of the demo. In yellow are the Lightstreamer server and web client components; in light blue are the Dojo Toolkit components that serve as a communication layer/interface, and finally in darker blue are the Dojo Toolkit user interface components.

For this demo, the Lightstreamer server (and Adapters) and the web client engine are configured identically to the Stock-List demos, with the exception of the use of the NonVisualTable in place of OverwriteTable. As with the original stock list demos, the NonVisualTable is configured to receive stock updates from the server.

Central to the demo is the LightstreamerStore, a JavaScript interface based on the new dojo.store APIs. This object-based store is written so that the query method (to which you pass the name of the data adapter you want to use) returns a QueryResults object that is promise-based; all you need to do is attach callback function to the "observe" method of the results to listen for any updates from the server. Each object returned by the server is passed to anything assigned to the "observe" function, which makes it simple to consume.

The demo's application code is contained in one file: index.js. This file splits common functionality using objects named for their purpose: formatters, updaters, handlers, etc. These objects contain the stateful functionality of the application. Following these object definitions is the basic "initialization" block; this defines the initial state of the application, along any executable initialization.

The demo has three basic components: the controlling button bar (allowing for actions against the rest of the application), the Grid (which shows raw data in a tabular format, along with some integrated indicators/controllers that are data-specific), and the Chart (which visualizes the data in the Grid, including augmenting it by showing some sort of history). In a more complex application, greater care would be taken in terms of structure. But because this is a fairly simple application, a certain amount of leeway can (and has) been taken.

When looking through the code for StockList, the best place to start is the definition of the object "handlers", and the method "start". This is called during the dojo.ready execution and makes the initial calls to the LightstreamerStore. Of particular importance is the "results.observe" method, which is the entry point for the entire demo. Each instance of the "object" argument is a JSON object encapsulating all of the data returned from Lightstreamer. This object is passed to the ObjectStore driving the Grid, and a custom function called "updaters.chart" to drive the Chart beneath.

Updating the dojox.grid.DataGrid

The Grid is designed to listen to updates based on the older dojo.data mechanisms, so an additional store it was designed to work with (dojo.data.ObjectStore) is implemented, along with the basic methods for manipulating it. This store is an adapter store to allow widgets that normally rely on the older dojo.data APIs to interact with the newer dojo.store APIs (released with the Dojo Toolkit 1.6).

In addition to the fields specified in the configuration layout and schema, when a new object is received by from the LightstreamerStore two additional fields are added: "show" and "legend". These are used by the user interface to control what data streams are displayed in the underlying chart, and to show what colors the chart is using for the data stream. The "show" value is the only one in the grid that is intended for user interaction; using the Grid's built-in editing capabilities, a checkbox is displayed. To listen for changes in the value of the checkbox, a handler called "setItem" was added. This handler limits functionality to the "show" field, and updates the user interface based on the action taken.

Updating the dojox.charting.Chart

In dojox.charting, there are two basic choices when creating a chart to show dynamic values in series: use dojox.charting.DataSeries, or manually updating a chart after adding values to existing series. For this demo, it was decided to manually update series in a chart because of the nature of the streams returned from the Lightstreamer server. Lightstreamer returns new objects that are based on a single point in time, but charts by their nature attempt to visualize a historical view of data.

To handle this, a JavaScript object is created called "chartData" that is populated based on the return from "results.observe"; instead of just updating an existing object, the data is slightly modified (with x and y values), and pushed into an array of data representing each stream. All items returned from Lightstreamer are created first as a property of this chartData object, and new data with the same identifier simply push new points into the historical list (see "updaters.chart" for details). Because this application can be potentially run for a long time, an additional mechanism is put into place to discard data points older than a specific range of data. This ensures that the historical list for each item is of limited length.

Finally, because of performance concerns, the chart itself is not updated when each new data point is pushed into the historical lists; instead, the chart updates based on a timer so that no matter what kind of data is returned, updates happen based on a specific "frame rate" (at the time of writing, once per second). This allows the chart engine to not run many sub-second operations and attempt to keep up with the rate that data is returned from the Lightstreamer server—effectively decoupling chart updates from data updates.

Handling time zone differences and the time field

One particular problem arose when attempting to plot the data returned for StockList: time zone differences. The current data set that Lightstreamer returns is based on time; however, the time returned is based not on the browser's current timezone, but rather the timezone where the server lives. To handle this, an initial value range for the X axis is created based on the user's time zone. But when the first data point is returned by the Lightstreamer server, the value range on the X axis is recalculated once based on the time field returned, and then rendered outside of the timed updates on a chart.

Shifting the X Axis

The last major concern with plotting historical data is shifting the X axis value range based on where in time the series being plotted currently are. It turns out that dojox.charting has a very simple (but not necessarily intuitive) method for dealing with this: you simply re-add the axis definition with the same name but with adjusted min and max values. This can be found in the semi-private method "handlers._startChart", where the actual timer to update the chart is defined. When new data is returned from the Lightstreamer server, the value of the time field is checked and if it is greater than a cached "highTime", replaces that value. Then, when the chart is updated, that value is checked against a specific range (at the time of writing, 30 seconds) and if it turns out to be greater than a specific threshold, the X axis is redefined before the render update happens. The visual result of this is that when 20 seconds of historical time is shown on the chart, the chart "shifts" to the left so that the newest values are always shown.

Setting up the demo on your own instance of Lightstreamer

To set up StockList on your own instance of Lightstreamer:

  1. In your Lightstreamer installation, in the directory pages/demos, create a new folder called "DojoToolkitDemo".
  2. Download the ZIP archive from StockList, and unzip the contents into the new folder.
  3. Get the latest Dojo Toolkit distribution from the Dojo Toolkit; StockList requires the Dojo Toolkit v.1.6 or higher.
  4. Copy the /dojo, /dijit and /dojox folders into /DojoToolkitDemo/js merging their contents with the files already in the dojo and dojox folders. In particular keep the ObjecStore.js files that comes with the demo, not the one that comes with the Dojo Toolkit distribution.
From there, you should be able to hit http://localhost:8080/demos/DojoToolkitDemo/ and see StockList (adjust the port setting based on your installation).