package com.mxgraph.layout;
import java.awt.Rectangle;
import java.util.ArrayList;
import java.util.List;
import com.mxgraph.model.mxGeometry;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.util.mxPoint;
import com.mxgraph.view.mxCellState;
import com.mxgraph.view.mxGraph;
import com.mxgraph.view.mxGraphView;
public class mxEdgeLabelLayout extends mxGraphLayout
{
/**
* Constructs a new stack layout layout for the specified graph,
* spacing, orientation and offset.
*/
public mxEdgeLabelLayout(mxGraph graph)
{
super(graph);
}
/*
* (non-Javadoc)
* @see com.mxgraph.layout.mxIGraphLayout#execute(java.lang.Object)
*/
public void execute(Object parent)
{
mxGraphView view = graph.getView();
mxIGraphModel model = graph.getModel();
// Gets all vertices and edges inside the parent
List<Object> edges = new ArrayList<Object>();
List<Object> vertices = new ArrayList<Object>();
int childCount = model.getChildCount(parent);
for (int i = 0; i < childCount; i++)
{
Object cell = model.getChildAt(parent, i);
mxCellState state = view.getState(cell);
if (state != null)
{
if (!isVertexIgnored(cell))
{
vertices.add(state);
}
else if (!isEdgeIgnored(cell))
{
edges.add(state);
}
}
}
placeLabels(vertices.toArray(), edges.toArray());
}
/**
*
*/
protected void placeLabels(Object[] v, Object[] e)
{
mxIGraphModel model = graph.getModel();
// Moves the vertices to build a circle. Makes sure the
// radius is large enough for the vertices to not
// overlap
model.beginUpdate();
try
{
for (int i = 0; i < e.length; i++)
{
mxCellState edge = (mxCellState) e[i];
if (edge != null && edge.getLabelBounds() != null)
{
for (int j = 0; j < v.length; j++)
{
mxCellState vertex = (mxCellState) v[j];
if (vertex != null)
{
avoid(edge, vertex);
}
}
}
}
}
finally
{
model.endUpdate();
}
}
/**
*
*/
protected void avoid(mxCellState edge, mxCellState vertex)
{
mxIGraphModel model = graph.getModel();
Rectangle labRect = edge.getLabelBounds().getRectangle();
Rectangle vRect = vertex.getRectangle();
if (labRect.intersects(vRect))
{
int dy1 = -labRect.y - labRect.height + vRect.y;
int dy2 = -labRect.y + vRect.y + vRect.height;
int dy = (Math.abs(dy1) < Math.abs(dy2)) ? dy1 : dy2;
int dx1 = -labRect.x - labRect.width + vRect.x;
int dx2 = -labRect.x + vRect.x + vRect.width;
int dx = (Math.abs(dx1) < Math.abs(dx2)) ? dx1 : dx2;
if (Math.abs(dx) < Math.abs(dy))
{
dy = 0;
}
else
{
dx = 0;
}
mxGeometry g = model.getGeometry(edge.getCell());
if (g != null)
{
g = (mxGeometry) g.clone();
if (g.getOffset() != null)
{
g.getOffset().setX(g.getOffset().getX() + dx);
g.getOffset().setY(g.getOffset().getY() + dy);
}
else
{
g.setOffset(new mxPoint(dx, dy));
}
model.setGeometry(edge.getCell(), g);
}
}
}
}