0

Intro

I'm working on a project, that renders the vertices in a graph in different sizes (according to their relative workload).

Problem

How I expected it to work

This is what happens when I turn off the dynmaic resizing of vertices:

enter image description here

So here everything is correct. The connection-circles are placed just on the border of the cirular shapes.

This result is achieved by the code in Listing 1.

What actually happens on dynamic resizing

Here you can see, that the connection-circles are placed somewhere near the border, but always lack the correct position.

enter image description here

This result is achieved by the code in Listing 2.

Listing 1 - Without resizing

viewer.getRenderContext().setVertexShapeTransformer(vertex -> {
    return vertex.getShape();
});

Listing 2 - With resizing

viewer.getRenderContext().setVertexShapeTransformer(vertex -> {
    double localWorkload = vertex.getLocalWorkload();
    double globalWorkload = graph.getGlobalWorkload();
    double relation = local / global;
    return AffineTransform.getScaledInstance(relation, relation).createTransformedShape(vertex.getShape());
});

Actually I'm lazily precalculating 10 different sizes of the vertex' shape within the vertex. But this code snippet is more clear and achieves the same result (though not as performant).

What I already tried and looked at

This all happens in the edu.uci.ics.jung.visualization.renderers Package.

  • checked the BasicEdgeArrowRenderingSupport class for anything I might utilize to correct this issue
  • checked if it was the `flatness` of the PathIterator in the BasicEdgeArrowRenderingSupport
  • checked if it was the arrowPlacementTollerance parameter

Question

How do I achieve the desired result which is produced by Listing 1 but with dynamically resizing shapes as in Listing 2?

I guess the answer to this question will be resulting in either:

  • There is some essential failure (logically or programatically) I did
  • Or it is a basic problem of the edge arrow rendering support
Jan
  • 2,025
  • 17
  • 27
  • It's difficult. It seems like you *heavily* reconfigured the rendering compared to the "default" settings. Quite a while ago, I digged into the JUNG source code to figure out what they did there, and IIRC, they are actually computing the intersection point of the edge and the vertex shape, but don't remember all influencing factors here. Can you provide a MCVE (I mean, a really small one, like http://stackoverflow.com/a/35301625/3182664 ) that allows toggling between the two behaviors via a compile-time flag? – Marco13 Mar 20 '16 at 12:30
  • Actually this is what JUNG supports. Adding custom Transformers for defining specific shapes (and colors, strokes, etc...). I will create a MCVE next week, will not take much though. It's just about creating a `Graph` in JUNG and adding a method `getWorkLoad()` to the `MyNode` class. After that I will create an instance of the `VisualizationViewer` from JUNG and add the Transformers I described in Listing1 and Listing2. – Jan Mar 20 '16 at 14:03
  • BTW: They do this in JUNG, from what I read in the code: Iiterate on the Edgeshapes' path until the iterators' coordinates point within the destinationvertex shape (name this point *P2*). Afterwards they create a Line2D from the last point of the iteration to *P2*, and pass this line to another Transformer which will find the position on the actual edge... At this phase the `arrowPlacementTolerance` comes into play... So the smaller this value the more acurate should be the result of the arrowhead being exactly on the edge. But this all just works with static sizes and I don't know why. – Jan Mar 20 '16 at 14:09
  • "*this is what JUNG supports*" sure, there's nothing wrong with that (and it is *intended* to be used like that) - but it's hard to figure out where (and why) the computation of the edge end points may be messed up by a particular `Transformer`. It's mainly about isolating the root cause for the undesired behavior. – Marco13 Mar 20 '16 at 15:00
  • Ok Thanks for the obvious suggestion to create a MVCE. I created one and this is working perfectly fine... And I have no clue why it is not working in the application I was talking about... Maybe because I use javafx, maybe because there are several background threads doing a lot of work and something is interfering... Will have to try and error. Anyway the link to the MVCE: https://github.com/JanSurft/MVCE-DynamicResizing – Jan Mar 21 '16 at 09:45
  • If you manage to reproduce the error in a MVCE (or at least, a S(mall)VCE), I can have a look at it. – Marco13 Mar 21 '16 at 12:18

0 Answers0