cdelker / schemdraw

MIT License
103 stars 20 forks source link

Feature Request: Ability to embed an element in another element #12

Closed TheCleric closed 8 months ago

TheCleric commented 1 year ago

I am currently using schemdraw to diagram some dynamic workflows using mostly schemdraw.flow. One thing I'm finding I'm needing though is the concept of embedding elements within each other. By that I mean if there is an overall block for a set of elements, then have the sub-elements within that. So for example I'm rendering this now (where Package is a parent of Package\Schools and Package\Schools is a parent of the other boxes):

image

What would be preferable would be something like:

image

I think there are some ways to do this manually by rendering the children first, and then assign a width, height, and zorder to the parent, but this feels hacky in terms of the chaining that schemdraw seems to use.

A possible method from this would be adding a .inner() and .outer() to the element (like you can do .up(), .down(), etc.) to signal that the next element should be placed within that element via .inner() and to break out of this by adding .outer(). These could also be chained so .up().inner() would start drawing at the inside top, and .outer().down() would begin drawing outside the container going down.

cdelker commented 10 months ago

A nested context manager may be a good way to do this. Here's a mock-up I started:

with schemdraw.Drawing() as d:
    d += flow.Start().label('Start')
    d += flow.Arrow().down()
    with d.container() as c:
        c += flow.Box().label('Step 1').drop('E')
        c += flow.Arrow().right()
        c += flow.Box().label('Step 2')
        c.label('Subprocess', loc='N', halign='center', valign='top')

download

cdelker commented 8 months ago

Container element, as described above, was added in version 0.18.