Fork me on GitHub

Hey I'm coming back to membrane to draw some visuals after not using it for a bit. I'm a little rusty so mainly asking this to see if I'm missing something obvious. I'm using skija as the drawing platform. I have this code:

(ui/with-style :membrane.ui/style-stroke
      (apply ui/horizontal-layout
        (for [[colnum row->v]
              {4 {1 "id0", 2 "id1", 3 "id2"},
               5 {1 "id3", 2 "id4", 3 "id5", 4 "id6"},
               6 {1 "id7", 2 "id8", 3 "id9", 4 "id10"},
               7 {1 "id11", 2 "id12", 3 "id13"},
               8 {1 "id14"}}]
          (apply ui/vertical-layout
            (for [[peer v] row->v]
              (ui/padding 20
                (let [rect (ui/rectangle 50 50)
                      label (ui/center (ui/label v) (ui/bounds rect) )]
                  [rect label])))))))
Which in the attached image. Is there a way in membrane to draw a line from one of these rectangles to another one? That is, if I can keep a reference to all the rect records, is there a way to get the absolute location of any two of them given a common parent? Is the only obvious way to do this (without re-implementing the layout engine) by pre-calculating coordinates manually and not using the horizontal/vertical layout features?


There's more than one way to do it.


I think the way I would do it is traverse the created views to get a mapping of rect coordinates that you could use. horizontal and vertical layout are really just measuring and stacking items. It seems like you're working with a fairly regular grid, so it wouldn't be unreasonable to write a few helper functions to do the layout within the grid.


I'll write some example code. One sec.


Awesome thanks!


ok, here's quick sketch. It's a little longer than I'd like, but hopefully most of the uninteresting parts can be hidden away in a util.clj or similar. This solution uses zippers. I can update the example with something else, but zippers do a really great job of fulfilling the OO equivalent parent/back references. The other thing to note is the introduction of IContentOffset . ui/bounds and ui/origin conflate hitboxes, view extents, and probably a few other things. This is a known problem and something I'd like to fix in membrane, but I'm also trying to avoid partial fixes until I get a chance to think things through a bit more (or reference someone else who has thought it through).


I think @U63D7UXJB has also been working on diagramming and maybe has some tips.


I've also done some basic diagramming. It would be nice to investigate building a standalone library similar to mermaid.


Awesome thanks for all that! Really appreciate it


If the layout is grid based, I might also explicitly model that.


It's easy to create a protocol which you use to lay out elements eg top-left bottom-right, also easy to write your own eg horizontal-layout

👍 1

What would be more involved/interesting might be changing how events get dispatched based on capture but it's not super necessary as they just get passed along


It's tricky because it seems like working at a higher level like this (without pixel coords, or possibly any coords, but as you say, explicit nominal coords might be worth it too) is desirable when possible, but it takes a bit of effort to get there too, it's sort of unclear before implementing a couple options which will be the nicest to actually use

👍 1

I think because html DOM is such a cluster fuck people might assume rolling your own here is harder than it is


I should keep a list of missing utilities somewhere so that they can either be added to membrane or packaged in helper libraries.


or even just a list of utilities people would like to see.

👍 1

I always hit this pattern of problem where I want to draw say a graph, look up some libraries, find one that looks nice, say (i tried this first. Well, after graphviz which also wasn't really doing what I want without hacks). But then before the day is over I always hit something that is basically impossible to express cleanly in that framework. Like I wanted to add labels to the x and y axis here, you can't do that in cytoscape without awkwardly using separate graph items as labels, or shoving the graph in a dom and trying to line things up there. Like it seems like it would be ideal if a "graph" library could just plug into an existing ui/layout engine (like membrane 🙂 ) and it's job is just to draw the lines nicely between things with splines and whatever nice graph features. But instead every visualization/charting/etc library re-implements it's own layout/coordinate stuff in a non-compatible way, and they all have a learning curve, and you always hit limitations (at least I always do)


Yeah I've felt this, if they yielded effects/data it would help but people also want interactions


Added a in github discussions to start keeping track of "missing pieces".

👍 2