Visualization is central to many domains, including data analysis and artificial intelligence. Nowadays, it has never been so easy to write a visualization. Most programming languages come with several libraries dedicated to visualizing data. As such, the technical aspects necessary to implement a visualization engine and to build a visualization are now largely understood. Despite all the experience gained by the software engineering community in building efficient visualization engines, there are still some challenges that have been poorly addressed globally. In particular, one of the challenges that needs to be properly addressed when designing a library to visualize data is being able to integrate visualizations in an existing production environment. Connecting and integrating one or more visualizations in a given environment is an important and non-trivial challenge. Agile visualization, as promoted by the Roassal visualization engine for the Pharo programming language, provides a solution to that problem, which is the topic of this book. This chapter develops the idea of Agile visualization.
All the code provided in this chapter is available at https://github.com/bergel/AgileVisualizationAPressCode/blob/main/01-04-AgileVisualization.txt.
Visualizing Classes as a Running Example
This chapter incrementally builds visualizations of a software component source code. From a data point of view, a software source code is a complex piece of data: source code does not easily fit in a .csv file and standard data analyses techniques cannot be run on software source code. Visualizing software source has many applications, ranging from software quality assessment to reengineering the software architecture. As such, visualizing software source code is a reasonable and non-trivial task.
Figure 4-1 represents the class hierarchy of the Collection component of Pharo. The Collection component is an essential part of Pharo and consists of a set of classes to build collections, lists, and arrays of Pharo objects. The visualization uses a simple metaphor in which each box is a class. Lines indicate inheritance, and in particular, a superclass is located above its subclasses. The height of a box indicates the number of methods defined in the represented class, while the width represents the number of variables. The color of the boxes ranges from gray to red, indicating the number of lines of code of the represented class. A tall and large box indicates a class with many methods and is defined by many lines of code. Conversely, a small gray box indicates a class that doesn’t have many methods or variables and has only a few lines of code. This visualization gives an overview of the source code distribution over the class hierarchy. It also enables you to spot exceptional entities (i.e., classes that are visually very different from other classes).
We will now detail the script. The classes variable refers to a set of Pharo classes. Each class is represented as an RSBox object, added to the c canvas. One important feature of Roassal is support of the connection between a graphical shape and the object model represented by the shape. This connection is expressed using the model: message, as in the expression RSBox new model: aClass. The use of the model: message makes the connection explicit between an arbitrary object (e.g., a class in this case) and the graphical shape.
To define the shape and color of each box, you use normalizers, which use the model object. A class in Pharo answers to many different messages. For example, the String numberOfMethods expression gives a number greater than 300, which is the number of methods defined in the String class. The number of methods defined in the String class depends on the considered version of Pharo. Similarly, you can send the numberOfVariables, numberOfLinesOfCode, superclass message to a class to obtain the number of instance variables, the number of lines of code, and the superclass, respectively. Lines are built between classes to indicate inheritance using a dedicated object, the RSLineBuilder. The classes, positioned in the canvas using the tree layout, are draggable and the class name appears as a popup when the mouse cursor hovers a class.
Example in the Pharo Environment
The provided code example looks relatively standard, and the same visualization can easily be built using any modern visualization engine. If you are familiar with a library such as D3.js or Matplotlib, you might say: “Well, I can do the same”. This is true up to a point. The real benefit of Roassal is not the API. Beneath the surface, Roassal offers a number of features to make the visualization navigable and facilitate the integration within the Pharo environment.
A graphical shape in Roassal is linked to an object model. The simple expression RSBox new model: aClass makes a box a façade of a class, and this way of representing data is very different compared to the way other engines operate. By having the connection between a graphical shape and the object model explicit, you can click a shape to inspect the object model. In this case, you can click that box to open an Inspector on the clicked class. The Inspector provides a number of built-in visual representations for the inspected object.
In Figure 4-2, the most-left pane represents the visualization of the classes given in the initial script. In this first visualization, the Interval class is selected. The selection displays the method call-graph at the center. In the call-graph, the collect: method is selected, and it shows the method source code on the right side.
To summarize, you have independently built two visualizations. The Inspector framework exposes them in a very convenient way while supporting their navigations. You can jump from the first one to the second one, even their scripts are independent.
Closing Words
Imagine being empowered with a tool to easily prototype visualizations and to embed them in your work environment. If the cost of building visualizations and their integration is low enough, you would likely write more visualizations more frequently. As soon as visualizations are easy to write and use in daily tasks, visualization will pop up like mushrooms in your production environment. We define the notion of agility in data visualization as lowering the production cost of a visualization, and lowering the cost of integrating visualization in a production environment. Agility turns a beautiful picture in a tool to enable practitioners to act upon a valuable domain and enjoy immediate feedback.
Roassal3 is the result of more than ten years of hard work. The Pharo and Smalltalk communities have played an important role in shaping the API and identifying the key aspects of what Agile visualization is.
What Have You Learned in This Chapter?
Visualizations can be defined for any object, by simply defining visualization methods on a class. A visualization is hooked into the Inspector framework using the pragma inspectorPresentationOrder:title: and using the SpRoassal3InspectorPresenter class. Several visualizations can be defined in a class.
Clicking a shape opens a new pane in the Inspector and offers a visualization defined in the class of the selected object.