0

Is it possible to create bidirectional arrows in JUNG using FRLayout? Ideally, is it possible to have an algorithm that uses these arrows (end-points are arrowheads at both ends) for cases where both a->b and b<-a?

I think it might be related to

 Renderer.Edge<String, String> edgeRenderer = 
        vv.getRenderer().getEdgeRenderer();

but can't see how to get the shapes of the arrowheads

anarche
  • 536
  • 4
  • 19

2 Answers2

1

If you render the edges as straight lines, then antiparallel edges (a->b and b->a) will look like what you want.

If you look at PluggableRendererDemo you'll see examples of how to change the edge shape:

vv.getRenderContext().setEdgeShapeTransformer(EdgeShape.line(graph));

If you actually want to render two separate edges as a single edge, that's going to be more involved; essentially you'd need to hack (or subclass) BasicEdgeRenderer so that it checks for antiparallel edges and treats them differently. To draw the arrows on both ends of an edge, take a look at the code in that class for rendering undirected edges (which can optionally have arrows on both ends).

Joshua O'Madadhain
  • 2,704
  • 1
  • 14
  • 18
  • The first recommendation worked - it will be interesting to explore the second, I'll try that for more crowded graphs where straight lines might not be ideal – anarche Apr 30 '18 at 13:30
1

You could do something like this hack to make (in this case) Curved edges overlay each other:

        vv.getRenderContext().setEdgeShapeTransformer(new Function<String, Shape> () {
            @Override
            public Shape apply(String edge) {
                Pair<String> endpoints = graph.getEndpoints(edge);
                float controlY = 60.f;
                 // use some hacked 'ordering' of the endpoint nodes so that the curve for A->B is on the same side as the curve from B->A
                if (endpoints.getFirst().toString().compareTo(endpoints.getSecond().toString()) < 0) {
                    controlY *= -1;
                }
                return new QuadCurve2D.Float(0.0f, 0.0f, 0.5f, controlY, 1.0f, 0.0f);
            }
        });