Commit 37ad0306 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

Merge branch '1358-sbgn-view-unit-of-information-is-shown-twice-for-a-multimer' into 'master'

Resolve "SBGN view: unit of information is shown twice for a multimer"

Closes #1358

See merge request !1299
parents 4b7bd7d5 96aabae5
Pipeline #40149 failed with stage
in 20 minutes and 14 seconds
......@@ -6,6 +6,8 @@ minerva (16.0.0~alpha.2) stable; urgency=medium
* Small improvement: homomultimer information is provided in API (#1468)
* Small improvement: missing info about species for SBML parsing warning
(#1472)
* Small improvement: information about dimer in sbgn is provided only once
if the information is duplicated in sbgn data (#1358)
* Small improvement: glyph quality is improved (#1458)
* Bug fix: arrows without a "process" box had an irregular empty space in
their lines (#1471)
......
......@@ -42,7 +42,7 @@ public class AntisenseRnaConverter extends SpeciesConverter<AntisenseRna> {
@Override
protected void drawImpl(final AntisenseRna antisenseRna, final Graphics2D graphics, final ConverterParams params) {
Color oldColor = graphics.getColor();
GeneralPath path = getAntisenseRnaPath(antisenseRna);
GeneralPath path = getShape(antisenseRna);
graphics.setColor(antisenseRna.getFillColor());
graphics.fill(path);
Stroke stroke = graphics.getStroke();
......@@ -66,7 +66,8 @@ public class AntisenseRnaConverter extends SpeciesConverter<AntisenseRna> {
* {@link AntisenseRna} for which we want to get border
* @return border of the {@link AntisenseRna}
*/
private GeneralPath getAntisenseRnaPath(final AntisenseRna antisenseRna) {
@Override
protected GeneralPath getShape(final AntisenseRna antisenseRna) {
// CHECKSTYLE:OFF
GeneralPath path = new GeneralPath(Path2D.WIND_EVEN_ODD, 4);
path.moveTo(antisenseRna.getX(), antisenseRna.getY());
......@@ -80,7 +81,7 @@ public class AntisenseRnaConverter extends SpeciesConverter<AntisenseRna> {
@Override
public PathIterator getBoundPathIterator(final AntisenseRna alias) {
return getAntisenseRnaPath(alias).getPathIterator(new AffineTransform());
return getShape(alias).getPathIterator(new AffineTransform());
}
}
......@@ -68,7 +68,7 @@ public class ComplexConverter extends SpeciesConverter<Complex> {
complex.setX(complex.getX() - SpeciesConverter.HOMODIMER_OFFSET);
complex.setY(complex.getY() - SpeciesConverter.HOMODIMER_OFFSET);
GeneralPath path = getAliasPath(complex);
GeneralPath path = getShape(complex);
Stroke stroke = graphics.getStroke();
graphics.setColor(complex.getFillColor());
......@@ -79,14 +79,14 @@ public class ComplexConverter extends SpeciesConverter<Complex> {
if (complex.getState().equals("brief")) {
complex.increaseBorder(-INTERNAL_BORDER_DIST);
path = getAliasPath(complex);
path = getShape(complex);
complex.increaseBorder(INTERNAL_BORDER_DIST);
graphics.setStroke(LineType.DOTTED.getStroke());
graphics.draw(path);
}
if (complex.getActivity() && !params.isSbgnFormat()) {
complex.increaseBorder(INTERNAL_BORDER_DIST);
path = getAliasPath(complex);
path = getShape(complex);
complex.increaseBorder(-INTERNAL_BORDER_DIST);
graphics.setStroke(LineType.DOTTED.getStroke());
graphics.draw(path);
......@@ -128,7 +128,7 @@ public class ComplexConverter extends SpeciesConverter<Complex> {
@Override
public PathIterator getBoundPathIterator(final Complex complex) {
return getAliasPath(complex).getPathIterator(new AffineTransform());
return getShape(complex).getPathIterator(new AffineTransform());
}
/**
......@@ -138,7 +138,8 @@ public class ComplexConverter extends SpeciesConverter<Complex> {
* exact object for which we want to get a border
* @return border of the {@link Complex}
*/
private GeneralPath getAliasPath(final Complex complex) {
@Override
protected GeneralPath getShape(final Complex complex) {
GeneralPath path = new GeneralPath(Path2D.WIND_EVEN_ODD);
path.moveTo(complex.getX() + TRIMMED_CORNER_SIZE, complex.getY());
path.lineTo(complex.getX() + complex.getWidth() - TRIMMED_CORNER_SIZE, complex.getY());
......
......@@ -45,6 +45,21 @@ public class DegradedConverter extends SpeciesConverter<Degraded> {
@Override
protected void drawImpl(final Degraded degraded, final Graphics2D graphics, final ConverterParams params) {
Area a1 = getShape(degraded);
Color oldColor = graphics.getColor();
graphics.setColor(degraded.getFillColor());
graphics.fill(a1);
graphics.setColor(degraded.getBorderColor());
Stroke stroke = graphics.getStroke();
graphics.setStroke(getBorderLine(degraded));
graphics.draw(a1);
graphics.setStroke(stroke);
drawText(degraded, graphics, params);
graphics.setColor(oldColor);
}
@Override
protected Area getShape(final Degraded degraded) {
double diameter = getDiameter(degraded);
double x = getXCoord(degraded, diameter);
double y = getYCoord(degraded);
......@@ -64,16 +79,7 @@ public class DegradedConverter extends SpeciesConverter<Degraded> {
path.closePath();
a1.exclusiveOr(new Area(path));
Color oldColor = graphics.getColor();
graphics.setColor(degraded.getFillColor());
graphics.fill(a1);
graphics.setColor(degraded.getBorderColor());
Stroke stroke = graphics.getStroke();
graphics.setStroke(getBorderLine(degraded));
graphics.draw(a1);
graphics.setStroke(stroke);
drawText(degraded, graphics, params);
graphics.setColor(oldColor);
return a1;
}
/**
......
......@@ -56,14 +56,15 @@ public class DrugConverter extends SpeciesConverter<Drug> {
* {@link Drug} for which we are looking for a border
* @return Shape object defining given alias
*/
private Shape getDrugShape(final Drug drug) {
@Override
protected Shape getShape(final Drug drug) {
return new RoundRectangle2D.Double(drug.getX(), drug.getY(), drug.getWidth(), drug.getHeight(),
RECTANGLE_CORNER_ARC_SIZE, RECTANGLE_CORNER_ARC_SIZE);
}
@Override
protected void drawImpl(Drug drug, final Graphics2D graphics, final ConverterParams params) {
Shape a1 = getDrugShape(drug);
Shape a1 = getShape(drug);
double offset = OFFSET_BETWEEN_BORDERS;
Shape a2 = new RoundRectangle2D.Double(
drug.getX() + offset, drug.getY() + offset, drug.getWidth() - 2 * offset, drug.getHeight() - 2 * offset,
......@@ -113,7 +114,7 @@ public class DrugConverter extends SpeciesConverter<Drug> {
@Override
public PathIterator getBoundPathIterator(Drug drug) {
return getDrugShape(drug).getPathIterator(new AffineTransform());
return getShape(drug).getPathIterator(new AffineTransform());
}
}
......@@ -41,7 +41,7 @@ public class GeneConverter extends SpeciesConverter<Gene> {
@Override
protected void drawImpl(final Gene gene, final Graphics2D graphics, final ConverterParams params) {
Shape shape = getGeneShape(gene);
Shape shape = getShape(gene);
Color c = graphics.getColor();
graphics.setColor(gene.getFillColor());
graphics.fill(shape);
......@@ -66,7 +66,8 @@ public class GeneConverter extends SpeciesConverter<Gene> {
* {@link Gene} for which we are looking for a {@link Shape}
* @return {@link Shape} that represents {@link Gene}
*/
private Shape getGeneShape(final Gene gene) {
@Override
protected Shape getShape(final Gene gene) {
Shape shape;
shape = new Rectangle(gene.getX().intValue(), gene.getY().intValue(), gene.getWidth().intValue(),
gene.getHeight().intValue());
......@@ -75,7 +76,7 @@ public class GeneConverter extends SpeciesConverter<Gene> {
@Override
public PathIterator getBoundPathIterator(final Gene gene) {
return getGeneShape(gene).getPathIterator(new AffineTransform());
return getShape(gene).getPathIterator(new AffineTransform());
}
}
......@@ -40,10 +40,7 @@ public class IonConverter extends SpeciesConverter<Ion> {
@Override
protected void drawImpl(Ion ion, final Graphics2D graphics, final ConverterParams params) {
double diameter = getDiameter(ion);
double x = getXCoord(ion, diameter);
double y = getYCoord(ion);
Shape shape = new Ellipse2D.Double(x, y, diameter, diameter);
Shape shape = getShape(ion);
Color oldColor = graphics.getColor();
graphics.setColor(ion.getFillColor());
graphics.fill(shape);
......@@ -56,6 +53,15 @@ public class IonConverter extends SpeciesConverter<Ion> {
graphics.setColor(oldColor);
}
@Override
protected Shape getShape(Ion ion) {
double diameter = getDiameter(ion);
double x = getXCoord(ion, diameter);
double y = getYCoord(ion);
Shape shape = new Ellipse2D.Double(x, y, diameter, diameter);
return shape;
}
/**
* Returns transformed y coordinate for the {@link Ion}.
*
......
......@@ -38,7 +38,7 @@ public class PhenotypeConverter extends SpeciesConverter<Phenotype> {
@Override
protected void drawImpl(Phenotype phenotype, final Graphics2D graphics, final ConverterParams params) {
GeneralPath path = getPhenotypePath(phenotype);
GeneralPath path = getShape(phenotype);
Color oldColor = graphics.getColor();
graphics.setColor(phenotype.getFillColor());
......@@ -60,7 +60,8 @@ public class PhenotypeConverter extends SpeciesConverter<Phenotype> {
* @return {@link GeneralPath} object defining border of the given
* {@link Phenotype}
*/
private GeneralPath getPhenotypePath(final Phenotype phenotype) {
@Override
protected GeneralPath getShape(final Phenotype phenotype) {
// CHECKSTYLE:OFF
GeneralPath path = new GeneralPath(Path2D.WIND_EVEN_ODD, 6);
path.moveTo(phenotype.getX() + phenotype.getWidth() / 6, phenotype.getY());
......@@ -76,7 +77,7 @@ public class PhenotypeConverter extends SpeciesConverter<Phenotype> {
@Override
public PathIterator getBoundPathIterator(Phenotype phenotype) {
return getPhenotypePath(phenotype).getPathIterator(new AffineTransform());
return getShape(phenotype).getPathIterator(new AffineTransform());
}
}
......@@ -50,8 +50,8 @@ public class ProteinConverter extends SpeciesConverter<Protein> {
* Default constructor.
*
* @param colorExtractor
* Object that helps to convert {@link DataOverlayEntry} values into colors
* when drawing {@link Species}
* Object that helps to convert {@link DataOverlayEntry} values into
* colors when drawing {@link Species}
*/
public ProteinConverter(ColorExtractor colorExtractor) {
super(colorExtractor);
......@@ -72,14 +72,7 @@ public class ProteinConverter extends SpeciesConverter<Protein> {
@Override
protected void drawImpl(final Protein protein, final Graphics2D graphics, final ConverterParams params) {
java.util.List<String> unitOfInformationText = new ArrayList<>();
if (protein.getStatePrefix() != null && protein.getStateLabel() != null) {
if (protein.getStatePrefix().equals("free input")) {
unitOfInformationText.add(protein.getStateLabel());
} else {
unitOfInformationText.add(protein.getStatePrefix() + ":" + protein.getStateLabel());
}
}
java.util.List<String> unitOfInformationText = getUnitOfInformation(protein);
int homodir = protein.getHomodimer();
......@@ -93,7 +86,8 @@ public class ProteinConverter extends SpeciesConverter<Protein> {
protein.setX(protein.getX() - SpeciesConverter.HOMODIMER_OFFSET);
protein.setY(protein.getY() - SpeciesConverter.HOMODIMER_OFFSET);
Shape shape = getShape(protein, graphics);
drawActivityShape(protein, graphics);
Shape shape = getShape(protein);
Color oldColor = graphics.getColor();
graphics.setColor(protein.getFillColor());
graphics.fill(shape);
......@@ -119,25 +113,39 @@ public class ProteinConverter extends SpeciesConverter<Protein> {
protein.setHeight(protein.getHeight() + SpeciesConverter.HOMODIMER_OFFSET * (protein.getHomodimer() - 1));
}
Shape getShape(final Protein protein, final Graphics2D graphics) {
protected java.util.List<String> getUnitOfInformation(final Protein protein) {
java.util.List<String> unitOfInformationText = new ArrayList<>();
if (protein.getStatePrefix() != null && protein.getStateLabel() != null) {
if (protein.getStatePrefix().equals("free input")) {
unitOfInformationText.add(protein.getStateLabel());
} else {
unitOfInformationText.add(protein.getStatePrefix() + ":" + protein.getStateLabel());
}
}
return unitOfInformationText;
}
void drawActivityShape(final Protein protein, final Graphics2D graphics) {
if (protein instanceof GenericProtein && protein.getActivity()) {
drawActivityGenericProtein(protein, graphics);
} else if (protein instanceof TruncatedProtein && protein.getActivity()) {
drawActivityTruncatedShape(protein, graphics);
} else if (protein instanceof ReceptorProtein && protein.getActivity()) {
drawActivityReceptorProtein(protein, graphics);
}
}
@Override
protected Shape getShape(final Protein protein) {
Shape shape = null;
if (protein instanceof GenericProtein) {
shape = getGenericShape(protein);
if (protein.getActivity()) {
drawActivityGenericProtein(protein, graphics);
}
} else if (protein instanceof IonChannelProtein) {
shape = getIonChannelShape(protein);
} else if (protein instanceof TruncatedProtein) {
shape = getTruncatedShape(protein);
if (protein.getActivity()) {
drawActivityTruncatedShape(protein, graphics);
}
} else if (protein instanceof ReceptorProtein) {
shape = getReceptorShape(protein);
if (protein.getActivity()) {
drawActivityReceptorProtein(protein, graphics);
}
} else {
logger.warn(new LogMarker(ProjectLogEntryType.DRAWING_ISSUE, protein) + "Unknown shape for protein");
shape = getDefaultAliasShape(protein);
......
package lcsb.mapviewer.converter.graphics.bioEntity.element.species;
import java.awt.*;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.List;
import org.apache.logging.log4j.LogManager;
......@@ -38,14 +38,7 @@ public class ProteinSbgnConverter extends ProteinConverter {
@Override
protected void drawImpl(final Protein protein, final Graphics2D graphics, final ConverterParams params) {
List<String> unitOfInformationText = new ArrayList<>();
if (protein.getStatePrefix() != null && protein.getStateLabel() != null) {
if (protein.getStatePrefix().equals("free input")) {
unitOfInformationText.add(protein.getStateLabel());
} else {
unitOfInformationText.add(protein.getStatePrefix() + ":" + protein.getStateLabel());
}
}
List<String> unitOfInformationText = getUnitOfInformation(protein);
int originalHomodimer = protein.getHomodimer();
int homodir;
......@@ -56,10 +49,15 @@ public class ProteinSbgnConverter extends ProteinConverter {
}
protein.setHomodimer(homodir);
super.drawImpl(protein, graphics, params);
protein.setHomodimer(originalHomodimer);
drawUnitOfInformation(unitOfInformationText, protein, graphics);
}
@Override
protected List<String> getUnitOfInformation(final Protein protein) {
List<String> unitOfInformationText = super.getUnitOfInformation(protein);
if (protein instanceof IonChannelProtein) {
if (protein.getActivity()) {
unitOfInformationText.add("open");
......@@ -68,20 +66,24 @@ public class ProteinSbgnConverter extends ProteinConverter {
}
}
if (homodir > 1) {
unitOfInformationText.add("N:" + Integer.toString(protein.getHomodimer()));
if (protein.getHomodimer() > 1) {
String unit = "N:" + Integer.toString(protein.getHomodimer());
if (!unitOfInformationText.contains(unit)) {
unitOfInformationText.add(unit);
}
}
Color oldColor = graphics.getColor();
drawUnitOfInformation(unitOfInformationText, protein, graphics);
graphics.setColor(oldColor);
return unitOfInformationText;
}
@Override
Shape getShape(final Protein protein, final Graphics2D graphics) {
protected Shape getShape(final Protein protein) {
return getGenericShape(protein);
}
@Override
void drawActivityShape(final Protein protein, final Graphics2D graphics) {
}
@Override
Shape getStructuralStateShape(StructuralState state) {
double arcSize = Math.min(state.getWidth(), state.getHeight());
......
......@@ -46,7 +46,7 @@ public class RnaConverter extends SpeciesConverter<Rna> {
@Override
protected void drawImpl(final Rna rna, final Graphics2D graphics, final ConverterParams params) {
GeneralPath path = getRnaPath(rna);
GeneralPath path = getShape(rna);
Color oldColor = graphics.getColor();
graphics.setColor(rna.getFillColor());
graphics.fill(path);
......@@ -71,7 +71,8 @@ public class RnaConverter extends SpeciesConverter<Rna> {
* {@link Rna} for which we are looking for a border
* @return {@link GeneralPath} object defining border of the given {@link Rna}
*/
private GeneralPath getRnaPath(final Rna rna) {
@Override
protected GeneralPath getShape(final Rna rna) {
// CHECKSTYLE:OFF
GeneralPath path = new GeneralPath(Path2D.WIND_EVEN_ODD, 4);
path.moveTo(rna.getX() + rna.getWidth() / 4, rna.getY());
......@@ -85,7 +86,7 @@ public class RnaConverter extends SpeciesConverter<Rna> {
@Override
public PathIterator getBoundPathIterator(final Rna rna) {
return getRnaPath(rna).getPathIterator(new AffineTransform());
return getShape(rna).getPathIterator(new AffineTransform());
}
}
......@@ -42,7 +42,8 @@ public class SBGNNucleicAcidFeatureConverter extends SpeciesConverter<Species> {
* {@link Species} for which the shape should be returned
* @return shape of the SBGN Nucleic acid feature for given alias
*/
private Shape getShape(final Species species) {
@Override
protected Shape getShape(final Species species) {
GeneralPath bottomRoundedRectangle = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
double x = species.getX(), y = species.getY(), width = species.getWidth(), height = species.getHeight();
......
......@@ -66,7 +66,8 @@ public class SimpleMoleculeConverter extends SpeciesConverter<SimpleMolecule> {
drawText(simpleMolecule, graphics, params);
}
Shape getShape(final SimpleMolecule simpleMolecule) {
@Override
protected Shape getShape(final SimpleMolecule simpleMolecule) {
return new Ellipse2D.Double(simpleMolecule.getX(), simpleMolecule.getY(), simpleMolecule.getWidth(),
simpleMolecule.getHeight());
}
......
......@@ -65,7 +65,8 @@ public class SimpleMoleculeSbgnConverter extends SimpleMoleculeConverter {
graphics.setColor(oldColor);
}
Shape getShape(final SimpleMolecule simpleMolecule) {
@Override
protected Shape getShape(final SimpleMolecule simpleMolecule) {
int arc = (int) Math.min(simpleMolecule.getWidth(), simpleMolecule.getHeight());
return new RoundRectangle2D.Double(simpleMolecule.getX(), simpleMolecule.getY(), simpleMolecule.getWidth(),
simpleMolecule.getHeight(), arc, arc);
......
......@@ -376,6 +376,7 @@ public abstract class SpeciesConverter<T extends Species> extends ElementConvert
* where the drawing should be performed
*/
protected void drawUnitOfInformation(List<String> units, T species, final Graphics2D graphics) {
Color oldColor = graphics.getColor();
List<String> unitsToDraw = new ArrayList<>();
for (String text : units) {
if (text != null && !text.trim().isEmpty()) {
......@@ -394,11 +395,11 @@ public abstract class SpeciesConverter<T extends Species> extends ElementConvert
double height = UNIT_OF_INFORMATION_HEIGHT;
Rectangle2D rectangle = new Rectangle2D.Double(p.getX() - width / 2, p.getY() - height / 2, width, height);
Color c = graphics.getColor();
graphics.setColor(Color.WHITE);
graphics.fill(rectangle);
graphics.setColor(c);
graphics.setColor(species.getBorderColor());
graphics.draw(rectangle);
graphics.setColor(species.getFontColor());
Font font = graphics.getFont();
graphics.setFont(getUnitOfInformationFont());
......@@ -410,6 +411,7 @@ public abstract class SpeciesConverter<T extends Species> extends ElementConvert
count++;
}
graphics.setColor(oldColor);
}
@Override
......@@ -626,4 +628,6 @@ public abstract class SpeciesConverter<T extends Species> extends ElementConvert
this.arrowTransformation = arrowTransformation;
}
protected abstract Shape getShape(T species);
}
......@@ -45,7 +45,7 @@ public class UnknownConverter extends SpeciesConverter<Unknown> {
if (unknown.getActivity()) {
int border = ACTIVITY_BORDER_DISTANCE;
unknown.increaseBorder(border);
Shape shape2 = new Ellipse2D.Double(unknown.getX(), unknown.getY(), unknown.getWidth(), unknown.getHeight());
Shape shape2 = getShape(unknown);
Stroke stroke = graphics.getStroke();
graphics.setStroke(LineType.DOTTED.getStroke());
graphics.draw(shape2);
......@@ -53,7 +53,7 @@ public class UnknownConverter extends SpeciesConverter<Unknown> {
unknown.increaseBorder(-border);
}
Shape shape = new Ellipse2D.Double(unknown.getX(), unknown.getY(), unknown.getWidth(), unknown.getHeight());
Shape shape = getShape(unknown);
Color c = graphics.getColor();
graphics.setColor(unknown.getFillColor());
graphics.fill(shape);
......@@ -61,6 +61,12 @@ public class UnknownConverter extends SpeciesConverter<Unknown> {
drawText(unknown, graphics, params);
}
@Override
protected Shape getShape(Unknown unknown) {
Shape shape = new Ellipse2D.Double(unknown.getX(), unknown.getY(), unknown.getWidth(), unknown.getHeight());
return shape;
}
@Override
public PathIterator getBoundPathIterator(Unknown unknown) {
throw new InvalidStateException("This class doesn't provide boundPath");
......
......@@ -6,9 +6,16 @@ import static org.mockito.Mockito.when;
import java.awt.*;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.output.ByteArrayOutputStream;
import org.junit.Rule;
import org.mockito.Mockito;
......@@ -65,6 +72,9 @@ public abstract class GraphicsTestFunctions {
protected GenericProtein createProtein() {
GenericProtein result = new GenericProtein("s" + elementCounter++);
result.setFillColor(Color.YELLOW);