Повернуть метку ребра в JgraphX

У меня есть край, который является вертикальным, и я хочу соответствующим образом повернуть метку края.

Например, замените часть рисунка «helloworld.java» на:

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");
}

Параметр rotation=90 вращает край, но не метку. Я нашел mxCurveLabelShape, но не понимаю, как им пользоваться. Я несколько раз пробовал, но в edge-mxCell нет mxCurve. Я старался:

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

что, очевидно, не может работать, так как ребро mxCell также не содержит непустых mxPoints. Могу ли я использовать места, где ребро соединяется с его концами? Есть ли способ обратиться только к метке и использовать для этого rotation?

Любые идеи?


person Nieke Aerts    schedule 10.03.2016    source источник


Ответы (1)


Хорошо, я разобрался, это некрасиво и (пока) не работает для ортогональных ребер, то есть ребер, состоящих из горизонтальных и вертикальных сегментов.

Я могу заставить это работать, перезаписав одну и введя одну функцию для mxGraphComponent. А именно, функция drawLabel теперь проверяет, исходит ли метка от края, и если да, то выбирает другую функцию createTemporaryGraphics. В последнем блок ребра, а также метка известны, и поворот вычисляется с учетом блока края. Вдоль (quadrant) передается логическое значение, которое сообщает, находится ли край между северо-востоком и юго-западом прямоугольника (quadrant = true) или между северо-западом и юго-востоком (quadrant = false). В настоящее время это не оптимально с точки зрения расположения (т. е. вертикальные метки могут заканчиваться сверху края). Но я оставляю настройку для тех, кто хочет использовать это;)

Итак, начнем: (поместите это везде, где вы инициируете 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;
            }
        };
    }

};
person Nieke Aerts    schedule 23.03.2016