在 JgraphX 中旋转边缘标签
Rotate an edge label in 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
?
有什么想法吗?
好吧,我已经弄明白了,它不是很漂亮而且它(还)不适用于正交边,即由水平和垂直线段组成的边。
我让它工作的方法是覆盖一个并为 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;
}
};
}
};
我有一条垂直边,我想相应地旋转边标签。
例如,将 "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
?
有什么想法吗?
好吧,我已经弄明白了,它不是很漂亮而且它(还)不适用于正交边,即由水平和垂直线段组成的边。
我让它工作的方法是覆盖一个并为 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;
}
};
}
};