
# states.py
# Andrew Davison, ad@coe.psu.ac.th, May 2025

import graphviz

TEMP_FNM = 'temp_graph'

dg = graphviz.Digraph(format='png')
dg.attr(label='Nested Statechart',
        compound='true')  # allow edges to/from clusters

# a cluster c with a nested cluster p
with dg.subgraph(name='cluster_op') as c:
  c.attr(label='Operational', style='rounded')

  c.node('standby', 'Standby')
  c.node('continuous', 'Continuous')

  with c.subgraph(name='cluster_pul') as p:
    p.attr(label='Pulsing', style='rounded')
    p.node('pOn', 'Pump On')
    p.node('pOff', 'Pump Off', penwidth='2')

    p.edge('pOff', 'pOn')
    p.edge('pOn', 'pOff')
    # p.node('pulsingStart', '', shape='point')  
    p.node('pulsingStart', '', shape='circle', 
            width='0.1', height='0.1', style='filled',
            fillcolor='black', fixedsize='true')
       # a bigger black point; looks better
    p.edge('pulsingStart', 'pOff')
  # -------------
  
  # edges to/from cluster p
  c.edge('standby', 'pulsingStart', 
                lhead='cluster_pul', style='dashed')
  c.edge('pOff', 'standby', 
                ltail='cluster_pul', style='dashed')

  c.edge('standby', 'continuous')
  c.edge('continuous', 'standby')

# entry arc into cluster c, but no node
dg.node('start', '', shape='point', style='invis')
dg.edge('start', 'standby')  # start point to standby


dg.render(filename=TEMP_FNM, view=True, cleanup=True)

