I'm attempting to create links in JointJS that are smooth curves but also route around obstacles. The default implementation allows us to choose routers and connectors. Routers let you define the logic to avoid obstacles and basically return a set of points to hit on the connector. The connector takes that set of points and converts it into an svg path.
Using no router or the "orthogonal" router with the "smooth" connector produces a result like this
The manhattan and metro routers have logic to avoid obstacles. You can use them with the default connector or a rounded one (default but with rounded corners) to get something like this:
For comparison, the metro router without the smooth connector looks like
Combining the smooth connector with one of those routers works great, except that you tend to get strange artifacts at the ends (and unnecessarily complex curves):
I believe this issue is that the smooth connector is just calculating bezier curves that go through the points from the router.
I thought that perhaps I could solve the problem by calculating the curves (using g.Curve.throughPoint()
which created this last picture and then adjusting the very first and very last control points to be inline with the start and end points horizontally and vertically, respectively (in this case). That made far less difference than I hoped (in particular at the start):
This is the svg path of that last one:
M 150 110 C 155.78724378793083 110 161.57448757586167 98.34306652925683 170 110 C 178.42551242413833 121.65693347074317 189.48929348448416 150.79926714760109 220 160 C 250.51070651551584 169.20073285239891 300.46833848620173 158.45986488033893 320 160 C 339.53166151379827 161.54013511966107 328.6373525707088 175.36127333104315 340 180 C 351.3626474292912 184.63872666895685 384.982251230963 180.09504179548838 400 180 C 415.017748769037 179.90495820451162 411.43364250543914 184.2585594870033 410 190 C 408.56635749456086 195.7414405129967 410 202.87072025649834 410 210
I think the issue is the control points are so close together that it while it is technically perpendicular, it comes in very steep so you can only see it if you zoom way in.
Fundamentally, I think the problem to all the issues is that we don't really want to go through the same points as the metro router. By definition, that's going to make the curve more 'wiggly' than needed.
So my question is - is there a way to programmatically "round" the curves to look more like the one at the top, while ensuring they avoid obstacles? I suspect this will require both new router and connector logic to ensure the curve works for any arbitrary layout, though perhaps that's not true.
Something more like this: