constant near keys should be able to be set on containers
as long as nothing within is connected to anything outside
direction: right
x -> y: {
style.stroke: green
}
y -> z: {
style.stroke: red
}
legend: {
# This is the TODO
near: bottom-center
color1: foo {
shape: text
style.font-color: green
}
color2: bar {
shape: text
style.font-color: red
}
}
@donglixiaoche if you want to try a hard one!
@alixander yep,a hard one,exactly what I want
@donglixiaoche
so, for context, you can set near to constant values on individual shapes. it's implemented here: https://github.com/terrastruct/d2/pull/525
but people commonly want to make a legend, which is a container of stuff, and put it in the top-center.
setting constant nears works roughly like:
- identify which objects are constant nears
- remove them before the main layout engine runs
- run main layout engine
- add them back in to the appropriate spot
for containers, i think you'll have to
- validate in the d2compiler that nothing in the container or descendant of container is connected to anything outside, (because if it is, it has to run in the main layout engine)
- remove that container and all descendants of that container, including connections between children of that container
- add all those things back in after main layout engine runs
@alixander just so you know, i'm still working on this issue...
as you mentioned, for shapes with near keyword, before main layout, i need to remove that container and all descendants of that container. but if having descendants is allowed for container with near keyword, these descandants also need to be layouted, which can't be done if we remove them from the graph. so i was thinking reolve this problem by contrusting a new graph, and then run another main layout? am i correct? or do you have any ideas?
@donglixiaoche oh that's a good point, i didn't think about that.
- It looks like the core layout is coupled with sequence diagram layouts. that should probably be separated: https://github.com/terrastruct/d2/blob/7ba463c690d5771d42fdf808c1c33adb3b0d35ad/d2lib/d2.go#L73
- The descendants would also need to undergo layout, but they themselves might also have
nearcontainers, or sequence diagrams. So it should be recursive. Which means this whole portion of layout code should probably be separated so that it can be run recursively: https://github.com/terrastruct/d2/blob/7ba463c690d5771d42fdf808c1c33adb3b0d35ad/d2lib/d2.go#L66-L81 . By doing this, perhaps (1) won't be necessary.
contrusting a new graph, and then run another main layout?
yes, each constant-near-container would have to be its own graph. so you remove all the constant-near-containers, run layout on all of them (recursively), then run on the main graph, then re-insert all the objects and edges back into the main graph.
quite complicated, let me know when you run into anything at all, always available to help
@alixander i didn't think about the recursive way cause previously only root level shape could have a near attribute, ok then, let me think about it
@donglixiaoche yeah wait actually that is the case right now. sorry got confused with this issue: https://github.com/terrastruct/d2/issues/841
in that case, no need to handle non-root nears. they're still illegal for now
Naively, I would expect this to work, i.e. that containers would be laid out hierarchically, from the inside out (and that any connections going out of an inner container to somewhere adapt to that). But specifically I would expect to be able to position a complex object in a corner or an a border of a container.