© Alexandre Bergel 2022
A. BergelAgile Visualization with Pharohttps://doi.org/10.1007/978-1-4842-7161-2_13

13. Integration in the Inspector

Alexandre Bergel1  
(1)
Santiago, Chile
 

Pharo offers many powerful and extensible software development tools. One of them is the Inspector, designed to inspect any Pharo object. The Inspector is a central tool in Pharo as it allows you to see the internal representation of an object, intimately interact with an object through an evaluation panel, and define visual representations of an object.

Visualizations built with Roassal can be hooked into the Inspector. Furthermore, navigation through the graph of objects happens by simply clicking Roassal shapes, which can open a new visualization, itself showing clickable shapes. This chapter details the mechanism to embed Roassal visualizations in the Pharo Inspector.

In addition to detailing the support of Roassal by the Inspector, the chapter illustrates the use of Chart (the charting library of Roassal) and Mondrian (the graph library of Roassal).

Pharo Inspector

The Pharo Inspector can be invoked in a number of ways. You can send the inspect message to any object to open the Inspector. For example, you can open the Playground and execute the following code by pressing Cmd+D (on macOS) or Alt+D (on Linux and Windows) or by right-clicking Do It (see Figure 13-1):
c := OrderedCollection new.
c add: 10.
c add: 15.
c add: 19.
c inspect
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig1_HTML.jpg
Figure 13-1

Opening the Inspector

The action of sending inspect opens a new window. Although this can be convenient in many situations, the Inspector can also be open within the Playground window. You can press Cmd+G/Alt+G to embed the Inspector in the Playground window using the following code. In such a case, the inspect message is not necessary (see Figure 13-2):
c := OrderedCollection new.
c add: 10.
c add: 15.
c add: 19.
c
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig2_HTML.jpg
Figure 13-2

Inspecting a collection

Invoking the Cmd+G/Alt+G keystroke splits the Playground into two panes, with the Playground on the left and the Inspector on the right. The Inspector has three tabs—Items, Raw, and Meta. The first tab (Items) lists the items contained in the collection. The second tab (Raw) shows the internal values of the object representing the ordered collection. The third tab (Meta) shows the list of methods defined in the class of the object, OrderedCollection. The tabs that are offered by the Inspector depend on the object to be inspected. For example, inspecting a color object gives a different set of tabs.

In the following sections, you will see how to plug a Roassal visualization as a tab when inspecting an ordered collection. In particular, you will define new tabs to access visualizations.

Visualizing a Collection of Numbers

Open a system browser on the SequenceableCollection class , the superclass of OrderedCollection, and define the following method:
SequenceableCollection>>visualizeListOfNumbers
    | c d |
    c := RSChart new.
    d := RSLinePlot new.
    d y: self.
    c addPlot: d.
    c build.
    ^ c canvas
In the system browser, you should see Figure 13-3.
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig3_HTML.png
Figure 13-3

The visualizeListOfNumbers method, together with the methods defined in this chapter

This visualization can be invoked in the Playground using Cmd+G/Alt+G (see Figure 13-4):
c := OrderedCollection new.
c add: 10.
c add: 15.
c add: 19.
c visualizeListOfNumbers
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig4_HTML.png
Figure 13-4

Visualizing numbers

The Playground splits and the visualization appears on the right pane. This visualization can be improved by adding title ticks with the following method (see Figure 13-5):
SequenceableCollection>>visualizeListOfNumbers
    | c d |
    c := RSChart new.
    d := RSLinePlot new.
    d y: self.
    c addPlot: d.
    c title: 'Visualizing numbers'.
    c addDecoration: RSVerticalTick new.
    c addDecoration: RSHorizontalTick new.
    c build.
    ^ c canvas
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig5_HTML.png
Figure 13-5

Improving the list of numbers

If you want to include the value 0, use the mustInclude0inY method , as in this new version (see Figure 13-6):
SequenceableCollection>>visualizeListOfNumbers
    | c d |
    (self allSatisfy: #isNumber) ifFalse: [
        ^ RSCanvas new add:
            (RSLabel text: 'Need to contain numbers'); yourself ].
    c := RSChart new.
    d := RSLinePlot new.
    d y: self.
    c addPlot: d.
    c title: 'Visualizing numbers'.
    c addDecoration: RSVerticalTick new.
    c addDecoration: RSHorizontalTick new.
    c mustInclude0inY.
    c build.
    ^ c canvas
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig6_HTML.jpg
Figure 13-6

Improving the list of numbers

This new version of visualizeListOfNumbers has a guard to prevent building a chart if the collection does not contain numbers. This small visualization easily scales up. Consider the following script (see Figure 13-7):
numberOfValues := 1000.
y := 0.
c := OrderedCollection new.
numberOfValues timesRepeat: [
    c add: y.
    y := y + ((-30 to: 30) atRandom) ].
c visualizeListOfNumbers
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig7_HTML.png
Figure 13-7

Visualizing a collection containing numbers

This example illustrates how a Roassal canvas can be rendered in the Pharo Inspector. It plots 1,000 values. Since the example does not use a seeded random generator, the graph you obtain may be slightly different. The visualizeListOfNumbers method is called by the script to produce the visualization. However, the integration of Roassal in the Inspector framework may produce the visualization by automatically invoking visualizeListOfNumbers. You can define the inspectorVisualization method to wrap a Roassal canvas into a SpRoassal3InspectorPresenter object:
SequenceableCollection>>inspectorVisualization
    <inspectorPresentationOrder: 90 title: 'Visualization'>
    ^ SpRoassal3InspectorPresenter new
        canvas: self visualizeListOfNumbers;
        yourself
