SVG interaction#

Graphviz provides the functionality to output svg images. We draw on this feature and extend the svg files with a script to allow interactive actions. This interactivity, will be single shot, which means that the svg file will be generated by a single clingo call and no further interaction with the solver will be possible. Therefore, all information for the interactivity should be rendered in the same file and no information of what has been clicked can be accessed.

Warning

Command line

This functionality is limited to the command line using the integration with clingo with the --viz-encoding parameter.

Interaction#

Interaction can be defined for any element using the attribute class. This attribute is mapped into a css class for which functionality will be internally provided. The class value will be a string based on the event, the element in which the event is triggered, a css style property, and the corresponding value. To generate this string we provide the following python function:

@svg(Event,ElementID,PropertyName,PropertyValue)

  • Event: The available events are “click”,”mouseenter”,”mouseleave” and “contextmenu”. Where contextmenu is the right click event

  • Element: The id of the element in which the event is performed

  • PropertyName: The name of a css style property to be set

  • PropertyValue: The value of the css property

Example

Expanding adjacent nodes on click “When N1 is clicked, the visibility of N2 is set to visible”

node(1..4). edge((1,2..3)). edge((3,4)).
attr(node,N2,class,@svg(click,N1,visibility,visible)):-edge((N1,N2)).

Initial style#

Initial svg style can be set using the function @svg_init(PropertyName,PropertyValue)`

Example (continuation)

Set all nodes as hidden except for node 1.

attr(node,N,class,@svg_init(visibility,hidden)):-node(N), N!=1.

Available styles#

Warning

SVGs are exported using html group tags <g>. All properties will be set on the group, this means that properties of elements inside the group will not be overwritten. We alleviate this issue exclusively for changing colors as seen below.

Setting a color

As mentioned above, some properties, like fillcolor will not be overwritten by the css style property. To tackle this limitation, we provide a special string @svg_color(), to represent the css string currentcolor. This can be used as the attribute value to different graphviz color attributes (color, fillcolor, fontcolor, etc.) and will be replaced by the color set on the group by the svg class.

Example (continuation)

Change the color on hover

attr(node,N,style,filled):-node(N).
attr(node,N,fillcolor,@svg_color()):-node(N).
attr(node,N,class,@svg(mouseenter,N,color,green)):-node(N).
attr(node,N,class,@svg(mouseleave,N,color,blue)):-node(N).

API usage#

For API usage, the ClingraphContext should be provided. Additionally, the following functions must be called by hand:

  • add_elements_ids: with the Control object before calling clingo.

  • add_svg_interaction: with the svg paths after rendering.

See the API Documentation of Clingo Utils for details.

Example API

fbs = []
ctl = Control(['--warn=none'])
add_elements_ids(ctl)
ctl.load('examples/doc/example7/example7.lp')
ctl.ground([("base", [])], ClingraphContext())
ctl.solve(on_model=lambda m: fbs.append(Factbase.from_model(m)))
graphs = compute_graphs(fbs)
paths = render(graphs,directory ='out',format='svg')
add_svg_interaction(paths)

Limitations#

  • Labels are not linked to a style and therefore can’t be changed interactively. A way around this is to create multiple layers of nodes with the same position and change their visibility. See the minesweeper.lp example on this approach.

  • The layering on nodes and edges can’t be controlled. Which means we won’t know which elements will be on top.

  • Properties are set on group elements and are not overwritten in the children.

  • The position of the elements is fixed, therefore expanding the size of the image on demand is not possible. Instead, the visibility of the elements can be changed, but the position will be the same.

Examples#

Multiple examples using svg interactivity can be found in the examples folder: