Mondrian is a rich API which offers facilities to describe and render graphs. Mondrian is an essential piece of Roassal due to its expressiveness and simplicity of use. For any data structure, Mondrian allows mapping of metric values and properties into visual dimensions, such as shape and colors.
Mondrian is often considered as being the most expressive part of Roassal: highly interactive and flexible visualizations may be the result of just a few lines of code. Mondrian is often the starting point of the Roassal platform.
An online video illustrates this chapter: http://bit.ly/Mondrian-AgileVisualization
As a contrived example, consider the following script (Figure 1.1):
Six gray squares are horizontally lined up. Each square corresponds to a word contained in the array passed to nodes:
. Several layouts are available, thanks to the layout builder (see the description of the layout builder in the Layout chapter). For example, the force layout is activated as:
Edges may be simply added using the edge builder, accessible by sending edges
to the Mondrian builder:
A label may be used instead of a grayed box and the layout may be configured as follows (Figure 1.2):
As a slightly more elaborated example, consider the following example:
The example creates an instance of the class RTMondrian
and assigns this object to the b
variable. Nodes are then set in the builder, which are 300 successive numbers, starting from 1. Each node is represented as a little gray square. Two sets of edges are defined. The first set, described using b edges connectFrom: [ :value | value // 2 ]
, models the relation between a value
and value // 2
. The message //
returns "the integer quotient defined by division with truncation toward negative" as indicated by the comment of the method //
defined in the class Number
(e.g., 9//4 = 2
).
The second set of edges, described using b edges notUseInLayout; connectTo: [ ... ]
, is defined as the sum of the two digits. For a given numerical value
, the expression (value / 10) asInteger
returns the first digit or it and value \ 10
the last digit. Each number is linked to another number representing the sum of its digits (e.g., 15 is linked to 6). These edges are not taken into account for the layout as specified with the message notUseInLayout
.
The first set of edges uses the default shape for lines, which is straight, gray, and non-directed. For the second set, a shape is defined as a Bezier line following the control points given by the expression value // 2
, painted in a translucent blue.
The layout used is cluster
, forming a radial-like appearance. For this set of elements and edges, horizontalTree
, tree
, radial
are all relevant layouts.
The previous examples visualized numerical values and define some connections based on a mathematical relation. Any arbitrary objects may be visualized with Mondrian. Consider the following example that displays data obtained from a CSV (comma separated file):
Figure 2.1 illustrates the result. Data obtained from a CSV description is used in the visualization. Each city and country is represented as a circle. The size of the circle represents the number of people living in the city or the country. We use a logarithmic scale to cope with large variations.
To keep the example concise and self-contained, the CSV content is provided as a Pharo String. If you wish to have the file externally provided, then you may simply have
In that case, a file named file.csv
has to be in the same folder as your Pharo image. A full path may be provided.
As illustrated in the example given above, a script in Mondrian essentially contains five different sections: shape description, node declaration, edge declarations, layout description, normalization.
The message shape
, layout
, edges
sent to an RTMondrian
object returns a shape, layout builder, and edge builders, respectively. Sending the message nodes:
creates some elements using the shape previously defined.
As a first example, consider the following script (Figure 4.1):
The script visualizes the collection class hierarchy obtained with the expression Collection withAllSubclasses
. Relation between nodes is obtained by linking each nodes to its subclasses. A tree layout is then set.
Each box of the visualization represents a class. The height of a class indicates its amount of methods that it defines. The width indicates the number of variables the class defines. The color indicates the number of lines of code the class defines (white = the class with the smallest number of lines of code, black = the heaviest class). Each of Mondrian node is draggable and has a tooltip.
The normalizer may also give a particular color to an element based on an attribute or a property. Consider the following example (Figure 4.2):
The script simply associates a circle to each class, subclass of the class Collection
. Edges indicates superclass links. The cluster layout makes subclasses located around a superclass. Each class has a color, representing the package of a class. Each package has a color, given by the message distinctColorUsing:
.
Mondrian offers a convenient way to nest elements. Each node may act as a space to which nodes may be added. The message nodes:forEach:
has to be used for that purpose. Consider the following example (Figure 5.1):
There are 10 top level nodes, representing the values 0, 10, 20, ..., up to 90. Each node contains an amount of inner values that correspond to the number it represents.
Encapsulating nodes may also have a title and be connected (Figure 5.2):
The use of withTextAbove
makes each encapsulating node have a title above. Node color may be set to reflect particular conditions, as in the following example (Figure 5.3):
Inner nodes may have a proper shape and be connected. Consider the following version of the visualization of the Roassal shapes (Figure 5.4):
File systems have a hierarchy driven by the nesting of folders and files. Consider the following code:
The instruction UIManager default chooseDirectory
opens a file browser to let the user (i.e., you) select a directory. The class UIManager
offers many methods to require input from the user. The message allChildren
, sent to the FileReference
returned by chooseDirectory
, returns a collection of all the file references. For each file directly contained in the selected directory, a hierarchy is shown. The size of a box
representing a file depends on the number of characters contained in that file. A logarithmic scale is used to cope with file size disparities. Thanks to the GT infrastructure, clicking on a file displays its content.