When the graph is complex, it can be interesting to customize the look of the graphical representation, highlight some nodes, some edges ...
It is possible to change lots of aspects of the style.
There are global style settings that are applied to all elements of the graph, and local style settings that are applied only to specific nodes, edges, ports (a port being an input or output of the node).
A global style setting is defined in a dictionary. A local style setting is a method of a class that must be overridden.
To generate a graph with some style you use the option style of the graphviz function:
schedule.graphviz(file,config=your_config,style=your_style)Two default styles are available:
Style.default_style()Style.dark_style()
If you want to change some settings, you define a dictionary with new values for those settings and you create a Style object using this dictionary:
myStyle=Style(myDictionary)
You don't need to define a value for all the settings recognized in a dictionary. You only need to provide values for the global settings you want to change. For instance:
newBackground = {"graph_background" : "gray"}Any setting not defined in the dictionary will use a value from the default style. And if you don't pass any dictionary, the default global settings will be used.
The list of all global settings is:
_DEFAULT_STYLE = {
# Graph global settings
"graph_background" : "white" # Color of graph background
,"graph_font" : "Times-Roman" # Font used in the graph
# Node settings
,"node_color" : "none" # Fill color of any node
,"node_boundary_color" : "black" # Boundary color of any node
,"node_label_size" : "14.0" # Font size of node labels
,"node_label_color" : "black" # Color of node labels
# Special node settings (Constant node and delay box)
,"special_node_border" : "1" # Thickness of node boundary
# Node port settings (port = input or output of a node)
,"port_sample_color" : "blue" # Color of number of samples
,"port_sample_font_size" : "12.0" # Font size of number of samples
,"port_font_color" : "black" # Color of a port
,"port_font_size" : "12.0" # Font size of a port
# Edge settings
,"edge_color" : "black" # Color of any edge
,"edge_label_size" : "12.0" # Font size of any edge label
,"edge_label_color" : "black" # Color of any edge label
,"edge_style" : "solid" # Edge style (dashed, dotted ...)
,"arrow_size" : 0.5 # Arrow size at end of edge
}Color settings and style settings must be using syntax and names recognized by graphviz.
To change the setting for a particular element of the graph (like a specific node), you need to inherit from theStyle class and override a specific method.
For instance, to change the filling color of a specific node, you could define:
class MyStyle(Style):
def node_color(self,node):
if node.isPureNode:
return("burlywood1")
return super().node_color(node)This node function will change the filling color of all nodes that are pure functions (like CMSIS-DSP functions with no state). Otherwise, the default styling will be used.
This object can be created with a dictionary of global settings:
MyStyle(globalStyle)but if no dictionary is used, the default settings are used by MyStyle
When you write the methods of your style object, you may need to access some information about the node, edge or port. Most of the time, this information is passed as arguments to the method. But sometimes, you need to extract some information from those arguments.
You can use the methods of the node object when you receive a node object. The method of a FIFO when it is a FIFO object. But the style object is also providing some additional methods to make it simpler to access some information:
def isFIFO(self,edge):Since the graph can be either pre-compute or post compute, the edge may have different description.
In pre-compute mode, an edge is a just a pair of node. In post-compute mode, it is a FIFO.
def fifoLength(self,edge):Return the length of the FIFO (in number of samples). If it is applied to a pre-compute edge, it will return None.
def edgeSrcNode(self,edge):Get the source node in pre or post compute graphs
def edgeDstNode(self,edge):Get the destination node in pre or post compute graphs
def edgeSrcPort(self,edge):Get the source port in pre or post compute graphs
def edgeDstPort(self,edge):Get the destination port in pre or post compute graphs
def getPort(self,node,i,input=False):Get the port number i on inputs or outputs of a node. It will raise an exception if the index i is negative or bigger than the number of inputs or outputs.
Controlled with the graph_backround dictionary item:
Controlled with the graph_font dictionary item:
Controlled with the node_boundary_color dictionary item:
Controlled with the node_color dictionary item:
Controlled with the node_label_color dictionary item:
Controlled with the node_label_size dictionary item:
Controlled with the port_font_color dictionary item:
The port (like o1, o, i) colors are changes.
Controlled with the port_font_size dictionary item:
The port (like o1, o, i) font size are changes.
Controlled with the port_sample_color dictionary item:
The color of the number of samples is changed.
Controlled with the port_sample_font_size dictionary item:
The font size of the number of samples is changed.
Controlled with the special_node_border dictionary item:
Special nodes are virtual nodes (they do not exist in the C++ code):
- Constant nodes
- Delay box
Constant nodes are argument of pure functions and just C variables (not real nodes).
Delay box are additional samples in a FIFO.
Controlled with the edge_color dictionary item:
Controlled with the edge_label_color dictionary item:
Controlled with the edge_label_size dictionary item:
Controlled with the edge_style dictionary item:
Edge style is : solid, dashed, dotted ... please refer to the graphviz documentation..
Settings applied to a specific node, edge or port.
def edge_color(self,edge):In this example, the color of the edges connecting CMSIS-DSP nodes is changed.
def edge_label(self,edge):In this example, the label of the edges connecting CMSIS-DSP nodes is changed. It is on two lines instead on being on one line.
Those labels are graphviz HTML like labels.
def edge_labe_color(self,edge):In this example, when the FIFO length >= 320, the edge label is in red.
def edge_label_size(self,edge):In this example, when the FIFO length >= 320, the edge font size is increased.
def edge_style(self,edge):In this example, the style of the edges connecting CMSIS-DSP nodes is changed to dashed.
def node_boundary_color(self,node):CMSIS-DSP nodes are colored differently in this example.
def node_color(self,node):CMSIS-DSP nodes are colored differently in this example.
def node_label(self,node):arm_scale_f32 nodes are now named * in this example. The label has been customized.
def node_label_color(self,node):CMSIS-DSP nodes are colored differently in this example.
def node_label_size(self,node):CMSIS-DSP nodes have a different label font size.
def port_font_color(self,item,i,input=False):Output ports of CMSIS-DSP nodes are colored differently in this example.
def port_font_size(self,item,i,input=False):Output ports of CMSIS-DSP nodes have a different font size.
def port_sample_color(self,nb_sample):When number of samples for an IO is >= 320, it is displayed in red in this example.
def port_sample_font_size(self,nb_sample):When number of samples for an IO is >= 320, the font size is increased
def const_border(self,const_name):Border around the HALF node is increased.
def const_boundary_color(self,const_name):Color of the HALF node is changed.
def const_color(self,const_name):Color of the HALF node is changed.
def const_edge_color(self,name,dstPort):Color of edges connecting the HALF node to the CMSIS-DSP function are changed.
def const_edge_style(self,name,dstPort):Style of edges connecting the HALF node to the CMSIS-DSP function are changed.
def const_label_color(self,const_name):def const_label_size(self,const_name):def delay_border(self,delay_value):def delay_boundary_color(self,delay_value):def delay_color(self,delay_value):def delay_edge_color(self,srcPort,nb_samples):def delay_edge_style(self,srcPort,nb_samples):def delay_label_color(self,delay_value):def delay_label_size(self,delay_value):









































