Comments (11)
I.e. make all edges curvy to the right so bi directional pairs of edges are distinguishable?
Yes, that was my goal.
I am not that sure whether the use of tangets feature will result in the nices looking curves here.
I am not really an expert in any kind of geometry, I'll trust your judgement.
I hope to find some time for a PR soon!
from graphmakie.jl.
I've implement my sketch above in #48 . What do you think?
from graphmakie.jl.
The desired behaviour here is for edges to allways bend in the same direction? I.e. make all edges curvy to the right so bi directional pairs of edges are distinguishable? I was thinking about something like this before, I think it is a good feature to have and a PR is welcome! The relevant code starts around here, where each edge gets associated with a bezier curve.
I am not that sure whether the use of tangets
feature will result in the nices looking curves here. There are some rules on how to draw circle segments using cubic bezier curves. Maybe we could use something like this to calculate the waypoints for the bezier curves for each edge directly.
What would be the right user interface here? Define the radius of the curve? Or maybe the maximum deviation from straight line? The latter might be more general for graphs where the edge length is very inhomogeneous.
from graphmakie.jl.
I tried to figure out the control point positions given distance d to the straight line... the boxed equations might do the trick
from graphmakie.jl.
I need to agree that it is not very convenient drawing the Bezier curves for big networks.
I think a major improvement can be easily made if the tangents
points are given not only as relative to the src
.dst
node positions but also relative to the coordination system defined by a cartesian coordinating system with the x axis being the direct straight edge from src
to dst
. This way only a coordinate transormation needs to be made before drawing the bezier graphs. This should also trigger digraph edges to be symmetrical if same tangents
are given.
from graphmakie.jl.
That's amazing! Thank you!
(And sorry for not having pursued this any further.)
from graphmakie.jl.
I also think it's a nice feature. Allow me to collaborate a little bit more on what I meant.
Right now tangents being passed are treated with a rather counter-intuituve reference system, which for me makes it impossible to directly pass in the correct values.
See the picture attached for an explanation:
Given a bezier point (p1, p2) now, p1 is being treated according to x1-y1
and p2 according to x2-y2
. That being said the reference system is irrelative to the direct edge connecting the two nodes.
I think a rotation could be used to make the reference system of point p1 be x1'-y1'
and from p2 x2'-y2'
, thus dependant on the direct interconnecting edge.
This can lead to much more intuituve plotting. Please have a look to the pluto notebook (shared as a .gz)
eZtangets.jl.html.gz
or as pdf file: eZtangents.pdf
from graphmakie.jl.
when the interconnecting edge is not horizontal or vertical I see that there is some offset, making it not completely symmetrical. It can be seen in the last plot in the notebook
from graphmakie.jl.
Yeah you totally have a point there! For context, I've created the tangents interface to allow for this plot:
For that specific usescase the global coordinate system is the right choice. I'd also argue that the word tangent
implies a global coordinate system since tangents are usually defined in that space. It is also the only option which extends easily to 3D.
However, we totally need a way of specifying this "locally:" the big question is the right kind of interface. I don't want to add 10 different methods for drawing curvy edges, i think this will be confusing.
Distance from straight line: this is implementend in the PR. I think it is the most straight forward interface. There is a "right" distance for the control points such as the resulting spline looks like a circle segment [1], which is probably the best look for this kind of graphs. The use should not care about this. In order to deal with [1] one might add another parameter, distance_space=:data
and distance_space=:pixel
.
I think there is also a need for a more low level interface to place the control points (for example in a rotated coordinate system as you suggested). Do you think it would be beneficial to have this in cartesian coordinates? Another way would be to specify an angle and a distance per control point.
Maybe it would be also sufficient to provide a real low level interface: the user could provide a function f(src, dst, i)->(c1, c2)
which gets the positions of the source and destination vertex of the i-th edge and returns a tuple of two control points, than it would be relatively easy to implement whatever you like.
[1] There is a subtle difference between pixel space and data space here which is not implemented in the PR. I guess thats also the reason why your last example plot looks kinda asymetric. Try with ax.aspect = DataAspect()
.
from graphmakie.jl.
One could even go all in on the f(src, dst, i) -> (c1, c2)
interface. Getting rid of all of the other options and provide prebuild functions such as:
waypoint_edge([p1, p2,...])
simple_curvy_edge(distance; space=[:pixel, :data])
global_tangents(...)
local_tangents(...)
Hm but given that 2/3 of questions regarding GraphMakie are due to the layout interface this kind of interface does not seem to be intuitive for a lot of users.
from graphmakie.jl.
[1] There is a subtle difference between pixel space and data space here which is not implemented in the PR. I guess thats also the reason why your last example plot looks kinda asymetric. Try with ax.aspect = DataAspect().
Yes, Now it looks fully symmetrical. true!
Regarding "local" and "global" perpective, I guess both are kind of local (translated to the src
or dst
node), but the "global" holds on to the same global directions, while the "local" in addition rotates about the dst-src
vector.
I see that in your example the "global" view is needed.
Another way would be to specify an angle and a distance per control point
Actually I think that such a relative polar system would be a more straightforward choice and more easy to configure.
For my use case curve_distance
would suffice, and probably is also the simplest to use. But for drawing more fancy graphs, indeed a lower level "local" or "global" interface is needed. Putting everything as a key-value argument in the graphplot
function, it will bring much unneeded confusion.
I actually see the tangents as part of the more general layout
. And given that the layout
also expects an input function, tangents
could work similarly as you proposed getting a function f(src, dst, i)->(c1, c2)
. Some default functions (or tools like "global" or "local" view) can be given, in the same way that there are default functions for the layout.
from graphmakie.jl.
Related Issues (20)
- curve_distance & curve_distance_usage observable not updating figure
- Precompilation stuck on Julia 1.9 HOT 6
- handle overlapping `nlabels` HOT 6
- node_color and node_marker only accept Symbol HOT 5
- Performant graph plotting and benchmarking HOT 4
- Element-wise `automatic` configuration HOT 1
- Deleting a plot doesn't remove all listeners HOT 2
- Mixing directed and undirected edges HOT 2
- Add padding around graphplot to accommodate node size. HOT 2
- `node_attr` broken using Makie v0.19.11 HOT 1
- Slow start HOT 2
- Setting node size with ilabel
- Improve Reftests HOT 1
- provide convenience function for MetaGraphsNext HOT 7
- KeyError: key :textsize not found when running doc examples HOT 2
- UndefVarError: `mouse_selection` not defined HOT 5
- arrow_shift = :end works poorly with larger edge width HOT 6
- bounding box cuts off nodes HOT 3
- `pick` one `LineSegments` returns odd index HOT 2
- Dynamic Layout + Interaction.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphmakie.jl.