Create bidirectional arrows in JUNG

89 Views Asked by At

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

2

There are 2 best solutions below

0
AudioBubble On BEST ANSWER

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);
            }
        });
1
Joshua O'Madadhain On

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).