-
Notifications
You must be signed in to change notification settings - Fork 482
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Elk: use ports for columns in the sql table shape #1429
Comments
I think we could add ports for each columns with foreign key or primary key constraints |
yeah 100%, should be doable in ELK. (related: #630 (comment)) |
I got it somewhat working. It is not perfect and works differently than TALA, since all connections leave from the right side and enter on the left side. There is a way to make ELK choose on which side a port should be placed, but it only does it to reduce number of crossings, it doesn't care about connection length or aesthetics. And I don't know if it would even work, since I can't figure out how to set correct Y coordinate for ports when Would you be interested in a PR if I can make it work reliably? |
@landmaj What's the behavior when you connect sql table row to non-sql table thing? Or sql table row to just sql table. I think the leaving and entering on consistent sides isn't entirely a negative to everyone, so I wouldn't say that's a blocker. A PR would be welcome! ❤️ |
For some reason when you connect sql table row to sql table, the arrow goes to the upper left corner. I have no idea why but I should be able to fix it. Connecting sql table row to non-sql table thing works just fine, no issues there. I found another issue - there is a piece of code in And as you can see I figured out how to automatically choose left/right side. Thought I'm still not sure if implementing this feature, fixed sides or not, is actually worth it. The diagrams end up being much more spread out. Here you can see an example with all the bugs mentioned above: |
I think that's right, the code doesn't account for merges. That looks good! I think even if the routes are a little messier, it's entirely in the user's hands whether they want to activate it by specifying ports when declaring connections (assuming the "going to top left" bug gets fixed). ELK options are a bit confusing and at times I've just trial-and-error'd combinations until one worked. The maintainer is pretty active on their chat though (glitter) and Github issues, which I've asked a few times. |
OK, thanks for feedback. I will get back to work but it may take some time, since I have a real work too. 😆 I will be back with a fully working implementation next weekend, I hope. |
Yup understand, thank you! |
Re laddersYeah perfect. Re Object to sql tableWhy all at the top vs defining ports e.g. every X pixels around the borders of the table? Re self loopI think this would be easier to do than the rest, since self loops are more manual, but can definitely be deferred to a followup issue. Re connection blendingThis is something that your original implementation of keeping incoming connections to one side and outgoing connections to another side would've helped with. I guess not in the case of loops since they're manual, but ideally incoming and outgoing don't share ports. Agreed it's okay to defer though. Getting the bare minimum working and deferring edge cases to followup issues is 👍 . Thanks for the thoroughness in considering all those! |
I have a version I think I'm happy with. Let me know I you like it and I will add tests and create PR. If connections leaving from rows have meaning, defining ports every X pixels around the border for table connections would be misleading. I settled on the following settings:
For The end result looks good IMO. primary: {
shape: sql_table
id: int {constraint: primary_key}
primary_id: int {constraint: foreign_key}
column: string
}
primary.primary_id -> primary.id
obj -> primary
secondary: {
shape: sql_table
id: int {constraint: primary_key}
primary_id: int {constraint: foreign_key}
column: string
}
secondary.primary_id -> primary.id
secondary -> obj All table and column names are the same because I forgot to uncomment code which censored names from a real db (which I will show later). DownUpRightLeft |
One connection is misaligned if the direction is left or right. I have no idea why, I just noticed it. I also tested it on a diagram from #1668. It looks messy but the diagram is insane. |
Wow, nice work!
Right, agreed. Note to self to recommend direction: right/left for ERDs that utilize this in ELK. i think the misalignments just come from hacks we do for padding on labels and containers. @gavin-ts can speak to this more. I wonder if the code made the red connection first, gave it the first available port (which goes clockwise), and then defined the green one next, leading to the crossover. In which case, a post-processing step of swapping ports to reduce crossings would be helpful.
Yes please! |
It should work better now, before it skipped all row connections, even if they never merged anywhere. It now checks if "corner" point is shared with any other route, so even long, merging edges should be able to benefit from ladder removal. I also fixed misaligned connections. Instead of checking if end point is still attached to a node, for row connections it checks if new Y coordinate is within 1/3 row height from the row center. This is diagam from #1668 rendered using code from just opened PR. Some connections could look better but it's still better than without any straightening at all. Here is a version with all straightening logic disabled. The direction is changed because I apparently changed it yesterday and didn't notice before making a screenshot. The edges are identical, just mirrored. And here is my DB. Topmost connection is now properly connected. |
The only issue left I can think of is when you specify diffrent arrowheads for multiple connections to a single row. Here is an example: direction: right
a: {
shape: sql_table
id: int { constraint: primary_key }
}
b: {
shape: sql_table
id: int { constraint: primary_key }
a_1: int { constraint: foreign_key }
a_2: int { constraint: foreign_key }
}
b.a_1 -> a.id: {
target-arrowhead.shape: cf-many
}
b.a_2 -> a.id They are overlaid on each other. But I don't think there is any way to make it work. |
BTW this issue was a fun challenge but I think you should reconsider |
At the moment for the sql_table shape only TALA layout engine render connections to the exact columns.
But I think we could implement it for the ELK via "ports"
References:
The text was updated successfully, but these errors were encountered: