Commit 0b2d056a authored by Piotr Gawron's avatar Piotr Gawron
Browse files

drawing is done according to z-index order

parent 9d84a793
Pipeline #10159 failed with stage
in 10 minutes and 29 seconds
......@@ -8,7 +8,6 @@ import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
......@@ -18,11 +17,20 @@ import lcsb.mapviewer.commands.ColorExtractor;
import lcsb.mapviewer.commands.SemanticZoomLevelMatcher;
import lcsb.mapviewer.common.MimeType;
import lcsb.mapviewer.converter.graphics.bioEntity.BioEntityConverterImpl;
import lcsb.mapviewer.converter.graphics.layer.LayerConverter;
import lcsb.mapviewer.converter.graphics.layer.LayerLineConverter;
import lcsb.mapviewer.converter.graphics.layer.LayerOvalConverter;
import lcsb.mapviewer.converter.graphics.layer.LayerRectConverter;
import lcsb.mapviewer.converter.graphics.layer.LayerTextConverter;
import lcsb.mapviewer.model.graphics.PolylineData;
import lcsb.mapviewer.model.map.BioEntity;
import lcsb.mapviewer.model.map.Drawable;
import lcsb.mapviewer.model.map.compartment.Compartment;
import lcsb.mapviewer.model.map.compartment.PathwayCompartment;
import lcsb.mapviewer.model.map.layout.ColorSchema;
import lcsb.mapviewer.model.map.layout.graphics.Layer;
import lcsb.mapviewer.model.map.layout.graphics.LayerOval;
import lcsb.mapviewer.model.map.layout.graphics.LayerRect;
import lcsb.mapviewer.model.map.layout.graphics.LayerText;
import lcsb.mapviewer.model.map.model.Model;
import lcsb.mapviewer.model.map.reaction.Reaction;
import lcsb.mapviewer.model.map.species.Complex;
......@@ -606,7 +614,7 @@ public abstract class AbstractImageGenerator {
/**
* Default class logger.
*/
private Logger logger = Logger.getLogger(AbstractImageGenerator.class);
private static Logger logger = Logger.getLogger(AbstractImageGenerator.class);
/**
* Graphics object which allows to draw objects.
......@@ -641,7 +649,7 @@ public abstract class AbstractImageGenerator {
* params}.
*
* @param params
* list of all params to create apropriate image
* list of all params to create appropriate image
* @throws DrawingException
* thrown when there was a problem with drawing a map
*
......@@ -700,59 +708,58 @@ public abstract class AbstractImageGenerator {
// Get the SBGN display format option from the model
this.sbgnFormat = params.isSbgn();
// Correct order of displaying is: elements, reactions, compartments,
// layers.
// In this way we can display all reactions and overlay them by compartments
// or layers if they should be solid and hide complexity behind it
List<Drawable> bioEntities = new ArrayList<>();
bioEntities.addAll(params.getModel().getBioEntities());
for (Layer layer : params.getModel().getLayers()) {
bioEntities.addAll(layer.getDrawables());
}
bioEntities.sort(BioEntity.Z_INDEX_COMPARATOR);
// draw all elements
for (Element element : params.getModel().getSortedSpeciesList()) {
// draw only elements that don't have parents (aren't included in any
// compartment/complexes)
for (Drawable element : bioEntities) {
if (element instanceof Species) {
if (((Species) element).getComplex() == null && element.getCompartment() == null) {
drawSpecies((Species) element);
}
}
}
// draw all reactions
for (Reaction reaction : params.getModel().getSortedReactions()) {
drawReaction(reaction);
}
// draw all compartments
for (Compartment compartment : params.getModel().getSortedCompartments()) {
// draw only compartment that don't have parents (aren't included in any
// compartment/complexes)
if (compartment.getCompartment() == null) {
drawCompartment(compartment);
drawSpecies((Species) element);
} else if (element instanceof Reaction) {
drawReaction((Reaction) element);
} else if (element instanceof Compartment) {
drawCompartment((Compartment) element);
} else if (element instanceof LayerText) {
drawText((LayerText) element);
} else if (element instanceof LayerOval) {
drawOval((LayerOval) element);
} else if (element instanceof LayerRect) {
drawRect((LayerRect) element);
} else if (element instanceof PolylineData) {
drawLine((PolylineData) element);
} else {
throw new DrawingException("Unknown class type: " + element);
}
}
// draw all layers
for (Layer layer : params.getModel().getLayers()) {
drawLayer(layer);
}
closeImageObject();
setDrawn(true);
}
private void drawText(LayerText element) {
new LayerTextConverter().draw(element, graphics);
}
private void drawRect(LayerRect element) {
new LayerRectConverter().draw(element, graphics);
}
private void drawOval(LayerOval element) {
new LayerOvalConverter().draw(element, graphics);
}
private void drawLine(PolylineData element) {
new LayerLineConverter().draw(element, graphics);
}
/**
* Method called after drawing. It should close drawing canvas properly.
*/
protected abstract void closeImageObject();
/**
* This method draw layer on the graphics.
*
* @param layer
* layer to be drawn
*/
private void drawLayer(final Layer layer) {
// get a converter nad set text borders to no
LayerConverter converter = new LayerConverter(false);
converter.drawLayer(layer, graphics);
}
/**
* Don't allow to create default public constructors with empty list of
* parameters.
......@@ -780,28 +787,7 @@ public abstract class AbstractImageGenerator {
converter.draw(compartment, graphics, compartmentParams, params.getVisibleLayoutsForElement(compartment));
// If compartment should be filled, then we could skip drawing the inside
// compartments.
if (zoomLevelMatcher.isTransparent(level, compartment.getTransparencyLevel()) || !params.nested) {
List<Element> result = new ArrayList<>();
result.addAll(compartment.getElements());
Collections.sort(result, Element.SIZE_COMPARATOR);
// draw all children of this compartment
for (Element child : result) {
// if a child is a standard species
if (child instanceof Species) {
drawSpecies((Species) child);
} else if (child instanceof Compartment) {
drawCompartment((Compartment) child);
} else {
// if a child is not a compartment or a species then we have a
// problem
throw new DrawingException(eu.getElementTag(child) + "Unknown Element type");
}
}
if (!compartment.containsIdenticalSpecies()) {
if (!(compartment instanceof PathwayCompartment)) {
converter.drawText(compartment, graphics, compartmentParams);
......@@ -848,21 +834,6 @@ public abstract class AbstractImageGenerator {
new ConverterParams().scale(customScale).level(level).sbgnFormat(sbgnFormat).nested(params.nested),
params.getVisibleLayoutsForElement(species));
// if the species is a complex then we may want to draw children
// objects
if (species instanceof Complex) {
Complex complex = (Complex) species;
// before drawing children check if the view is not set to brief
// mode
if (!complex.getState().equalsIgnoreCase("brief")) {
// depending on current zoom level, children are drawn or not
if (zoomLevelMatcher.isTransparent(level, complex.getTransparencyLevel()) || !params.nested) {
for (Species child : complex.getElements()) {
drawSpecies(child);
}
}
}
}
}
/**
......
package lcsb.mapviewer.converter.graphics.layer;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import lcsb.mapviewer.converter.graphics.geometry.ArrowTransformation;
import org.apache.log4j.Logger;
import lcsb.mapviewer.model.graphics.PolylineData;
import lcsb.mapviewer.model.map.layout.graphics.Layer;
import lcsb.mapviewer.model.map.layout.graphics.LayerOval;
import lcsb.mapviewer.model.map.layout.graphics.LayerRect;
import lcsb.mapviewer.model.map.layout.graphics.LayerText;
import org.apache.log4j.Logger;
/**
* This class allows to draw layer on Graphics2D.
*
......@@ -22,134 +18,53 @@ import org.apache.log4j.Logger;
*/
public class LayerConverter {
/**
* Default class logger.
*/
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(LayerConverter.class.getName());
/**
* Color used for text frames.
*/
private static final Color FRAME_COLOR = Color.LIGHT_GRAY;
/**
* Should the border around text be visible.
*/
private boolean visibleTextBorder = true;
/**
* This objects helps drawing arrows.
*/
private ArrowTransformation arrowTransformation = new ArrowTransformation();
/**
* Default constructor.
*
* @param visibleTextBorder
* should the text hav border
*/
public LayerConverter(final boolean visibleTextBorder) {
this.visibleTextBorder = visibleTextBorder;
}
/**
* Draw the whole layer on the Graphics2D.
*
* @param layer
* object to be drawn
* @param graphics
* where we want to draw the object
*/
public void drawLayer(final Layer layer, final Graphics2D graphics) {
if (layer.isVisible()) {
for (LayerText text : layer.getTexts()) {
drawLayerText(text, graphics);
}
for (LayerRect rect : layer.getRectangles()) {
drawLayerRect(rect, graphics);
}
for (LayerOval oval : layer.getOvals()) {
drawLayerOval(oval, graphics);
}
for (PolylineData line : layer.getLines()) {
drawLayerLine(line, graphics);
}
}
}
/**
* Draw text on the Graphics2D.
*
* @param text
* object to be drawn
* @param graphics
* where we want to draw the object
*/
private void drawLayerText(final LayerText text, final Graphics2D graphics) {
if (visibleTextBorder) {
Color tmpColor = graphics.getColor();
graphics.setColor(FRAME_COLOR);
Rectangle2D rect = new Rectangle2D.Double(text.getX(), text.getY(), text.getWidth(), text.getHeight());
graphics.draw(rect);
graphics.setColor(tmpColor);
}
int x = text.getX().intValue() + 2;
int y = text.getY().intValue();
y += graphics.getFontMetrics().getHeight();
graphics.drawString(text.getNotes(), x, y);
}
/**
* Draws rectangle on the Graphics2D.
*
* @param rect
* object to be drawn
* @param graphics
* where we want to draw the object
*/
private void drawLayerRect(final LayerRect rect, final Graphics2D graphics) {
Color tmpColor = graphics.getColor();
graphics.setColor(rect.getColor());
Rectangle2D rectangle = new Rectangle2D.Double(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
graphics.draw(rectangle);
graphics.setColor(tmpColor);
}
/**
* Draws line on the Graphics2D.
*
* @param line
* object to be drawn
* @param graphics
* where we want to draw the object
*/
private void drawLayerLine(final PolylineData line, final Graphics2D graphics) {
Color tmpColor = graphics.getColor();
graphics.setColor(line.getColor());
arrowTransformation.drawLine(line, graphics);
graphics.setColor(tmpColor);
}
/**
* Draws oval on the Graphics2D.
*
* @param oval
* object to be drawn
* @param graphics
* where we want to draw the object
*/
private void drawLayerOval(final LayerOval oval, final Graphics2D graphics) {
Color tmpColor = graphics.getColor();
graphics.setColor(oval.getColor());
Ellipse2D o = new Ellipse2D.Double(oval.getX(), oval.getY(), oval.getWidth(), oval.getHeight());
graphics.draw(o);
graphics.setColor(tmpColor);
}
/**
* Default class logger.
*/
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(LayerConverter.class.getName());
LayerLineConverter lineConverter;
LayerRectConverter rectConverter;
LayerOvalConverter ovalConverter;
LayerTextConverter textConverter;
/**
* Default constructor.
*
* @param visibleTextBorder
* should the text have border
*/
public LayerConverter(final boolean visibleTextBorder) {
this.lineConverter = new LayerLineConverter();
this.ovalConverter = new LayerOvalConverter();
this.rectConverter = new LayerRectConverter();
this.textConverter = new LayerTextConverter(visibleTextBorder);
}
/**
* Draw the whole layer on the Graphics2D.
*
* @param layer
* object to be drawn
* @param graphics
* where we want to draw the object
*/
public void drawLayer(final Layer layer, final Graphics2D graphics) {
if (layer.isVisible()) {
for (LayerText text : layer.getTexts()) {
textConverter.draw(text, graphics);
}
for (LayerRect rect : layer.getRectangles()) {
rectConverter.draw(rect, graphics);
}
for (LayerOval oval : layer.getOvals()) {
ovalConverter.draw(oval, graphics);
}
for (PolylineData line : layer.getLines()) {
lineConverter.draw(line, graphics);
}
}
}
}
\ No newline at end of file
package lcsb.mapviewer.converter.graphics.layer;
import java.awt.Color;
import java.awt.Graphics2D;
import org.apache.log4j.Logger;
import lcsb.mapviewer.converter.graphics.geometry.ArrowTransformation;
import lcsb.mapviewer.model.graphics.PolylineData;
/**
* This class allows to draw {@link PolylineData} on Graphics2D.
*
* @author Piotr Gawron
*
*/
public class LayerLineConverter {
/**
* Default class logger.
*/
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(LayerLineConverter.class.getName());
/**
* This objects helps drawing arrows.
*/
private ArrowTransformation arrowTransformation = new ArrowTransformation();
/**
* Draws line on the Graphics2D.
*
* @param line
* object to be drawn
* @param graphics
* where we want to draw the object
*/
public void draw(final PolylineData line, final Graphics2D graphics) {
Color tmpColor = graphics.getColor();
graphics.setColor(line.getColor());
arrowTransformation.drawLine(line, graphics);
graphics.setColor(tmpColor);
}
}
\ No newline at end of file
package lcsb.mapviewer.converter.graphics.layer;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import org.apache.log4j.Logger;
import lcsb.mapviewer.model.map.layout.graphics.LayerOval;
/**
* This class allows to draw {@link LayerOval} on Graphics2D.
*
* @author Piotr Gawron
*
*/
public class LayerOvalConverter {
/**
* Default class logger.
*/
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(LayerOvalConverter.class.getName());
/**
* Draws oval on the Graphics2D.
*
* @param oval
* object to be drawn
* @param graphics
* where we want to draw the object
*/
public void draw(final LayerOval oval, final Graphics2D graphics) {
Color tmpColor = graphics.getColor();
graphics.setColor(oval.getColor());
Ellipse2D o = new Ellipse2D.Double(oval.getX(), oval.getY(), oval.getWidth(), oval.getHeight());
graphics.draw(o);
graphics.setColor(tmpColor);
}
}
\ No newline at end of file
package lcsb.mapviewer.converter.graphics.layer;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import org.apache.log4j.Logger;
import lcsb.mapviewer.model.map.layout.graphics.LayerRect;
/**
* This class allows to draw layer on Graphics2D.
*
* @author Piotr Gawron
*
*/
public class LayerRectConverter {
/**
* Default class logger.
*/
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(LayerRectConverter.class.getName());
/**
* Draws rectangle on the Graphics2D.
*
* @param rect
* object to be drawn
* @param graphics
* where we want to draw the object
*/
public void draw(final LayerRect rect, final Graphics2D graphics) {
Color tmpColor = graphics.getColor();
graphics.setColor(rect.getColor());
Rectangle2D rectangle = new Rectangle2D.Double(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
graphics.draw(rectangle);
graphics.setColor(tmpColor);
}
}
\ No newline at end of file
package lcsb.mapviewer.converter.graphics.layer;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import org.apache.log4j.Logger;
import lcsb.mapviewer.model.map.layout.graphics.LayerText;
/**
* This class allows to draw {@link LayerText} on Graphics2D.
*
* @author Piotr Gawron
*
*/
public class LayerTextConverter {
/**
* Default class logger.
*/
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(LayerTextConverter.class.getName());
/**
* Color used for text frames.
*/
private static final Color FRAME_COLOR = Color.LIGHT_GRAY;