Commit 668e2a0e authored by Piotr Gawron's avatar Piotr Gawron
Browse files

work in progress - overlay colors are framework parameters

there are two type of overlay colors:
* user scope (every user account have custom color schema)
* system scope used when user colors are not defined
parent 0e7c9f27
package lcsb.mapviewer.common.geometry;
import java.awt.Color;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
public class ColorParser {
/**
* Base of the hex representation.
*/
private static final int HEX_BASE = 16;
/**
* Length of the string describing color in rgb: "#RRGGBB".
*/
private static final int COLOR_STRING_LENGTH = 7;
/**
* Where starts description of red color in stirng representing color.
*/
private static final int COLOR_SUBSTRING_START_RED = 1;
/**
* Where starts description of green color in stirng representing color.
*/
private static final int COLOR_SUBSTRING_START_GREEN = 3;
/**
* Where starts description of blue color in stirng representing color.
*/
private static final int COLOR_SUBSTRING_START_BLUE = 5;
public Color parse(String string) {
if (string.charAt(0) != '#') {
string = "#" + string;
}
if (string.length() != COLOR_STRING_LENGTH) {
throw new InvalidArgumentException("Invalid color value: " + string + ". Correct format: #xxxxxx (where x is a hex value)");
} else {
return new Color(Integer.valueOf(string.substring(COLOR_SUBSTRING_START_RED, COLOR_SUBSTRING_START_GREEN), HEX_BASE), //
Integer.valueOf(string.substring(COLOR_SUBSTRING_START_GREEN, COLOR_SUBSTRING_START_BLUE), HEX_BASE), //
Integer.valueOf(string.substring(COLOR_SUBSTRING_START_BLUE, COLOR_STRING_LENGTH), HEX_BASE));
}
}
}
package lcsb.mapviewer.common.geometry;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import java.awt.Color;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.Test;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
public class ColorParserTest {
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}
@Test
public void testSetInvalidColor() throws Exception {
try {
ColorParser parser = new ColorParser();
parser.parse("qwe");
fail("Exception expected");
} catch (InvalidArgumentException e) {
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testSetInvalidColor2() throws Exception {
try {
ColorParser parser = new ColorParser();
parser.parse("fffffff");
fail("Exception expected");
} catch (InvalidArgumentException e) {
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
@Test
public void testSetColor() throws Exception {
try {
ColorParser parser = new ColorParser();
Color color = parser.parse("#ffffff");
assertEquals(Color.WHITE, color);
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>lcsb.mapviewer</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>converter-graphics</artifactId>
<name>MapViewer graphics converter</name>
<description>Converter that allows to transform model into graphic representation</description>
<dependencies>
<!-- dependency from the MapViewer model -->
<dependency>
<groupId>lcsb.mapviewer</groupId>
<artifactId>model</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>lcsb.mapviewer</groupId>
<artifactId>model-command</artifactId>
<version>1.0</version>
</dependency>
<!-- Log4J -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- Library used for generating svg -->
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-rasterizer</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-svggen</artifactId>
<version>${batik.version}</version>
</dependency>
<!-- iText library for generating pdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itext.version}</version>
</dependency>
</dependencies>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>lcsb.mapviewer</groupId>
<artifactId>parent</artifactId>
<version>1.0</version>
</parent>
<artifactId>converter-graphics</artifactId>
<name>MapViewer graphics converter</name>
<description>Converter that allows to transform model into graphic representation</description>
<dependencies>
<!-- dependency from the MapViewer model -->
<dependency>
<groupId>lcsb.mapviewer</groupId>
<artifactId>model</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>lcsb.mapviewer</groupId>
<artifactId>model-command</artifactId>
<version>1.0</version>
</dependency>
<!-- Log4J -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<!-- Library used for generating svg -->
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-rasterizer</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.apache.xmlgraphics</groupId>
<artifactId>batik-svggen</artifactId>
<version>${batik.version}</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>${mockito.version}</version>
<scope>test</scope>
</dependency>
<!-- iText library for generating pdf -->
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itext.version}</version>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itext.version}</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
......@@ -14,6 +14,7 @@ import java.util.Map;
import org.apache.log4j.Logger;
import lcsb.mapviewer.commands.ColorExtractor;
import lcsb.mapviewer.common.MimeType;
import lcsb.mapviewer.converter.graphics.layer.LayerConverter;
import lcsb.mapviewer.converter.graphics.reaction.ReactionConverter;
......@@ -93,6 +94,8 @@ public abstract class AbstractImageGenerator {
*/
private Rectangle2D.Double border = null;
private ColorExtractor colorExtractor = null;
/**
* This class contains a list of params that are used for drawing.
*
......@@ -170,6 +173,10 @@ public abstract class AbstractImageGenerator {
*/
private List<Map<Object, ColorSchema>> visibleLayouts = new ArrayList<>();
private Color minColor = null;
private Color maxColor = null;
/**
* @param scale
* scale to set
......@@ -481,6 +488,24 @@ public abstract class AbstractImageGenerator {
return result;
}
public Color getMaxColor() {
return maxColor;
}
public Color getMinColor() {
return minColor;
}
public Params minColor(Color minColor) {
this.minColor = minColor;
return this;
}
public Params maxColor(Color maxColor) {
this.maxColor = maxColor;
return this;
}
}
/**
......@@ -526,6 +551,8 @@ public abstract class AbstractImageGenerator {
this.level = params.getLevel();
this.scale = params.getScale();
colorExtractor = new ColorExtractor(params.getMinColor(), params.getMaxColor());
// set border frame extended by a margin
border = new Rectangle2D.Double(
params.getX() - SINGLE_FRAME_MARGIN, params.getY() - SINGLE_FRAME_MARGIN, params.getWidth() * scale + 2 * SINGLE_FRAME_MARGIN,
......@@ -645,7 +672,7 @@ public abstract class AbstractImageGenerator {
}
// get a converter for this compartment
AliasConverter converter = new AliasConverter(compAlias);
AliasConverter converter = new AliasConverter(compAlias, colorExtractor);
ConverterParams compartmentParams = new ConverterParams().textCentered(fill).level(level);
if (nested) {
......@@ -732,7 +759,7 @@ public abstract class AbstractImageGenerator {
}
// at the beginning try to find an appropriate converter
AliasConverter converter = new AliasConverter(alias, sbgnFormat);
AliasConverter converter = new AliasConverter(alias, sbgnFormat, colorExtractor);
double customScale = 1;
if (rescale) {
customScale = scale;
......@@ -772,7 +799,7 @@ public abstract class AbstractImageGenerator {
if (!cross(reaction.getLines())) {
return;
}
ReactionConverter converter = new ReactionConverter();
ReactionConverter converter = new ReactionConverter(colorExtractor);
converter.drawReaction(reaction, graphics, sbgnFormat, visibleLayouts);
}
......
package lcsb.mapviewer.converter.graphics;
import java.awt.Graphics2D;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import lcsb.mapviewer.commands.ColorExtractor;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.converter.graphics.compartment.ArtifitialCompartmentConverter;
import lcsb.mapviewer.common.exception.NotImplementedException;
import lcsb.mapviewer.converter.graphics.compartment.BottomSquareCompartmentConverter;
import lcsb.mapviewer.converter.graphics.compartment.LeftSquareCompartmentConverter;
import lcsb.mapviewer.converter.graphics.compartment.OvalCompartmentConverter;
import lcsb.mapviewer.converter.graphics.compartment.PathwayCompartmentConverter;
import lcsb.mapviewer.converter.graphics.compartment.RightSquareCompartmentConverter;
import lcsb.mapviewer.converter.graphics.compartment.SquareCompartmentConverter;
import lcsb.mapviewer.converter.graphics.compartment.TopSquareCompartmentConverter;
......@@ -35,11 +35,11 @@ import lcsb.mapviewer.model.map.compartment.RightSquareCompartment;
import lcsb.mapviewer.model.map.compartment.SquareCompartment;
import lcsb.mapviewer.model.map.compartment.TopSquareCompartment;
import lcsb.mapviewer.model.map.layout.ColorSchema;
import lcsb.mapviewer.model.map.species.Element;
import lcsb.mapviewer.model.map.species.AntisenseRna;
import lcsb.mapviewer.model.map.species.Complex;
import lcsb.mapviewer.model.map.species.Degraded;
import lcsb.mapviewer.model.map.species.Drug;
import lcsb.mapviewer.model.map.species.Element;
import lcsb.mapviewer.model.map.species.Gene;
import lcsb.mapviewer.model.map.species.GenericProtein;
import lcsb.mapviewer.model.map.species.Ion;
......@@ -50,6 +50,7 @@ import lcsb.mapviewer.model.map.species.Rna;
import lcsb.mapviewer.model.map.species.SimpleMolecule;
import lcsb.mapviewer.model.map.species.TruncatedProtein;
import lcsb.mapviewer.model.map.species.Unknown;
import lcsb.mapviewer.modelutils.map.ElementUtils;
/**
* This class is designed to convert any type of alias into a graphic glyph that
......@@ -64,65 +65,8 @@ public class AliasConverter implements IAliasConverter<Element> {
/**
* Default class logger.
*/
private static Logger logger = Logger.getLogger(AliasConverter.class.getName());
// *****************************************************************
//
// STATIC PART
//
// *****************************************************************
/**
* Static map of graphic alias converters used for conversion of aliases. Key
* in this map is a class of alias. Value is the converter that can process
* this type of alias.
*/
private static Map<Class<? extends Element>, IAliasConverter<?>> aliasConverters = new HashMap<Class<? extends Element>, IAliasConverter<?>>();
static {
// at the beginning lets add all implemented aliases
// for element reference
addAliasConverter(GenericProtein.class, new ProteinConverter());
addAliasConverter(IonChannelProtein.class, new ProteinConverter());
addAliasConverter(ReceptorProtein.class, new ProteinConverter());
addAliasConverter(TruncatedProtein.class, new ProteinConverter());
addAliasConverter(Degraded.class, new DegradedConverter());
addAliasConverter(Complex.class, new ComplexConverter());
addAliasConverter(SimpleMolecule.class, new SimpleMoleculeConverter());
addAliasConverter(Drug.class, new DrugConverter());
addAliasConverter(Ion.class, new IonConverter());
addAliasConverter(Phenotype.class, new PhenotypeConverter());
addAliasConverter(Rna.class, new RnaConverter());
addAliasConverter(AntisenseRna.class, new AntisenseRnaConverter());
addAliasConverter(Gene.class, new GeneConverter());
addAliasConverter(Unknown.class, new UnknownConverter());
// for compartment aliases
addAliasConverter(SquareCompartment.class, new SquareCompartmentConverter());
addAliasConverter(OvalCompartment.class, new OvalCompartmentConverter());
addAliasConverter(PathwayCompartment.class, new ArtifitialCompartmentConverter());
addAliasConverter(BottomSquareCompartment.class, new BottomSquareCompartmentConverter());
addAliasConverter(TopSquareCompartment.class, new TopSquareCompartmentConverter());
addAliasConverter(LeftSquareCompartment.class, new LeftSquareCompartmentConverter());
addAliasConverter(RightSquareCompartment.class, new RightSquareCompartmentConverter());
}
/**
* Method that set a converter for specific alias type.
*
* @param clazz
* class type of alias
* @param converter
* converter that should be used for conversion of this alias
*/
protected static void addAliasConverter(final Class<? extends Element> clazz, final IAliasConverter<?> converter) {
if (aliasConverters.get(clazz) != null) {
logger.warn("Converter for " + clazz + " has been already added");
}
aliasConverters.put(clazz, converter);
}
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(AliasConverter.class.getName());
/**
* Returns a converter for given alias. If converter doesn't exist then null
......@@ -133,20 +77,57 @@ public class AliasConverter implements IAliasConverter<Element> {
* @return converter that can be applied for the given alias; null if such
* converter doesn't exist
*/
private static IAliasConverter<? extends Element> getConverterForAlias(final Element alias) {
private IAliasConverter<? extends Element> getConverterForAlias(Element alias, ColorExtractor colorExtractor) {
if (alias == null) {
throw new InvalidArgumentException("alias cannot be null");
}
IAliasConverter<?> result = aliasConverters.get(alias.getClass());
return result;
if (alias instanceof GenericProtein) {
return new ProteinConverter(colorExtractor);
} else if (alias instanceof IonChannelProtein) {
return new ProteinConverter(colorExtractor);
} else if (alias instanceof ReceptorProtein) {
return new ProteinConverter(colorExtractor);
} else if (alias instanceof TruncatedProtein) {
return new ProteinConverter(colorExtractor);
} else if (alias instanceof Degraded) {
return new DegradedConverter(colorExtractor);
} else if (alias instanceof Complex) {
return new ComplexConverter(colorExtractor);
} else if (alias instanceof SimpleMolecule) {
return new SimpleMoleculeConverter(colorExtractor);
} else if (alias instanceof Drug) {
return new DrugConverter(colorExtractor);
} else if (alias instanceof Ion) {
return new IonConverter(colorExtractor);
} else if (alias instanceof Phenotype) {
return new PhenotypeConverter(colorExtractor);
} else if (alias instanceof Rna) {
return new RnaConverter(colorExtractor);
} else if (alias instanceof AntisenseRna) {
return new AntisenseRnaConverter(colorExtractor);
} else if (alias instanceof Gene) {
return new GeneConverter(colorExtractor);
} else if (alias instanceof Unknown) {
return new UnknownConverter(colorExtractor);
} else if (alias instanceof SquareCompartment) {
return new SquareCompartmentConverter(colorExtractor);
} else if (alias instanceof OvalCompartment) {
return new OvalCompartmentConverter(colorExtractor);
} else if (alias instanceof PathwayCompartment) {
return new PathwayCompartmentConverter(colorExtractor);
} else if (alias instanceof BottomSquareCompartment) {
return new BottomSquareCompartmentConverter(colorExtractor);
} else if (alias instanceof TopSquareCompartment) {
return new TopSquareCompartmentConverter(colorExtractor);
} else if (alias instanceof LeftSquareCompartment) {
return new LeftSquareCompartmentConverter(colorExtractor);
} else if (alias instanceof RightSquareCompartment) {
return new RightSquareCompartmentConverter(colorExtractor);
} else {
throw new NotImplementedException(new ElementUtils().getElementTag(alias) + "Unknown element class");
}
}
// *******************************************************
//
// NON-STATIC CLASS DEFINITION
//
// *******************************************************
/**
* Converter used for conversion of the alias given in constructor.
*/
......@@ -161,14 +142,14 @@ public class AliasConverter implements IAliasConverter<Element> {
* @param sbgnFormat
* boolean value indicating if SBGN display format should be used
*/
public AliasConverter(final Element alias, final boolean sbgnFormat) {
public AliasConverter(final Element alias, final boolean sbgnFormat, ColorExtractor colorExtractor) {
// If alias is a nucleic acid feature to be displayed in SBGN
if (sbgnFormat && (alias instanceof AntisenseRna || alias instanceof Rna || alias instanceof Gene)) {
aliasConverter = new SBGNNucleicAcidFeatureConverter();
aliasConverter = new SBGNNucleicAcidFeatureConverter(colorExtractor);
} else {
// If not, at the beginning try to find an appropriate converter
aliasConverter = getConverterForAlias(alias);
aliasConverter = getConverterForAlias(alias, colorExtractor);
}
// if we don't know which converter to use then throw an exception
......@@ -183,8 +164,8 @@ public class AliasConverter implements IAliasConverter<Element> {
* @param alias
* alias for which this converter will be used
*/
public AliasConverter(final Element alias) {
this(alias, false);
public AliasConverter(final Element alias, ColorExtractor colorExtractor) {
this(alias, false, colorExtractor);
}
@SuppressWarnings("unchecked")
......
......@@ -9,6 +9,7 @@ import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import lcsb.mapviewer.commands.ColorExtractor;
import lcsb.mapviewer.converter.graphics.ConverterParams;
import lcsb.mapviewer.model.graphics.LineType;
import lcsb.mapviewer.model.map.compartment.BottomSquareCompartment;
......@@ -29,6 +30,10 @@ public class BottomSquareCompartmentConverter extends CompartmentConverter<Botto
@SuppressWarnings("unused")
private static Logger logger = Logger.getLogger(BottomSquareCompartmentConverter.class.getName());
public BottomSquareCompartmentConverter(ColorExtractor colorExtractor) {
super(colorExtractor);
}
@Override
public void drawAlias(final BottomSquareCompartment alias, final Graphics2D graphics, final ConverterParams params) {
// keep the old values of colors and line
......
......@@ -8,6 +8,7 @@ import java.util.List;
import org.apache.log4j.Logger;
import lcsb.mapviewer.commands.ColorExtractor;
import lcsb.mapviewer.common.Configuration;
import lcsb.mapviewer.common.exception.InvalidArgumentException;
import lcsb.mapviewer.common.geometry.EllipseTransformation;
......@@ -78,10 +79,13 @@ public abstract class CompartmentConverter<T extends Compartment> implements IAl
*/
private String placeFinderSynchronization = "";
private ColorExtractor colorExtractor;
/**
* Default constructor.
*/
protected CompartmentConverter() {
protected CompartmentConverter(ColorExtractor colorExtractor) {
this.colorExtractor = colorExtractor;
};
@Override
......@@ -177,7 +181,7 @@ public abstract class CompartmentConverter<T extends Compartment> implements IAl
int x = (int) (startX * alias.getWidth() + alias.getX());
graphics.drawRect(x, alias.getY().intValue(), (int) width, alias.getHeight().intValue());