use of cbit.vcell.graph.FeatureShape 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.FeatureShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method refreshLayoutChildrenMembraneShape.
public void refreshLayoutChildrenMembraneShape(MembraneShape shape) {
// this is like a row/column layout (1 column)
// find featureShape child
FeatureShape featureShape = null;
for (Shape child : shape.getChildren()) {
if (child instanceof FeatureShape) {
featureShape = (FeatureShape) child;
}
}
// calculate total height of all children (not including label)
// position featureShape (and label)
int centerX = shape.getSpaceManager().getSize().width / 2;
int currentY = MembraneShape.memSpacingY;
if (featureShape != null) {
featureShape.getSpaceManager().setRelPos(centerX - featureShape.getSpaceManager().getSize().width / 2, currentY);
currentY += featureShape.getSpaceManager().getSize().height + MembraneShape.memSpacingY;
}
// position speciesContextShapes
// angle = 0 at north pole and increases counter clockwise
int numSpeciesContexts = shape.countChildren() - 1;
if (numSpeciesContexts > 0) {
double deltaAngle = MembraneShape.TotalAngle / (numSpeciesContexts + 1);
double currentAngle = MembraneShape.BeginAngle + deltaAngle;
for (Shape child : shape.getChildren()) {
if (child instanceof SpeciesContextShape) {
child.getSpaceManager().setRelPos(shape.getRadialPosition(currentAngle));
currentAngle = (currentAngle + deltaAngle) % (2 * Math.PI);
}
}
}
}
use of cbit.vcell.graph.FeatureShape 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.FeatureShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method getPreferedSizeMembraneShape.
public Dimension getPreferedSizeMembraneShape(MembraneShape shape, Graphics2D g) throws GraphModel.NotReadyException {
FontMetrics fm = g.getFontMetrics();
shape.setLabelSize(fm.stringWidth(shape.getLabel()), fm.getMaxAscent() + fm.getMaxDescent());
// has 1 child (featureShape)
if (shape.childShapeList.size() == 1) {
FeatureShape featureShape = (FeatureShape) shape.childShapeList.get(0);
Dimension featureDim = getPreferedSize(featureShape, g);
shape.getSpaceManager().setSizePreferred((featureDim.width + MembraneShape.memSpacingX * 2), (featureDim.height + MembraneShape.memSpacingY * 2));
}
return shape.getSpaceManager().getSizePreferred();
}
use of cbit.vcell.graph.FeatureShape in project vcell by virtualcell.
the class GraphContainerLayoutVCellClassical method resizeMembraneShape.
public void resizeMembraneShape(MembraneShape shape, Dimension newSize, Graphics2D g) throws GraphModel.NotReadyException {
int deltaX = newSize.width - shape.getSpaceManager().getSize().width;
int deltaY = newSize.height - shape.getSpaceManager().getSize().height;
shape.getSpaceManager().setSize(newSize);
// allocate all extra new space to featureShape
if (shape.childShapeList.size() == 1) {
FeatureShape featureShape = (FeatureShape) shape.childShapeList.get(0);
Dimension featureSize = new Dimension(featureShape.getSpaceManager().getSize());
featureSize.width += deltaX;
featureSize.height += deltaY;
resize(featureShape, featureSize, g);
}
shape.refreshLayoutSelf();
refreshLayoutChildren(shape);
}
Aggregations