tnt.board creates a new track-based visualisation. Typically, each track displays a set of elements defined during its setup. Boards can be panned or zoomed within their defined limits. Once a board is created new tracks can be attached to it using the method board.add_track
Each new track needs to know how to get the data to display (either synchonously or asynchronously). A new call to get new data is performed everytime the board changes its state (while panning / zooming or programmatically). Each track should also define how to represent each of the features to display. TnT offers predefined common displays (like rectangles, lines, areas, pins) ready to use. New displays can also be created using display interface. Composite displays (ie, displays made of combinations fo different simple displays) are also allowed and a very powerful tool for displaying complex data. Examples of how to create different visualizations can be seen in the examples page.
The above example starts by defining a board that displays data from position 0 to 500, being the limits of the board 0 (the default) and 1000. Then two tracks are defined. The first one is a location track with top orientation. The second track is 30 pixels high and displays one block from position 200 to 350 in the board. Both tracks are attached to the board. The board itself is a function that when executed initialises the visualisation using the provided DOM element as its container. Finally, the board is started, which means that the data is retrieved and displayed. It is important to understand and remember these three states of the visualisation:
Boards are track-based visualizations that can be panned and zoomed making all the tracks in the board to update accordingly. TnT Board can be configured using several methods that affect all the tracks in the board (like the width of the board). The height of the board is defined by the sum of the heights of all the tracks. The board can be configured using the methods explained below. When used as setters, these methods return the board object itself allowing to chain them as in this example:
# tnt.board ()
Creates a new track-based board visualization that can be configured using the methods explained below. The returned object is also a function that can be called passing a DOM element as its argument. This DOM element is used as a container for the visualization.
# board.from (<integer>)
Defines the left coordinate of the board (the start left position). If called without arguments returns the current value.
# tnt.board.to (<integer>)
Defines the right coordinate of the board (the start right position). If called without arguments returns the current value.
# board.min (<integer>)
Defines the minimum possible coordinate of the board. If called without arguments returns the current limit. By default this value is 0.
# board.max (<integer>)
Defines the upper limit (ie, the maximum possible coordinate) of the board. If called without arguments returns the current upper limit.
# board.zoom_out (<integer>)
Defines the maximum extent of the board (ie, the limit when zooming out). If called without arguments returns the current value. This limit is respected even if the from and to coordinates specify spans beyond this limit. In that case, the coordinates are adjusted to satisfy this value.
# board.zoom_in (<integer>)
Defines the minimum extent of the board (ie, the limit when zooming in). If called without arguments returns the current value. This limit is respected even if the from and to coordinates specify spans beyond this limit. In that case, the coordinates are adjusted to satisfy this value.
# board.start ()
Starts the visualisation (re-)initialisig all the tracks feeding the tracks with their data and displays. If the board has already started re-initialises the tracks in the board to their current state.
# board.scroll (<float>)
Scrolls the board programmatically. The argument indicates the number of board pages to scroll, if it is possitive the board scrolls to the right, while if it is negative scrolls to the left. For example, board.scroll(1) scrolls right to the next non-overlapping page, while board.scroll(-0.5) scrolls left overlapping half a page.
# board.zoom (<float>)
Zooms in/out the track the specified amount. The argument indicates the number of pages to zoom, or in other words, times of extent. For example, board.zoom(1) does not do anything, board.zoom(0.5) zooms out to double the extent and board.zoom(2) zooms in to half the extent.
# board.tracks (<array>)
Reorders the tracks in the board. Expects an array of tracks as argument. This method requires the visualisation to have started already. The tracks are re-arranged with the order given in the array. New tracks are created while existing tracks not in the array are removed. As a side effect, the height for each existing track is recalculated. If no argument is provided, returns an array containing the current tracks in the board.
# board.add_track (<tnt.board.track>)
Adds a new track to the track visualisation. The order in which this method is called determines the order of the tracks in the board
# board.width (<integer>)
Specifies the width of the board. If the width changes after the visualisation has been initialised, the board and all the tracks are re-initialised with the new width. If no argument is provided, the current width is returned.
# board.allow_drag (<boolean>)
Specifies if the board can be scrolled with the mouse. If set to false, no drag event is used in the board. This method can be set dynamically after the visualisation has started. Disable dragging doesn't disallow scrolling programmatically via board.scroll.
# board.find_track (<string>)
Finds a track by ID. It expects the ID of the track as its argument.
Each board can contain one of more tracks to display data. They are piled up in the board vertically (growing downwards) in the order of attachment to the board. Tracks are created using the constructor tnt.board.track and attached using board.add_track. Each track instance can be configured using the methods explained below. When used as setters, these methods return the track object allowing to chain them as in the following example:
# tnt.board.track ()
Creates a new track. This track has to be configured via its methods. The newly created track can be attached to the board using board's add_track method.
# track.scale ()
Returns the scale to transform between the input domain and the output range. This scale is needed when elements (specified in the user-space) are displayed in the track (pixels-space). See the display interface for an example of use.
# track.color (<string>)
Specifies the background color of the track. Color names ("white") and hexadecimal codes ("#FFFFFF") are allowed. If called without arguments, the current track color is returned.
# track.height (<integer>)
Defines the height of the track in pixels. If called without arguments, returns the current height. This value can be changed after the visualisation has started, but for the change to be applied to the track, the board.tracks method should be called.
# track.label (<string>)
Sets a label to the track. This label is displayed in the top left corner of the track.
# track.id (<string>)
Sets an ID for the track. Uniqueness of track IDs is required in order to avoid unexpected results. Any track missing an ID when the tracks are initialised are assigned a numerical ID starting with "1". This means that explicitely giving low numerical IDs to tracks is not recommended to avoid ID collisions. If called without arguments, returns the current ID of the track.
Tracks need data to display. TnT Board provides two generic methods to fetch it: tnt.board.track.data.sync, which pulls data into the track synchronously and tnt.board.track.data.async, which relies on ES2015 Promises to fetch the data asynchronously. Both methods offer the same interface and share the same configuration methods.
# track.data (<tnt.board.track.data>)
Specifies a new data retriever for the track. This is used on every board update to retrieve new data to display
# tnt.board.track.data.sync ()
Specifies a synchronous data retriever.
# tnt.board.track.data.async ()
Specifies an asynchronous data retriever.
# tnt.board.track.data.empty ()
Convenience data element for tracks that doesn't require data. It is based on the synchronous data retriever so it still supports the same methods.
# data.retriever (<callback>)
Sets a callback that retrieves the data to visualise in the track. This callback is called passing the location object as its argument to allow positional data retrievals. This location object has the from and to properties. Inside of the callback, this is set to the current track. The callback is expected to return an array of objects (if the data is sync) or a Promise that resolves to an array of objects (if the data is async). These returned objects represent the elements to be displayed in each update of the board
# data.elements ()
Returns the elements that resulted from the last retrieval. Normally, there is no need to call this method directly since it is called implicitely by the display of the visualisation. It is useful though if the data needs to be edited before being passed to the Display
Once a track has retrieved its data, it needs to display it. TnT Board provides several ready-to-use data displays that can be ready-to-use by the tracks (see for example tnt.board.track.feature.block or tnt.board.track.feature.pin). These ready-to-use displays are based on the generic display interface and hence expose all the methods described for the generic interface. Creating custom features is also possble using the generic interface.
Each display is composed of one or more visual features. A display with more that one feature can be used to display different types of data in the same track (see tnt.board.track.feature.), for an example).
# track.display (<tnt.board.track.feature>)
Specifies a new data display for the track. This is used everytime new update is made in the track. If called without arguments, the current display is returned.
# [interface] tnt.board.track.feature ()
General interface for creating visual displays of data. This interface exposes four methods to configure the feature, create, mover, distribute and fixed. These methods are called interface methods and can be used to create new displays.
To understand how to use these interface methods it is useful to understand the interaction model in TnT Board:
TnT Board also offers several ready-to-use displays built on top of this general interface and described below.
The interface also exposes several methods that are inherited by the ready-to-use displays.
# [interface method] feature.create (<callback>)
Specifies how new elements are rendered. Accepts a callback that is called with a d3 selection containing the new elements on every data update. Inside of this function, this is set to the current track. When this method is called without arguments returns the current value.
# [interface method] feature.distribute (<callback>)
Distributes the elements to display in the track. Accepts a callback that is called with a d3 selection containing the elements displayed in the track. Inside the callback, this is set to the current track. When called without arguments this method returns the current value.
# [interface method] feature.move (<callback>)
Specifies how the existing elements are moved when the board is panned or zoomed. Accepts a callback that is called with a the d3 selection containing the current elements in the track. Inside of the callback, this is set to the current track. When called without arguments this method returns the current value.
# [interface method] feature.fixed (<callback>)
Sets a callback to display non-scaled elements in the display. There are cases where the track needs to dispay non-scaled visual elements (fixed while panning or zomming) like rulers, baselines, etc. The method specified with this callback is called on display initialisation passing the board's width as its argument. In this function, this is set to the current track. When called without arguments this method return the current guider function.
# feature.update ()
Updates the track with the current data elements. This is called automatically with every data update but can be called at any point. This is useful to update manually a track individually. This method expects to have this set to the track it belongs to.
# feature.reset ()
Resets the visualisation of a track. This method expects to have this set to the track it belongs to. In the resetting process all the SVG elements with classes tnt_elem, tnt_guider and tnt_guider are removed.
# feature.index (<callback>)
Specifies an index function to link elements between successive track updates. When a track is updated and the new data is retrieved, the display needs to know which elements are new, which have dissapeared and which are currently in the display. This binding of elements is made before the new data is displayed and is based on this function. This function is called on every (new & old) element passing the elements as its argument. Elements for which the index function returns the same value are linked or bound together. By default data are linked based on their position in the data array.
# display.color (<string>)
Specifies the foreground color of the elements to display in the track. Color names ("red") and hexadecimal codes ("00FF00") are allowed. If called without arguments, the current color is returned. By default all elements are black.
# tnt.board.track.feature.location ()
Creates a new location feature for a track. This is a data-less display that shows the current range of the board in the track
# tnt.board.track.feature.axis ()
Creates a new axis feature for a track. This is a data-less display that shows the x-axis of the plot in the track
# axis.orientation (<string>)
Sets the orientation of a tnt.board.track.feature.axis feature. It accepts a string as argument that can be either "top" or "bottom"
# tnt.board.track.feature.block ()
Creates a new block-based feature for a track. This feature expects the data as an array of objects containing numerical start and end properties, although the name of the properties is configurable.
# tnt.board.track.feature.pin ()
Creates a new pin-based feature for a track. This feature expects the data as an array of objects containing numerical pos and val properties, although the name of the properties is configurable. The pos property refers to its x-position in the track and the val property refers to the height of the pin in the track and expects a number in the y domain (by default, between 0 and 1).
# pin.domain (<array>)
Sets the domain for the y-axis in the tnt.board.track.feature.pins feature. It expects an array of numerical values representing the lower and upper limit respectively for the y-axis. By default the domain is [0,1]. Called without arguments return the current domain.
# tnt.board.track.feature.line ()
Creates a new line-based feature for a track. The line is defined by a series of points in the track. This points are applied a tension to smooth the connections between the points. This feature expects the data as an array of objects containing numerical pos and val properties, although the name of the properties is configurable. The pos property refers to the x-position of each point in the track and the val property refers to the height of the points in the track and expects a number in the y-axis domain (by default, between 0 and 1).
# tnt.board.track.feature.area ()
Creates a new area-based feature for a track. This feature is based on the tnt.board.track.feature.line feature but coloring the area behind the curve.
# tnt.board.track.feature.vline ()
Creates a feature that displays vertical lines in the specified positions. It expects an array of objects having a field representing the x-coordinate of the lines in the track. This value is the same one specified in the index property of the display