All Manuals > CAPI User Guide and Reference Manual > 21 CAPI Reference Entries

stacked-tree Class


A pane that displays a tree of items in a "stacked" drawing, where each item has an associated value and child items that represent a fraction of that value. Each item is displayed as a rectangle whose width corresponds to the value. Child items are displayed below the item to make a stack of rectangles.





An object which is the root of the tree of items, or nil.
A designator for a function.
A non-negative real or nil.
A designator for a function or nil.
A list of colors.
A designator for a function or nil.
A designator for a function or nil.
A boolean.
A positive real or nil.
A string or nil.



The class stacked-tree is a subclass of output-pane, which displays a tree of items in a "stacked" drawing. In a stacked drawing, each item of the tree is represented by a horizontal rectangle. The height of the rectangle is fixed to accommodate the height of the font of the stacked-tree, while the width corresponds to the "value" of the item. The children of each item are drawn side-by-side below the item itself, to make a stack of rectangles ("stacked").

Within each item's rectangle, the stacked-tree displays a label, consisting of the item's name (the third value of item-function, see below) and the percentage of the item's value with respect to the value of the stacked-tree. The name and/or percentage are omitted if the rectangle is not wide enough.

root and item-function specify the tree that the stacked-tree is displaying. root can be initialized by the :root initarg or set by using (setf stacked-tree-root) or modify-stacked-tree. Likewise, item-function can be initialized by the :item-function initarg or set by using (setf stacked-tree-item-function) or modify-stacked-tree. The stacked-tree uses item-function to traverse the tree starting from root.

item-function must be a designator for a function with two arguments: the stacked-tree and an item. It should return three values:


A real or nil. If item-value is a positive real, it specifies the item's value, which affects the width of the rectangle used to represent it. If item-value is nil, then the stacked-tree computes the value as the sum of the values of the item-children. If item-value is not positive, then the item is ignored.


A list of items that are the children of the item argument. If item-children is nil then the item is a leaf item and has no children.


A string or nil. When item-name is non-nil, the string representation of it (the result of calling the print-function inherited from collection) is displayed within the rectangle. Just the rectangle is displayed if item-name is nil.

Both root and elements of item-children returned by item-function can be any object. The only requirement is that item-function returns useful values when called with this object. Thus the tree is completely defined by root and by what item-function returns.

stacked-tree calls item-function on items down the tree until either a leaf item is reached (that is when item-children is nil), or when the depth of the tree reaches max-level, if that is non-nil.

Note: Currently there is nothing else to stop the descent down the tree, so you must either have a finite tree, that is your item-function must return nil as the item-children at some level on every branch, or you must supply a non-nil max-level.

If value is non-nil, it specifies the value on which to base the percentage computations when displaying items. If value is nil or not specified, it defaults to the item-value of root, which is the natural value in many cases, but not always. For example, the Profiler tool in the LispWorks IDE uses a value that is the number of times that the profiling was done, while the item-value of its root is the sum of the number of times that each process was profiled, which will be much larger when you profile more than one process.

color-function or colors specify the background color used for each displayed rectangle.

If color-function is non-nil, then colors is ignored. color-function is called for each item, the first time the item is displayed, with two arguments: the stacked-tree and the item. It must return a color specification (a color-spec or a recognized symbol, see 15 The Color System), which is then used as the background color of the rectangle for the item.

If color-function is nil, then colors is used. colors defaults to a plausible list of colors, so it does not need to be specified. If it supplied, it must be a list of color specifications. The stacked-tree selects a random color from this list for each item the first time the item is displayed.

Note: If you do not specify colors or color-function, then the stacked-tree automatically uses darker colors when the window is running with a dark theme. If color-function is non-nil, then after a color mode switch, color-function is called again for each item that is displyed. color-function can use top-level-interface-dark-mode-p on the top-level interface of the stacked-tree to decide whether it is dark mode or not, but it is probably better to set something inside the top-level-interface-color-mode-callback of the interface. If you supply colors, then it defines a fixed set that does not change. In this case, you probably want to also set the foreground, so the the color of the text does not chnage either.

If motion-callback is non-nil, it is called when the user moves the mouse over the stacked-tree, with three arguments: the stacked-tree, the item associated with the rectangle at the mouse position or nil if the mouse is not over any rectangle, and a vector specifying the coordinates of the item (or nil if the item is nil). The vector contains eight elements:

0,1,2,3: x, y, width, height

x, y, width, height of the item's rectangle in internal coordinates. Note that the rectangle may have only a partial overlap with the visible area, meaning that only part of it is visible.

4: label-offset.

The horizontal offset in pixels of the beginning of the label from the left side of the rectangle, that is the label's left side is x + label-offset.

5: label-draw-width

The width in pixels that is available to display the label. This is always smaller than the width by a few pixels, and if the rectangle is not visible, may be much smaller or 0.

6: label-width

The width in pixels of the label that should be displayed (as returned by get-string-extent when called with the label).

7: percent-width

The width in pixels that is required to display the percentage for the item.

If highlight is non-nil, when the user moves the mouse over the stacked-tree, the rectangle under the mouse is highlighted.

Note: Both motion-callback and highlight are implemented by defining the :motion gesture in the input-model of the stacked-tree. If you supply an input-model containing :motion (see output-pane), then this will override the internal one, so motion-callback will never be called and highlight will not have any effect.

