use of cbit.vcell.graph.StructureShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method refreshLayoutChildrenFeatureShape.
public void refreshLayoutChildrenFeatureShape(FeatureShape shape) {
// calculate total height and max width of speciesContext (column1)
int scCount = 0;
List<Shape> childShapeList = shape.getChildren();
for (int i = 0; i < childShapeList.size(); i++) {
Shape child = childShapeList.get(i);
if (child instanceof SpeciesContextShape) {
scCount++;
}
}
// calculate total height and max width of Membranes (column2)
int memCount = 0;
int memHeight = 0;
int memWidth = 0;
for (int i = 0; i < childShapeList.size(); i++) {
Shape child = childShapeList.get(i);
if (child instanceof StructureShape) {
memHeight += child.getSpaceManager().getSize().height;
memWidth = Math.max(memWidth, child.getSpaceManager().getSize().width);
memCount++;
}
}
int centerX = shape.getSpaceManager().getSize().width / 2;
int currentY = shape.getLabelSize().height;
currentY += shape.getLabelSize().height;
int totalSpacingY;
int spacingY;
int extraSpacingY;
int currentX = shape.getSpaceManager().getSize().width / 2 - memWidth / 2;
int spacingX = StructureShape.defaultSpacingX;
// position column2 (membranes)
totalSpacingY = (shape.getSpaceManager().getSize().height - currentY) - memHeight;
if (totalSpacingY < 0) {
LayoutErrorLog.logErrorMessage("unable to fit children within container");
}
spacingY = totalSpacingY / (memCount + 1);
extraSpacingY = totalSpacingY % (memCount + 1);
centerX = currentX + memWidth / 2;
// position children (and label)
int col2Y = currentY + spacingY + extraSpacingY;
for (int i = 0; i < childShapeList.size(); i++) {
Shape child = childShapeList.get(i);
if (child instanceof StructureShape) {
child.getSpaceManager().setRelPos(centerX - child.getSpaceManager().getSize().width / 2, col2Y);
col2Y += child.getSpaceManager().getSize().height + spacingY;
}
}
if (col2Y != shape.getSpaceManager().getSize().height) {
LayoutErrorLog.logErrorMessage("layout for column2 incorrect (" + shape.getLabel() + "), currentY=" + currentY + ", screenSize.height=" + shape.getSpaceManager().getSize().height);
}
if (memCount > 0) {
currentX += spacingX + memWidth;
}
if (scCount > 0) {
// The following code attempts to position SpeciesContextShapes so that their
// ovals and labels do not overlap other structures
// Calculate Mask of valid area where SpeciesContextShape may render
Area currentOval = new Area(new Ellipse2D.Double(shape.getSpaceManager().getRelX(), shape.getSpaceManager().getRelY(), shape.getSpaceManager().getSize().width, shape.getSpaceManager().getSize().height));
for (int i = 0; i < childShapeList.size(); i++) {
Shape child = childShapeList.get(i);
if (child instanceof StructureShape) {
Area childArea = new Area(new Ellipse2D.Double(child.getSpaceManager().getRelX() + shape.getSpaceManager().getRelX(), child.getSpaceManager().getRelY() + shape.getSpaceManager().getRelY(), child.getSpaceManager().getSize().width, child.getSpaceManager().getSize().height));
currentOval.subtract(childArea);
}
}
//
// Position SpeciesContextShapes so they and their labels don't overlap other structures.
// If fail, try a few more times with reduced spacing between SpeciesContextShapes to see
// if we can fit
//
final int TOPOFFSET = 20;
boolean bLayoutFailed = false;
int layoutRetryCount = 0;
final int MAX_LAYOUT_RETRY = 3;
int boxSpacingX = 50;
final int X_RETRY_SPACE_REDUCTION = 10;
int boxSpacingY = 30;
final int Y_RETRY_SPACE_REDUCTION = 5;
final int XEND = currentOval.getBounds().x + currentOval.getBounds().width;
final int YEND = currentOval.getBounds().y + currentOval.getBounds().height;
while (true) {
bLayoutFailed = false;
int xCount = 0;
int boxX = 0;
int boxY = 0;
for (int i = 0; i < childShapeList.size(); i++) {
if (childShapeList.get(i) instanceof SpeciesContextShape) {
SpeciesContextShape child = (SpeciesContextShape) childShapeList.get(i);
final int XSTEP = child.getSpaceManager().getSize().width + boxSpacingX;
final int YSTEP = child.getSpaceManager().getSize().height + boxSpacingY;
while ((layoutRetryCount <= MAX_LAYOUT_RETRY && // If last try, don't check labels for overlap
(// away from structure label
boxY <= TOPOFFSET || !currentOval.contains(// SCS label not overlap other structures
boxX + child.getSmallLabelPos().x + currentOval.getBounds().getX(), boxY + child.getSmallLabelPos().y + currentOval.getBounds().getY() - child.getSmallLabelSize().height, child.getSmallLabelSize().width, child.getSmallLabelSize().height))) || !currentOval.contains(// SCS oval not overlap other structures
boxX + currentOval.getBounds().getX(), boxY + currentOval.getBounds().getY(), SpeciesContextShape.DIAMETER, SpeciesContextShape.DIAMETER)) {
if (boxY < YEND) {
boxY += YSTEP;
} else {
boxY = (xCount % 2 == 0 ? TOPOFFSET : TOPOFFSET + SpeciesContextShape.DIAMETER);
boxX += XSTEP;
xCount += 1;
}
if (boxX > XEND && boxY > YEND) {
bLayoutFailed = true;
break;
}
}
if (!bLayoutFailed) {
child.getSpaceManager().setRelPos(boxX, boxY);
boxY += YSTEP;
} else {
break;
}
}
}
if (bLayoutFailed && layoutRetryCount <= MAX_LAYOUT_RETRY) {
boxSpacingX -= X_RETRY_SPACE_REDUCTION;
boxSpacingY -= Y_RETRY_SPACE_REDUCTION;
layoutRetryCount += 1;
} else {
break;
}
}
}
}
use of cbit.vcell.graph.StructureShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method getPreferedSizeFeatureShape.
public Dimension getPreferedSizeFeatureShape(FeatureShape shape, Graphics2D g) throws GraphModel.NotReadyException {
Font origfont = g.getFont();
g.setFont(shape.getLabelFont(g));
FontMetrics fm = g.getFontMetrics();
shape.setLabelSize(fm.stringWidth(shape.getLabel()), fm.getMaxAscent() + fm.getMaxDescent());
shape.getLabelPos().x = shape.getSpaceManager().getSize().width / 2 - fm.stringWidth(shape.getLabel()) / 2;
shape.getLabelPos().y = 5 + fm.getMaxAscent();
try {
if (shape.countChildren() > 0) {
int structCount = 0;
int childStructureTotalHeight = shape.getLabelSize().height;
int childStructureMaxWidth = shape.getLabelSize().width;
for (Shape child : shape.getChildren()) {
if (child instanceof StructureShape) {
structCount += 1;
Dimension childDim = getPreferedSize(child, g);
childStructureTotalHeight += childDim.height + StructureShape.defaultSpacingY;
childStructureMaxWidth = Math.max(childStructureMaxWidth, childDim.width);
}
}
int scsCount = 0;
// int childSCTotalHeight = 0;
int childSCMaxWidth = 0;
int childSCMaxHeight = 0;
for (Shape child : shape.getChildren()) {
if (child instanceof SpeciesContextShape) {
scsCount += 1;
Dimension childDim = getPreferedSize(child, g);
childSCMaxHeight = Math.max(childSCMaxHeight, childDim.height + ((SpeciesContextShape) child).getSmallLabelSize().height);
childSCMaxWidth = Math.max(childSCMaxWidth, childDim.width);
childSCMaxWidth = Math.max(childSCMaxWidth, ((SpeciesContextShape) child).getSmallLabelSize().width);
}
}
Dimension box = new Dimension();
if (scsCount != 0) {
int squareBoxX = (int) Math.ceil(Math.sqrt(scsCount));
int squareBoxY = squareBoxX - (int) (((squareBoxX * squareBoxX) % scsCount) / (double) squareBoxX);
int width1 = (squareBoxX * (childSCMaxWidth + 0));
// + defaultSpacingX;
int height1 = (squareBoxY * (childSCMaxHeight + 30));
// + defaultSpacingY;
box = new Dimension(width1, height1);
}
if (structCount == 0) {
shape.getSpaceManager().setSizePreferred((box.width + StructureShape.defaultSpacingX * 2), (box.height + StructureShape.defaultSpacingY * 2));
} else {
shape.getSpaceManager().setSizePreferred((childStructureMaxWidth + box.width + StructureShape.defaultSpacingX * 2), (Math.max(childStructureTotalHeight, box.height) + StructureShape.defaultSpacingY * 2));
}
} else {
shape.getSpaceManager().setSizePreferred((shape.getLabelSize().width + StructureShape.defaultSpacingX * 2), (shape.getLabelSize().height + StructureShape.defaultSpacingY * 2));
}
return shape.getSpaceManager().getSizePreferred();
} finally {
g.setFont(origfont);
}
}
use of cbit.vcell.graph.StructureShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method getSeparatorDeepCountFeatureShape.
public Point getSeparatorDeepCountFeatureShape(Shape shape) {
int selfCountX = 1;
if (shape.countChildren() > 0) {
selfCountX++;
}
int selfCountY = 1;
// column1 is speciesContextShapes
Point column1 = new Point();
int scShapeCount = 0;
for (int i = 0; i < shape.countChildren(); i++) {
Shape child = shape.childShapeList.get(i);
if (child instanceof SpeciesContextShape) {
scShapeCount++;
}
}
column1.x = (scShapeCount > 0) ? 1 : 0;
column1.y = (scShapeCount > 0) ? scShapeCount / 2 : 0;
// column2 is StructureShapes
Point column2 = new Point();
for (int i = 0; i < shape.countChildren(); i++) {
Shape child = shape.childShapeList.get(i);
if (child instanceof StructureShape) {
Point childCount = getSeparatorDeepCount(child);
column2.x += childCount.x;
column2.y += childCount.y;
}
}
return new Point(selfCountX + column1.x + column2.x, selfCountY + Math.max(column1.y, column2.y));
}
use of cbit.vcell.graph.StructureShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method getSeparatorDeepCountStructureMappingFeatureShape.
public Point getSeparatorDeepCountStructureMappingFeatureShape(Shape shape) {
int selfCountX = 1;
int selfCountY = 1;
// column is StructureShapes
Point sepCount = new Point(selfCountX, selfCountY);
for (int i = 0; i < shape.countChildren(); i++) {
Shape child = shape.childShapeList.get(i);
if (child instanceof StructureShape) {
Point childCount = getSeparatorDeepCount(child);
sepCount.x = Math.max(sepCount.x, childCount.x);
sepCount.y += childCount.y + 1;
}
}
if (shape.countChildren() > 0) {
sepCount.x += 2;
}
return sepCount;
}
Aggregations