Measuring complex “organisms” such as software systems involves a broad range of different metrics. The display is a precious, yet limited resource, because the amount of information a view is able to present at any moment is limited. Moreover, displaying too many details can overwhelm the users. Therefore, it is crucial to allow the users to chose the software characteris- tics that are important for the task at hand. To provide assistance for a broad range of tasks, we strived for extensive configurability of CodeCity, achieved mainly through the view configuration mechanism. A view configuration is a specification defining for each model element type:
1. the visibility, i.e., whether to incorporate it in the visualization, 2. the associated glyph type,
3. the layout to use for its components (e.g., the layout for packages will be used to place sub-packages and classes), and
4. the visual mappers associated with each property of the chosen glyph.
Figure 6.3. User interface to the view configuration
View configuration tuning is done visually, using the graphical user interface in Figure 6.3, which enables the modification of every view configuration parameter. The preview panel shows how a very small code city would look like with the current view configuration, which allows one to quickly understand the effect of each configuration parameter on the visualization.
In terms of view configuration management, CodeCity allows both saving a useful configu- ration and loading a saved configuration, either for direct use or as a starting point to building new configurations. The view configuration objects are able to construct a building script, i.e., a string which, once evaluated by the Smalltalk compiler, returns aViewConfigurationobject equivalent to the original one. This mechanism, which relies on the reflection supported by Smalltalk, allows us to store a view configuration as source code and therefore manage it with the versioning system. The major advantage of this approach over a text-based one (e.g., saving the view configuration in an XML file) is that whenever a class that is part of the view con- figuration (i.e., anyGlyph,Layout, orMapper) is subject to a renaming refactoring[FBB+99], the view configurations are updated automatically. The most complex components of a view configuration are the mappers, described next.
The Property Mapping Mechanism
The mapper class hierarchy, presented in Figure 6.4, provides access to various mapping strate- gies, including the three examples detailed in Section 3.3.2, i.e., identity mapping, box plot based mapping, and threshold based mapping. Each concrete mapper type has a corresponding user interface component, presented in Figure 6.5.
computeValueOn: asScript Mapper computeValueOn: defaultConstantValue asScript constantValue ConstantMapper block computeValueOn: defaultBlock asScript BlockMapper computeValueOn: IdentityMapper inputRangeResolution LinearMapper minimumInput maximumInput buildConverter asScript minimumOutput maximumOutput NumericalLinearMapper computeValueOn: buildColorScheme buildConverter asScript startColor endColor spectrumwise ColorLinearMapper computeValueOn: asScript codomain ClusterMapper buildConverter BoxplotMapper buildConverter buildEquidistantThresholds asScript thresholds ThresholdMapper defaultFunction asScript function FunctionalMapper computeValueOn: defaultPopulation buildConverter computeMaximumInput computeMinimumInput sortedFunctionValues population converter PopulationMapper computeValueOn: clashingColorNames preferredFirstColorNames colorNames colorCodesDictionary nextColorIndex ColorCodeMapper
Figure 6.4. Class diagram of CodeCity’s mappers
The key method of the mappers iscomputeValueOn, which is defined in the abstract class Mapper. This method takes a model element as parameter and returns the value of the corre- sponding visual property. For example, it takes aFAMIXClassobject (i.e., the model of a class) as input and returns the numerical value corresponding to the height of the building representing that class.
A ConstantMapper returns the same value regardless of the input and is therefore used to map a common value to all elements of a particular type, e.g., all the edges representing inheritance are colored orange (See Figure 6.5(a)).
AnIdentityMapperprovides the most accurate representation of a metric. For example, we use an identity mapper to map the number of methods of a class on the building’s height, as shown in Figure 6.5(b)).
For more complex mappings, we need to consider the metric values of all the elements— the population—of a particular model type. The simplest type of PopulationMapper is the LinearMapper, which scales the input values to a specified output range.
(a) Constant (b) Identity (c) Linear for colors
(d) Box plot based (e) Threshold based (f) Block (generic)
Figure 6.5. User interface widgets for the various mapping strategies
For example, the ColorLinearMapper uses a color scheme to convert the input property value into a color included in a specified range of the continuos optical spectrum. Figure 6.5(c) shows the color mapper we use for classes: the number of lines of code mapped on a color range from dark gray to intense blue.
The next mapper hierarchy, whose root class isClusterMapper, divides the input range into five or six sub-ranges and assigns a single output value for each of them. TheBoxplotMapper uses the box plot based technique to compute the boundaries between the sub-ranges corre- sponding to the extremely low, low, average, high, and extremely high categories. The box plot based mapper in Figure 6.5(d) maps a value h∈ {1, 3, 6, 12, 40} on the building’s height, accord- ing to the cluster to which its number of methods metric value belongs to. Each output value corresponds to a building type in Figure 3.5.
TheThresholdMapper also divides the input range into sub-ranges, whose boundaries are based on statistical data. The threshold mapper in Figure 6.5(e) maps on the building’s height a value h∈ {1, 3, 6, 12, 40}, according to the cluster to which the number of methods metric value of its class belongs to. This example’s input clusters, corresponding to the number of methods metric for Java classes, are:[0, 2), [2, 4), [4, 10), [10, 15), and [15, ∞).
Finally, theBlockMapperis a generic mapper which requires Smalltalk skills5to “program”
new ad-hoc mappers. Figure 6.5(f) presents a mapper which makes abstract classes semi- transparent (α = 0.5) and concrete classes opaque (α = 1).