empty-tree-string, if non-nil, should be a string. The default is "Empty STACKED-TREE displayer". It is displayed in the stacked-tree if you set root to nil, or when a non-positive item-value is returned when item-function is called on root.

If item-menu-function is non-nil, it is called when the context menu needs to be raised (normally by right-click of the mouse), with two arguments: the stacked-tree and the selected item (or nil if none is selected). It should return a menu, menu-component or nil. If item-menu-function returns a menu, then it is used as the context menu. If it returns a menu-component, LispWorks makes a menu containing the component followed by the default stacked-tree menu (described later). If it returns nil, LispWorks raises the default stacked-tree menu. If item-menu-function is nil, LispWorks also raises the default stacked-tree menu.

Note: item-menu-function is called from the make-pane-popup-menu method of stacked-tree. You can completely override this by using the :pane-menu initarg (see 8.12 Popup menus for panes), or by defining your own make-pane-popup-menu method specializing on stacked-tree and your own interface class.

Note: When the menu is raised as a result of a mouse click within a rectangle that is associated with an item then this item is selected while the menu is visible. When the menu has been dismissed, if the contents and the selection of the stacked-tree are still the same, then the selection goes back to the item that was selected before the mouse click.

Description: capi:output-pane features

Some features of stacked-tree are inherited from output-pane as described here.

If you supply a display-callback then it will be called after the stacked-tree has drawn what it wants to draw.

If you supply a resize-callback, then the stacked-tree ensures that the selected item is visible after calling your callback.

stacked-tree forces coordinate-origin to be :fixed-graphics.

The stacked-tree has default initargs for :draw-with-buffer, :horizontal-scroll and :vertical-scroll (all t). If you override any of these you will affect its behavior.

The stacked-tree implements its user input interaction (see below) using the input-model of output-pane. If you supply the :input-model initarg, its value will be appended before the internal input-model of stacked-tree, so your callbacks will override the internal ones. Note that this affects all interaction, including selection of an item. Your input-model callbacks can use stacked-tree-item-at-point to find the item at the x,y coordinates.

Description: capi:choice features

Some features of stacked-tree are inherited from choice as described here.

The interaction of stacked-tree is always :single-selection. Setting the items signals an error.

choice-selection and choice-selected-item can be used in the usual way, including setting them. When the selection is set, the stacked-tree ensures that the selected item is visible.

The selection-callback and action-callback (inherited from callbacks) can be used, and are called due to the input-model as described above.

Description: Mouse interaction

In the following discussion, root-width is the width in pixels of the rectangle used to display root. Whenever root is changed (and initially), root-width is set such that width of the rectangle used to display root is the visible width of the stacked-tree.

Moving the mouse over a stacked-tree calls motion-callback if it is non-nil, and highlights the item under the mouse if highlight is non-nil.

Left-click selects the item that was clicked.

Left-double-click on a item changes the root-width such that the width of the clicked item's rectangle matches the visible width of the stacked-tree, and scrolls horizontally such that the item's rectangle starts at the left of the stacked-tree.

Left-click and drag pans the stacked-tree, scrolling it such that the clicked point follows the mouse.

Description: Keyboard interaction

The arrow keys change the selected item in the direction indicated if possible. The Down key moves to the first child of the currently selected item (if any). The Left and Right keys move to the item at the same depth if there is any, which may be on a completely different branch of the tree.

The following gestures are also available:

Ctrl-+, Ctrl--: Zoom in, zoom out.

Zooming increases or decreases the root-width. It does not affect the vertical dimension.

Ctrl-i, Ctrl-o: Zoom in and out in large steps.

Zoom like Ctrl-+ and Ctrl--, but in larger steps.

Return, Ctrl-Return: Action callback, alternative action callback.

See callbacks.

Ctrl-r: Reset root-width.

Reset the root-width to its initial value, so the root of the tree has the visible width of the stacked-tree at the time it was first displayed, and scroll the root to the left of the stacked-tree.

Ctrl-b, Ctrl-f: Go backwards, Go forwards.

Go to the previous or next state of the display. Whenever the root-width changes or the user left-clicks, the stacked-tree records the current state of the display, including the root-width and scroll position. It uses a ring of length 50 for this record. Ctrl-b and Ctrl-f rotate around this ring.

Ctrl->, Ctrl-<: Increment font size, decrement font size.

Try to increment or decrement the font size by one point, and if this fails then try changing the font size by two points. If the font size changes then the height of the rectangles is adjusted to fit the new font height.

Description: context menu

The stacked-tree context menu contains items to perform the operations listed for keyboard interaction above. It is intended mainly as a way for the user to find the keyboard interaction shortcut. Note that if you override the input-model, and you redefine some of the keys, the menu will be confusing and you should replace it by your own menu.


The stacked-tree is useful when the values of an item's children sum to the value of the item itself or less. If the values of the children sum to more than the value of the item, they will overflow to the right of the item and clash with the children of the item's next sibling.

The stacked-tree is used in the Stacked Tree tab of the Profiler tool in the LispWorks IDE.

When (setf stacked-tree-root) or modify-stacked-tree is used to set the root of a stacked-tree that is already displayed, it immediately computes an internal representation by traversing the tree. This means that if the tree is big, this operation may take enough time to cause a noticeable delay.

See also


CAPI User Guide and Reference Manual (Macintosh version) - 01 Dec 2021 19:31:27