The value 90 provided to the inspectorPresentationOrder: keyword indicates the priority of the tab in the Inspector. A low value indicates that the Visualization tab is located on the left. Since you do not need the evaluation pane, the method can be defined:
SequenceableCollection>>inspectorVisualizationContext: aContext
    aContext withoutEvaluator

The inspectorVisualization and inspectorVisualizationContext: methods are semantically connected by having the first as the prefix of the second.

After defining inspectorVisualization and inspectorVisualizationContext:, evaluating the following script using Cmd+G/Alt+G embeds the visualization in the Inspector (see Figure 13-8):
numberOfValues := 1000.
y := 0.
c := OrderedCollection new.
numberOfValues timesRepeat: [
    c add: y.
    y := y + ((-30 to: 30) atRandom) ].
c
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig8_HTML.jpg
Figure 13-8

Embedding the visualization in the Inspector

If you wanted to keep the chart without the 0 value in the two axes, you could define this method:
SequenceableCollection>>visualizeListOfNumbersNo0
    | c d |
    (self allSatisfy: #isNumber) ifFalse: [
        ^ RSCanvas new add:
            (RSLabel text: 'Need to contain numbers'); yourself ].
    c := RSChart new.
    d := RSLinePlot new.
    d y: self.
    c addPlot: d.
    c title: 'Visualizing numbers'.
    c addDecoration: RSVerticalTick new.
    c addDecoration: RSHorizontalTick new.
    c build.
    ^ c canvas
The canvas returned by visualizeListOfNumbersNo0 has to be wrapped as follows:
SequenceableCollection>>inspectorVisualizationNo0
    <inspectorPresentationOrder: 90 title: 'VisualizationNo0'>
    ^ SpRoassal3InspectorPresenter new
        canvas: self visualizeListOfNumbersNo0;
        yourself
As seen previously, the evaluation pane can be suppressed using the following:
SequenceableCollection>>inspectorVisualizationNo0Context: aContext
    aContext withoutEvaluator
Inspecting the following script highlights the differences between the two visualizations (see Figure 13-9):
c := OrderedCollection new.
-3.14 to: 3.14 by: 0.1 do: [ :x |
    c add: x sin + 3 ].
c
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig9_HTML.png
Figure 13-9

Embedding multiple visualizations in the Inspector

Figure 13-9 shows that the two visualizations are accessible through a dedicated tab in the Inspector. The values kept in the c variable range from 2 to 4. In one visualization, the origin (0, 0) is part of the graph, in the other visualization, it is not. This contrived example illustrates the ability of the Pharo Inspector to render multiple visualizations.

Chaining Visualizations

A collection may contain other collections. In this section, you see how to define a visualization that enables you to navigate through nested collections. Consider this method:
SequenceableCollection>>visualizeCollections
    | m |
    (self allSatisfy: #isCollection) ifFalse: [
        ^ RSCanvas new add:
            (RSLabel text: 'Need to contain collections'); yourself ].
    m := RSMondrian new.
    m shape circle color: Color gray translucent.
    m nodes: self.
    m normalizeSize: #size from: 5 to: 10.
    m layout force.
    m line connectToAll:
            [ :coll | self select: [ :coll2 | coll size = coll2 size ] ].
    m build.
    ^ m canvas

The visualizeCollections method makes sense only if the collection contains other collections. If not, a gentle canvas indicates an error, as expressed in the first lines of the method. The Mondrian API is used to render each collection as a transparent circle. The size of a circle reflects the number of values contained in the represented collection. Circles of the same size are connected with a line.

The visualization is hooked into the Inspector using the following:
SequenceableCollection>>inspectorVisualizationColl
    <inspectorPresentationOrder: 90 title: 'Collections'>
    ^ SpRoassal3InspectorPresenter new
        canvas: self visualizeCollections;
        yourself
Since there is no need to have an evaluator pane, you can define it as follows:
SequenceableCollection>>inspectorVisualizationCollContext: aContext
    aContext withoutEvaluator
Consider this simple example (see Figure 13-10):
x := (-3.14 to: 3.14 by: 0.01).
y1 := x collect: #sin.
y2 := x collect: #tan.
y3 := x collect: #cos.
{ x . y1 . y2 . y3 }
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig10_HTML.png
Figure 13-10

Visualizing nested collections

Figure 13-10 shows three panes. The middle pane is the collection that contains four other collections. Since these four collections are the same size, they are all connected to each other with a line. Clicking a node in the graph opens a new pane, which renders the visualizations you have previously seen.

In the same spirit, here is a more complex example (see Figure 13-11):
numberOfCollections := 100.
c := OrderedCollection new.
r := Random seed: 42.
numberOfCollections timesRepeat: [
    t := OrderedCollection new.
    y := 0.
    (r nextInteger: 100) timesRepeat: [
        t add: y.
        y := y + ((-30 to: 30) atRandom) ].
    c add: t
].
c
../images/489192_1_En_13_Chapter/489192_1_En_13_Fig11_HTML.png
Figure 13-11

Visualizing many nested collections

Figure 13-11 visualizes a larger collection, made of 100 nested collections. Clusters can be easily distinguished in the Collections visualization.

What Have You Learned in This Chapter?

Roassal greatly benefits from the programming environment offered by Pharo. The Inspector, easily accessible from the Playground, is a central tool to support incremental and live programming. The chapter explained the following:
  • How to add visualizations accessible from the Inspector.

  • How to remove the evaluation pane in the Inspector for a particular visualization.

  • Examples of the Chart and Mondrian Roassal components.

The chapter defined a few simple visualizations on the SequenceableCollection class; however, these very same techniques can be applied to any class from any particular domain.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.44.100