I wanted to have the benefits of both, where you can define a diagram in a diagram language, but also retain a high degree of control over what the diagram looks like.
I also wanted this to work well for humans and agents.
On the Github link, there's a playground where you can try it out without installation. There's also instructions for a simple npm install and for installing a skill you can use with Claude or other agents.
There's a skill in the repo that you can install using `npx skills` to get started with. I'm sure the integration of Reladraw with agents can be made way better, though. It's just a bit... basic/rudimentary right now!
Instead of generating visuals from text and then back to text, just communicate visually with your agents.
Something like UML provides a certain granularity to be able to code something usefully in pure visual language. Of course there are other visual programming languages that provide more depth and would probably be better suited.
Point remains that a solution based on constantly mapping better two different representations of the same thing won’t be a long term efficient solution.
> Mermaid, Graphviz and D2 let you declare boxes and connections, then determine positions for you. If you have a particular picture in mind, these aren't the right tool.
D2's layout engine TALA [1] actually allows you to provide a lot of manual control. TALA used to be commercial, but is now open source.
In my own testing, TALA tends to produce much better layouts than Mermaid, including the ELK layout algorithm (which is not Mermaid's default; D2 also supports ELK).
TALA supports controlling direction per container, defining which shapes have to be near each other, and so on. I've not played with this yet, though.
For the diagrams I usually want to create, that's still not enough control to create what I envision.
edge parser -> renderer "test edge" from: left to: right
and it wasn't smart enough to make a curved arrow
It gave me some ideas to make routing better, too. For example, maybe you don't want the edge to curve above, but rather below. Or, in more complex examples, maybe you want the edge to curve above one thing and to the right of another.
(will update npm shortly too)
I've tried using svg in my MD files but they get unwieldy quite fast. This is a great idea. My first reaction was - but what's if I need something more exact. But reflecting on it, I've realized that this relative positioning is probably enough.
I like that you're going for one generic syntax instead of many specific ones, like mermaid and Plantuml, but it's as much as a pro as it is a con, it's one reason why these languages evolved in the first place, instead of everyone just using DOT. One possible mitigation would be some sort of reuse mechanism? Some way that generic nodes could be defined once and instantiated many times, so if I wanted to draw something like a sequence diagram, I could define/change my participant lanes just once.
Another issue the "No multi-line statements, no line continuations, no blocks." philosophy. I get *why* you chose it, and has its advantages, but it's a pretty annoying constraint, specially if one wants to have longer node names, or have more detailed description of the node in its label, like listing the responsibilities of a class, for instance. "No blocks" is something that can probably won't make much difference, but line continuations (i.e., some distinction between physical and logical lines) can make or break the user experience, IMHO
The syntax for line breaks is another thing I urge you to reconsider, '/' is waaay to common of a character, and being forced to write long strings in a single line can get *really* annoying. Some sort of multiline string support would really make your existing syntax shine.
The last two suggestions/complaints would complicate your parser a lot, specially since you're writing it manually, so, they are trade offs, but as a user who'd love to have something like this on my toolbelt, not having these features would make me hesitate a lot on investing time in this tool.
That said, it's a nice idea, I'll keep an eye on it =)
And, I'm not wedded to the "no multi-line statements". That's more a philosophy of the super early versions of keeping it simple. I noticed some of the playground examples could already benefit from even simple line continuation. The philosophy there would be, if people don't like line continuation, they don't have to use it, but for those who want it, give them a convenient way to do it. Good point about the forward slash char... so much food for thought. Really appreciate the thoughtful comment.
As a compiler writer I'm pondering if it'd be possible to parametrise to a degree with data-sources or you think that's something better suited to custom script generators (right now, it feels like you want to write a lot of this manually, but the grouping system does lend itself to wildcard expansions from data.
Am I getting that right? Super curious, because that sounds cool.
If so, you could target any number of render backends, keeping the same simple interface for your agent, avoiding the bazillion problems rendering engines face to work well across the ecosystem.
I'll add that to my Reladraw todo list!
I’ve been thinking about something similar to this but D2 wasn’t totally open source until now.
So, if you have a container with children, or multiple nodes off to the right of another, with links between them, adding or resizing one adjusts the rest, without re-specifying positions the way turtle graphics would require.
I've been playing with pikchr quite a bit and it has containers and you can specify links relative to the container. I can picture (pun not intended) your counter-example
My main objection to pikchr is that it is turtle graphics plus coordinate offsets, which to me feels like the wrong tool when I want to say "I have A to the left, and B, C, and D all right of A". I don't want to have to translate that to turtle graphic movements like saying "there's a group, draw B, move down some amount, place C, move down again, place D".
Similarly, if I'm thinking at the level of abstraction of nodes and edges and relative positions, it feels awkward to say something like this in pikchr (where the 0.2 is a guess to fiddle with):
arrow from Web.s down 0.2 then right until even with DB.s then to DB.s
Rather than saying in reladraw: edge web -> db from: bottom to: bottom
I think it's less a matter of "reladraw can do it, but pikchr cannot". It's more like, "both can get to the same destination, but how you get there is a matter of taste and how you express your intent".For example in pikchr:
A: box "A" fit
G: [
down
B: box "B" fit
move 0.1
C: box "C" fit
move 0.1
D: box "D" fit
move 0.1
E: box "E" fit
] with .w at A.e+(0.5,0)
arrow from A to G.B chop
arrow from A to G.C chop
arrow from A to G.D chop
arrow from A to G.E chop
To me, it's not as clear that your intent is that you want several nodes right of A. However, in reladraw, it's clearer to me that the intent is "these things are right of A": node a "A"
node b "B" right of a
node c "C" right of a
node d "D" right of a
node e "E" right of a
edge a -> b
edge a -> c
edge a -> d
edge a -> e
However, that's a subjective taste thing and I could see some people liking the pikchr approach.I think you're right that it's a matter of taste and that the intent is better represented by reladraw.
If I can point some personal downsides of pikchr is that there's no loops and when using macros you can't use parameters to create object labels.
For example, Triangle$1: line...
Just some thoughts in case you're looking for future inspiration for the language
You could take someone's explanation of their architecture, give it to an agent, and ask it to render it as a diagram using Graphviz, Mermaid, Draw.io, etc. The problem is that some of those don't give the agent control over what the diagram looks like (Graphviz, Mermaid) and others are inefficient and fiddly for an agent to manipulate (Draw.io). Reladraw aims to be easy for an agent (or human) to edit (like Mermaid) but have the expressiveness and positioning like you'd be able to achieve with a carefully crafted Draw.io diagram.
The idea with Reladraw is that a human or agent could just state "I want this node to the right of this other one", rather than have a layout engine decide. Hopefully less fiddling for agents!
Opening reladraw/docs/index.html to make a diagram then copy-pasting to save it is a little cumbersome.
2. it would be great to have this as a layouting layer for C4
3. which brings me to a suggestion: i think it would make sense to allow for decoupling the topological parts of the language (arrows, groupings, etc) from the layouting concerns (left of, right of, etc)
To explain the use case: One advantage would be: maintain model (and views) in C4, provide layout on top.
We recently generated a big C4 model of the whole company. Good and informative since you can click through it! But it doesn't look nice and doesn't tell a coherent picture visually.
I'm glad you beat me to this; I think what you made is likely better than what I would have produced.
For tools like IntelliJ, VSCode, Obsidian, they would be easier to get working I think, as they all support plugins/extensions. That way, they'd know what to do when they encounter a fenced-in area starting with ```reladraw.
This is super cool. I love diagrams, charts, etc. and use them a lot. Both privately and for work.
Definitely going to make use of this, I didn't know how much I wanted something like this until right now hahaha.
Examples: https://schemdraw.readthedocs.io/en/stable/gallery/flowchart...
Usage: https://schemdraw.readthedocs.io/en/stable/elements/flow.htm...
Fighting with mermaid is so frustraiting, especially when it comes to normal vs github formatting. This is going to replace several ad-hoc half impls I have laying around
This might not be what you have in mind, but Graphviz has a `rank` which can be used as a coarse way to influence the shape of the diagram. (I'm assuming you had something more sophisticated in mind though)
Probably easier would be if the relative drawing were its own distinct Mermaid diagram type, but then it would be largely a new language anyway.
Another option that appears to work well is to use Deno. I tried on my machine and it worked great. Only downside is the executable size is beefy. Could be about 70-105MB, or roughly 30MB compressed.
I don't know if that still sounds attractive? A 30MB download from Github, and then uncompressed to 100MB, and no other dependencies? (Most of it would be the Deno runtime, with only about 300KB being Reladraw)
Does the resolver do any routing? It doesn't auto-route around obstacles. But, if nodes A, B, and C all have edges going to the left side of D, they share that side and space themselves apart so they don't cross. If the side is too short, they'll bow out to make space for each other, so you don't have to manually fiddle. You can also give routing instructions like "these edges pass between these two nodes on their way to D".
Conflicting statements? Statements that can all hold will all apply. Right of one node and below another is okay. Or, "right of A and B and C" will clear whichever sticks out furthest. If they all can't hold, you'll get an error naming the clashing statements (e.g., something both left and right of A). Nothing silently wins.
Fantastic! Never change this.
People will complain. These people also prefer type unsafe languages. Hold fast.
But, I could see the other extreme where if you said "I want an edge going from the left side of A to the right side of B", you wouldn't want the tool to say "well, you didn't specify if I should go above A or below A, so I refuse to do anything". That could be super annoying. A sensible default that you can override would probably be more ergonomic there.
Is that sorta the way you'd think about it too? Or would you be more in favor of greater permissiveness, where the tool prefers warning even in contradictory scenarios?
For example, if you ask for edges to pass "between C and D", but those two nodes sit diagonally, the gap you are asking for might be the vertical channel or horizontal channel between them. So instead of guessing for you, it will tell you of the ambiguity and let you spell out what you want.
Will def be adding this to my list of diagramming tools the agent can use!