transitions
transitions copied to clipboard
Mermaid graph code generation should be prepared for states whose names have spaces or dashes
Mermaid code does not accept states with spaces or dashes. The code should be prepared for this by, at least, sanitizing the names before generating the Mermaid code.
I just pushed a version with "_name_to_id" to the feature branch.
This:
from transitions.extensions.diagrams import HierarchicalGraphMachine
states = ['A state with Spaces', 'B-with-dashes', {'name': 'C.with.dots',
'final': True,
'parallel': [{'name': '1', 'children': ['a', {"name": "b", "final": True}],
'initial': 'a',
'transitions': [['go', 'a', 'b']]},
{'name': '2', 'children': ['a', {"name": "b", "final": True}],
'initial': 'a',
'transitions': [['go', 'a', 'b']]}]}]
transitions = [["start", 'C.with.dots', 'A state with Spaces'], ["", "A state with Spaces", "B-with-dashes"], ["", "B-with-dashes", "C.with.dots"]]
m = HierarchicalGraphMachine(states=states, transitions=transitions, initial="C.with.dots", show_conditions=True,
title="Mermaid", graph_engine="mermaid", auto_transitions=False)
m.start()
print(m.get_graph().draw(None))
will result in this:
---
Mermaid
---
stateDiagram-v2
direction LR
classDef s_default fill:white,color:black
classDef s_inactive fill:white,color:black
classDef s_parallel color:black,fill:white
classDef s_active color:red,fill:darksalmon
classDef s_previous color:blue,fill:azure
state "A state with Spaces" as A___state___with___Spaces
Class A___state___with___Spaces s_default
state "B-with-dashes" as B___with___dashes
Class B___with___dashes s_default
state "C.with.dots" as C___with___dots
C___with___dots --> [*]
Class C___with___dots s_default
state C___with___dots {
state "1" as C___with___dots_1
state C___with___dots_1 {
[*] --> C___with___dots_1_a
state "a" as C___with___dots_1_a
state "b" as C___with___dots_1_b
C___with___dots_1_b --> [*]
}
--
state "2" as C___with___dots_2
state C___with___dots_2 {
[*] --> C___with___dots_2_a
state "a" as C___with___dots_2_a
state "b" as C___with___dots_2_b
C___with___dots_2_b --> [*]
}
}
C___with___dots --> A___state___with___Spaces: start
A___state___with___Spaces --> B___with___dashes
B___with___dashes --> C___with___dots
C___with___dots_1 --> C___with___dots_1_a
C___with___dots_2 --> C___with___dots_2_a
C___with___dots_1_a --> C___with___dots_1_b: go
C___with___dots_2_a --> C___with___dots_2_b: go
[*] --> C___with___dots
Some improvements concerning style:
from transitions.extensions.diagrams import HierarchicalGraphMachine
states = ['A state with Spaces', 'B-with-dashes', {'name': 'C.with.dots',
'final': True,
'parallel': [{'name': '1', 'children': ['a', {"name": "b", "final": True}],
'initial': 'a',
'transitions': [['go', 'a', 'b']]},
{'name': '2', 'children': ['a', {"name": "b", "final": True}],
'initial': 'a',
'transitions': [['go', 'a', 'b']]}]}]
transitions = [["start", 'C.with.dots', 'A state with Spaces'], ["", "A state with Spaces", "B-with-dashes"], ["", "B-with-dashes", "C.with.dots"]]
# remove default and parallel styles
# they will be set according to the chosen mermaid theme
del HierarchicalGraphMachine.style_attributes["node"]["default"]
del HierarchicalGraphMachine.style_attributes["node"]["parallel"]
m = HierarchicalGraphMachine(states=states, transitions=transitions, initial="C.with.dots", show_conditions=True,
title="Mermaid", graph_engine="mermaid", auto_transitions=False)
m.start()
print(m.get_graph().draw(None))
Output
---
Mermaid
---
stateDiagram-v2
direction LR
classDef s_inactive fill:white,color:black
classDef s_active color:red,fill:darksalmon
classDef s_previous color:blue,fill:azure
state "A state with Spaces" as A___state___with___Spaces
state "B-with-dashes" as B___with___dashes
state "C.with.dots" as C___with___dots
C___with___dots --> [*]
state C___with___dots {
state "1" as C___with___dots_1
state C___with___dots_1 {
[*] --> C___with___dots_1_a
state "a" as C___with___dots_1_a
state "b" as C___with___dots_1_b
C___with___dots_1_b --> [*]
}
--
state "2" as C___with___dots_2
state C___with___dots_2 {
[*] --> C___with___dots_2_a
state "a" as C___with___dots_2_a
state "b" as C___with___dots_2_b
C___with___dots_2_b --> [*]
}
}
class B___with___dashes s_previous
class C___with___dots_1_a, C___with___dots_2_a s_active
class C___with___dots_2_b, C___with___dots, A___state___with___Spaces, C___with___dots_1_b s_default
class C___with___dots_2, C___with___dots_1 s_parallel
C___with___dots --> A___state___with___Spaces: start
A___state___with___Spaces --> B___with___dashes
B___with___dashes --> C___with___dots
C___with___dots_1 --> C___with___dots_1_a
C___with___dots_2 --> C___with___dots_2_a
C___with___dots_1_a --> C___with___dots_1_b: go
C___with___dots_2_a --> C___with___dots_2_b: go
[*] --> C___with___dots