1

I have an edge which is vertical and I want to rotate the edge-label accordingly.

For example replace the "helloworld.java" drawing part with:

try
{
    Object v1 = graph.insertVertex(parent, "1", "TopLeft",
        20, 20, 80, 80);
    Object v3 = graph.insertVertex(parent, "2", "BottomLeft",
        20, 240, 80, 80);
    Object e1 = graph.insertEdge(parent, null, "edgelabel", 
        v1, v3, "dashed=true;endArrow=none;rotation=0");
}

Setting rotation=90 rotates the edge but not the label. I found mxCurveLabelShape, but I do not understand how to use it. I tried somewhat, but the edge-mxCell does not contain a mxCurve. I tried:

 List<mxPoint> pl = ((mxCell)e1).getGeometry().getPoints();
 mxCellState ecs1 = new mxCellState(graph.getView(),e1,null);
 mxCurveLabelShape cls = new mxCurveLabelShape(ecs1,(mxCurve)pl);

which obviously cannot work since the edge mxCell also does not contain non-empty mxPoints. Could I use the locations where the edge connects to its ends? Is there a way to address only the label and use rotation for that?

Any ideas?

Nieke Aerts
  • 209
  • 2
  • 11

1 Answers1

1

OK, I have figured it out, it's not pretty and it does not (yet) work for orthogonal edges, i.e., edges that consist of horizontal and vertical segments.

The way I can make it work is by overwriting one and introducing one function for mxGraphComponent. Namely, the drawLabel function now checks whether the label comes from an edge and if so it selects a different createTemporaryGraphics function. In the latter the box of the edge as well as the label is known and the rotation is computed given the edge-box. There is a boolean passed along (quadrant) which tells if the edge is between NorthEast and SouthWest of the rectangle (quadrant = true), or between NorthWest and SouthEast (quadrant = false). This is currently not optimal in the sense of location (i.e., vertical labels might end on top of the edge). But I leave the tweaking for whoever wants to use this ;)

Here we go: (place this wherever you initiate the graphComponent)

mxGraphComponent graphComponent = new mxGraphComponent(graph){
public mxInteractiveCanvas createCanvas()
    {
        return new mxInteractiveCanvas(){
            @Override
            public Object drawLabel(String text, mxCellState state, boolean html)
            {
                Map<String, Object> style = state.getStyle();
                mxIShape shapeL = getShape(style);
                mxITextShape shape = getTextShape(style, html);
                if (g != null && shape != null && drawLabels && text != null
                        && text.length() > 0)
                {
                    // Creates a temporary graphics instance for drawing this shape
                    float opacity = mxUtils.getFloat(style,
                            mxConstants.STYLE_TEXT_OPACITY, 100);
                    Graphics2D previousGraphics = g;
                    if(((mxCell) state.getCell()).isVertex()){
                        g = createTemporaryGraphics(style, opacity, null);                                  
                    }else{
                        //quadrant will be true if the edge is NE or SW
                        Object target = ((mxCell) state.getCell()).getTarget();
                        Object source = ((mxCell) state.getCell()).getSource();
                        boolean quadrant = false;
                        if(((mxCell)target).getGeometry().getCenterX()<((mxCell)source).getGeometry().getCenterX()){
                            if(((mxCell)target).getGeometry().getCenterY()>((mxCell)source).getGeometry().getCenterY()){
                                quadrant =  true;
                            }
                        }
                        if(((mxCell)target).getGeometry().getCenterX()>((mxCell)source).getGeometry().getCenterX()){
                            if(((mxCell)target).getGeometry().getCenterY()<((mxCell)source).getGeometry().getCenterY()){
                                quadrant =  true;
                            }
                        }
                        g = createTemporaryGraphics(style, opacity, state, state.getLabelBounds(),quadrant);
                    }

                    // Draws the label background and border
                    Color bg = mxUtils.getColor(style,
                            mxConstants.STYLE_LABEL_BACKGROUNDCOLOR);
                    Color border = mxUtils.getColor(style,
                            mxConstants.STYLE_LABEL_BORDERCOLOR);
                    paintRectangle(state.getLabelBounds().getRectangle(), bg, border);

                    // Paints the label and restores the graphics object
                    shape.paintShape(this, text, state, style);
                    g.dispose();
                    g = previousGraphics;
                }

                return shape;
            }
            public Graphics2D createTemporaryGraphics(Map<String, Object> style,
                    float opacity, mxRectangle bounds, mxRectangle labelbounds, boolean quad)
            {
                Graphics2D temporaryGraphics = (Graphics2D) g.create();

                // Applies the default translate
                temporaryGraphics.translate(translate.x, translate.y);

                // setup the rotation for the label
                double angle = java.lang.Math.atan(bounds.getHeight()/bounds.getWidth());
                double rotation = Math.toDegrees(angle);
                if(quad){
                    rotation = - rotation;
                }
                //get the translation needed
                double diff = labelbounds.getHeight()*(1-Math.cos(angle));
                double plusy = diff * Math.sin(angle);
                double plusx = diff * Math.cos(angle);
                // Applies the rotation and translation on the graphics object
                if (bounds != null)
                {
                    if (rotation != 0)
                    {
                        temporaryGraphics.rotate(Math.toRadians(rotation),
                                labelbounds.getCenterX(), labelbounds.getCenterY());
                        temporaryGraphics.translate(
                                - plusx, plusy);
                    }
                }

                // Applies the opacity to the graphics object
                if (opacity != 100)
                {
                    temporaryGraphics.setComposite(AlphaComposite.getInstance(
                            AlphaComposite.SRC_OVER, opacity / 100));
                }

                return temporaryGraphics;
            }
        };
    }

};
Nieke Aerts
  • 209
  • 2
  • 11