Deep-Symmetry / bytefield-svg

Node module that generates byte field diagrams in SVG format
Eclipse Public License 2.0
126 stars 20 forks source link

Long boxes #17

Closed lorrden closed 4 years ago

lorrden commented 4 years ago

When working with autogenerated diagrams of network packets (bit level), we sometimes end up with fields crossing multiple lines and being in general unhelpfully unaligned.

Due to the unalignedness, it is hard to define a row length that will fit all values, in some cases this causes boxes to spill over into the next row, which generates an exception.

For example, a protocol has a double, aligned at a byte boundary, we then use draw-box with a span of 8.

Can we get a function like: draw-long-box or something like that that handles overflow into next line automatically? This of-course raises the issue as to what to draw in the lines (e.g. repeating the label, continuation symbol of some sort, label at the longest box sequence (i.e. the second row if the sequence is 1, 7)).

brunchboy commented 4 years ago

This seems more specialized than will admit of a general purpose solution. I’d encourage you to write something that works for you, and if you feel it is general enough after working with it for a while, you could submit it as a pull request.

What I have done in the few situations where my diagrams needed something like this was to draw boxes individually on the rows that needed them, controlling the borders appropriately to make it look the way I want.

My goal here was to make all diagrams possible, and really common cases easy.

brunchboy commented 4 years ago

A good starting point for inspiration might be the code that implements draw-related-boxes which does similar kinds of multi-line border management: https://github.com/Deep-Symmetry/bytefield-svg/blob/1023e91be2702b169ad830540476f5107364d6d2/src/org/deepsymmetry/bytefield/core.cljs#L397-L434

brunchboy commented 4 years ago

Here’s an example page with a diagram where I had to create long boxes: https://djl-analysis.deepsymmetry.org/djl-analysis/beats.html

My pages use the shared function draw-packet-header to draw this, and it’s an example of one of the approaches I took. There were variations in different include files for different packet types; each place which required thought about where to draw the label, and so on. https://github.com/Deep-Symmetry/dysentery/blob/38d961e6e54ec4dfdfee6475d57fd10e64fc4b56/doc/modules/ROOT/examples/status_shared.edn#L12-L21

But this reminds me that I do provide some predefined named attributes to make the border management easier, like :box-above and :box-below.

lorrden commented 4 years ago

Those are very good examples, thanks. I suppose what is missing is a style that only draws its left/right border, that would let us define a long box spanning more than two rows.

brunchboy commented 4 years ago

Good idea. I didn’t run into any of those in my own diagrams that were not also variable-length, so I used draw-gap for them, but I will sure add one as part of the mini release I am working up to.

brunchboy commented 4 years ago

In the mean time you can just set those borders individually by looking at how the predefined attributes are set up, and set up your own predefined attribute if you want.

brunchboy commented 4 years ago

@lorrden in case you haven’t found them yet, here’s where the predefined attributes you are using are defined: https://github.com/Deep-Symmetry/bytefield-svg/blob/9d4a7cf681ebb4e22a8cc7f8268011bf3d9ef555/src/org/deepsymmetry/bytefield/core.cljs#L709-L713

My biggest problem is that I can’t think of a good keyword to use to name one that is open on both the top on the bottom. :box-middle would be ambiguous with :box-first and :box-last in the :box-related group, unfortunately. Also, it’s not clear to me that it is worth setting one up as a named attribute, since you can use {:borders #{:left :right}} to draw such a box; that isn’t too much to type.

brunchboy commented 4 years ago

Maybe :box-open-row? Nothing feels completely right.

brunchboy commented 4 years ago

I guess :box-left-right would be the least ambiguous. But again, that doesn’t save many characters compared to just spelling out the borders explicitly, as {:borders #{:left :right}}, and I worry that never doing that gets people stuck thinking they need to use my special predefined attributes to control their borders, rather than realizing they are simply convenience shorthand.

brunchboy commented 4 years ago

As the above commit suggests, I have decided the best way to deal with this is by improving the documentation to make my intentions here more easy to discover. If you look at bottom of the master version of the predefined attributes guide I have added a tip there about how to approach this. Please let me know if you think this is inadequate.

I will hold off on my next release in case you come up with other ideas that merit including in it, since you seem to be actively working on things. 😄

lorrden commented 4 years ago

Everything is possible, I see that now, so docs improvements is all that is needed in the end.

Again, an absolutely awesome tool :)