Consider the "Custom styling" example in cell 11 in this link from the pytransitions github pages. (tweeked code below)
I would like to add a reset event. When Reset
is triggered from most (but not all) other states the model returns to a known state. In this example that is INITIAL
.
Doing this for a large digraph creates a lot of clutter, omitting it leads to lack of documentation.
The solution is to add a fake transition:
machine.add_transition("Reset", "* ANY_STATE *", "INITIAL")
So a 'fake' global state fixes the issue, and draws properly. It does not care the state is not defined.
However the styling code example uses the state
key of the model but that does not exist as * ANY_STATE *
is fake and not in the list of states.
How to style the dynamicaly added state?
Updated example:
class Model:
pass
model = Model()
transient_states = ['T1', 'T2', 'T3']
target_states = ['G1', 'G2']
fail_states = ['F1', 'F2']
transitions = [['eventA', 'INITIAL', 'T1'], ['eventB', 'INITIAL', 'T2'], ['eventC', 'INITIAL', 'T3'],
['success', ['T1', 'T2'], 'G1'], ['defered', 'T3', 'G2'], ['fallback', ['T1', 'T2'], 'T3'],
['error', ['T1', 'T2'], 'F1'], ['error', 'T3', 'F2']]
machine = GraphMachine(model, states=transient_states + target_states + fail_states,
transitions=transitions, initial='INITIAL', show_conditions=True,
use_pygraphviz=False, ## Jupyter does not work with pygraphviz ##
show_state_attributes=True)
machine.machine_attributes['ratio'] = '0.471'
machine.style_attributes['node']['fail'] = {'fillcolor': 'brown1'}
machine.style_attributes['node']['transient'] = {'fillcolor': 'gold'}
machine.style_attributes['node']['target'] = {'fillcolor': 'chartreuse'}
# **** EXTRA LINE ****
machine.add_transition("Reset", "* ANY_STATE *", "INITIAL")
# As before
model.eventC()
# customize node styling - NOTE: id(model) is the dict key
for s in transient_states:
machine.model_graphs[id(model)].set_node_style(s, 'transient')
for s in target_states:
machine.model_graphs[id(model)].set_node_style(s, 'target')
for s in fail_states:
machine.model_graphs[id(model)].set_node_style(s, 'fail')
# draw the whole graph ...
model.get_graph()