package org.forester.phylogeny.data;\r
\r
import java.awt.Color;\r
+import java.awt.Font;\r
import java.io.IOException;\r
import java.io.Writer;\r
import java.util.ArrayList;\r
\r
public final class NodeVisualData implements PhylogenyData {\r
\r
- public static final String SIZE_REF = "aptx_visualiation:node_size";\r
- public static final String SIZE_TYPE = "xsd:decimal";\r
- private static final byte DEFAULT_FONT_SIZE = -1;\r
- private static final int DEFAULT_SIZE = -1;\r
- private static final int DEFAULT_TRANSPARANCY = -1;\r
- private Color _border_color;\r
- private Color _fill_color;\r
+ public static final String APTX_VISUALIZATION_REF = "style:";\r
+ public static final int DEFAULT_SIZE = -1;\r
+ public static final String FONT_COLOR_REF = APTX_VISUALIZATION_REF + "font_color";\r
+ public static final String FONT_COLOR_TYPE = "xsd:token";\r
+ public static final String FONT_REF = APTX_VISUALIZATION_REF + "font";\r
+ public static final String FONT_SIZE_REF = APTX_VISUALIZATION_REF + "font_size";\r
+ public static final String FONT_SIZE_TYPE = "xsd:unsignedByte";\r
+ public static final String FONT_STYLE_BOLD = "bold";\r
+ public static final String FONT_STYLE_BOLD_ITALIC = "bold_italic";\r
+ public static final String FONT_STYLE_ITALIC = "italic";\r
+ public static final String FONT_STYLE_PLAIN = "plain";\r
+ public static final String FONT_STYLE_REF = APTX_VISUALIZATION_REF + "font_style";\r
+ public static final String FONT_STYLE_TYPE = "xsd:token";\r
+ public static final String FONT_TYPE = "xsd:token";\r
+ public static final String NODE_COLOR_REF = APTX_VISUALIZATION_REF + "node_color";\r
+ public static final String NODE_COLOR_TYPE = "xsd:token";\r
+ public static final String NODE_FILL_GRADIENT = "gradient";\r
+ public static final String NODE_FILL_NONE = "none";\r
+ public static final String NODE_FILL_SOLID = "solid";\r
+ public static final String NODE_FILL_TYPE_REF = APTX_VISUALIZATION_REF + "node_fill_type";\r
+ public static final String NODE_FILL_TYPE_TYPE = "xsd:token";\r
+ public static final String NODE_SHAPE_CIRCLE = "circle";\r
+ public static final String NODE_SHAPE_RECTANGLE = "rectangle";\r
+ public static final String NODE_SHAPE_REF = APTX_VISUALIZATION_REF + "node_shape";\r
+ public static final String NODE_SHAPE_TYPE = "xsd:token";\r
+ public static final String NODE_SIZE_REF = APTX_VISUALIZATION_REF + "node_size";\r
+ public static final String NODE_SIZE_TYPE = "xsd:float";\r
+ public static final String NODE_TRANSPARENCY_REF = APTX_VISUALIZATION_REF + "node_transparency";\r
+ public static final String NODE_TRANSPARENCY_TYPE = "xsd:float";\r
+ private static final byte DEFAULT_FONT_SIZE = -1;\r
+ private static final int DEFAULT_TRANSPARENCY = -1;\r
private NodeFill _fill_type;\r
- private String _font;\r
+ private Font _font;\r
private Color _font_color;\r
+ private String _font_name;\r
private byte _font_size;\r
- private FontType _font_type;\r
+ private FontType _font_style;\r
+ private Color _node_color;\r
private NodeShape _shape;\r
private float _size;\r
- private float _transparancy;\r
+ private float _transparency;\r
\r
public NodeVisualData() {\r
init();\r
}\r
\r
- public NodeVisualData( final String font,\r
- final FontType font_type,\r
+ public NodeVisualData( final String font_name,\r
+ final FontType font_style,\r
final byte font_size,\r
final Color font_color,\r
final NodeShape shape,\r
final NodeFill fill_type,\r
- final Color border_color,\r
- final Color fill_color,\r
+ final Color node_color,\r
final float size,\r
- final float transparancy ) {\r
- setFont( font );\r
- setFontType( font_type );\r
+ final float transparency ) {\r
+ setFontName( font_name );\r
+ setFontStyle( font_style );\r
setFontSize( font_size );\r
setFontColor( font_color );\r
setShape( shape );\r
setFillType( fill_type );\r
- setBorderColor( border_color );\r
- setFillColor( fill_color );\r
+ setNodeColor( node_color );\r
setSize( size );\r
- setTransparancy( transparancy );\r
+ setTransparency( transparency );\r
}\r
\r
@Override\r
\r
@Override\r
public final PhylogenyData copy() {\r
- return new NodeVisualData( !ForesterUtil.isEmpty( getFont() ) ? new String( getFont() ) : null,\r
- getFontType(),\r
+ return new NodeVisualData( !ForesterUtil.isEmpty( getFontName() ) ? new String( getFontName() ) : null,\r
+ getFontStyle(),\r
getFontSize(),\r
getFontColor() != null ? new Color( getFontColor().getRed(), getFontColor()\r
.getGreen(), getFontColor().getBlue() ) : null,\r
getShape(),\r
getFillType(),\r
- getBorderColor() != null ? new Color( getBorderColor().getRed(), getBorderColor()\r
- .getGreen(), getBorderColor().getBlue() ) : null,\r
- getFillColor() != null ? new Color( getFillColor().getRed(), getFillColor()\r
- .getGreen(), getFillColor().getBlue() ) : null,\r
+ getNodeColor() != null ? new Color( getNodeColor().getRed(), getNodeColor()\r
+ .getGreen(), getNodeColor().getBlue() ) : null,\r
getSize(),\r
- getTransparancy() );\r
- }\r
-\r
- public final Color getBorderColor() {\r
- return _border_color;\r
- }\r
-\r
- public final Color getFillColor() {\r
- return _fill_color;\r
+ getTransparency() );\r
}\r
\r
public final NodeFill getFillType() {\r
return _fill_type;\r
}\r
\r
- public final String getFont() {\r
- return _font;\r
+ public final Font getFont() {\r
+ if ( _font != null ) {\r
+ return _font;\r
+ }\r
+ else if ( !ForesterUtil.isEmpty( getFontName() ) ) {\r
+ _font = new Font( getFontName(), getFontStyleInt(), getFontSize() );\r
+ return _font;\r
+ }\r
+ return null;\r
}\r
\r
public final Color getFontColor() {\r
return _font_color;\r
}\r
\r
+ public final String getFontName() {\r
+ return _font_name;\r
+ }\r
+\r
public final byte getFontSize() {\r
return _font_size;\r
}\r
\r
- public final FontType getFontType() {\r
- return _font_type;\r
+ public final FontType getFontStyle() {\r
+ return _font_style;\r
+ }\r
+\r
+ public final int getFontStyleInt() {\r
+ if ( getFontStyle() == FontType.BOLD ) {\r
+ return Font.BOLD;\r
+ }\r
+ else if ( getFontStyle() == FontType.ITALIC ) {\r
+ return Font.ITALIC;\r
+ }\r
+ else if ( getFontStyle() == FontType.BOLD_ITALIC ) {\r
+ return Font.BOLD + Font.ITALIC;\r
+ }\r
+ return Font.PLAIN;\r
+ }\r
+\r
+ public final Color getNodeColor() {\r
+ return _node_color;\r
}\r
\r
public final NodeShape getShape() {\r
return _size;\r
}\r
\r
- public final float getTransparancy() {\r
- return _transparancy;\r
+ public final float getTransparency() {\r
+ return _transparency;\r
}\r
\r
public final boolean isEmpty() {\r
- return ( ForesterUtil.isEmpty( getFont() ) && ( getFontType() == FontType.NORMAL )\r
+ return ( ForesterUtil.isEmpty( getFontName() ) && ( getFontStyle() == FontType.PLAIN )\r
&& ( getFontSize() == DEFAULT_FONT_SIZE ) && ( getFontColor() == null )\r
&& ( getShape() == NodeShape.DEFAULT ) && ( getFillType() == NodeFill.DEFAULT )\r
- && ( getBorderColor() == null ) && ( getFillColor() == null ) && ( getSize() == DEFAULT_SIZE ) && ( getTransparancy() == DEFAULT_TRANSPARANCY ) );\r
+ && ( getNodeColor() == null ) && ( getSize() == DEFAULT_SIZE ) && ( getTransparency() == DEFAULT_TRANSPARENCY ) );\r
}\r
\r
@Override\r
throw new UnsupportedOperationException();\r
}\r
\r
- public final void setBorderColor( final Color border_color ) {\r
- _border_color = border_color;\r
- }\r
-\r
- public final void setFillColor( final Color fill_color ) {\r
- _fill_color = fill_color;\r
+ public void parseProperty( final Property prop ) {\r
+ if ( prop.getRef().equals( FONT_REF ) ) {\r
+ setFontName( prop.getValue().trim() );\r
+ }\r
+ else if ( prop.getRef().equals( FONT_SIZE_REF ) ) {\r
+ int s = -1;\r
+ try {\r
+ s = Integer.parseInt( prop.getValue() );\r
+ }\r
+ catch ( final NumberFormatException e ) {\r
+ return;\r
+ }\r
+ if ( ( s >= 0 ) && ( s < Byte.MAX_VALUE ) ) {\r
+ setFontSize( s );\r
+ }\r
+ }\r
+ else if ( prop.getRef().equals( FONT_STYLE_REF ) ) {\r
+ setFontStyle( prop.getValue() );\r
+ }\r
+ else if ( prop.getRef().equals( FONT_COLOR_REF ) ) {\r
+ try {\r
+ setFontColor( Color.decode( prop.getValue() ) );\r
+ }\r
+ catch ( final NumberFormatException e ) {\r
+ return;\r
+ }\r
+ }\r
+ else if ( prop.getRef().equals( NODE_SIZE_REF ) ) {\r
+ float s = -1.0f;\r
+ try {\r
+ s = Float.parseFloat( prop.getValue() );\r
+ }\r
+ catch ( final NumberFormatException e ) {\r
+ return;\r
+ }\r
+ if ( s >= 0 ) {\r
+ setSize( s );\r
+ }\r
+ }\r
+ else if ( prop.getRef().equals( NODE_COLOR_REF ) ) {\r
+ try {\r
+ setNodeColor( Color.decode( prop.getValue() ) );\r
+ }\r
+ catch ( final NumberFormatException e ) {\r
+ return;\r
+ }\r
+ }\r
+ else if ( prop.getRef().equals( NODE_SHAPE_REF ) ) {\r
+ setShape( prop.getValue() );\r
+ }\r
+ else if ( prop.getRef().equals( NODE_FILL_TYPE_REF ) ) {\r
+ setFillType( prop.getValue() );\r
+ }\r
}\r
\r
public final void setFillType( final NodeFill fill_type ) {\r
_fill_type = fill_type;\r
}\r
\r
- public final void setFont( final String font ) {\r
- if ( !ForesterUtil.isEmpty( font ) ) {\r
- _font = font;\r
+ public final void setFillType( final String fill ) {\r
+ if ( fill.equalsIgnoreCase( NODE_FILL_NONE ) ) {\r
+ setFillType( NodeFill.NONE );\r
+ }\r
+ else if ( fill.equalsIgnoreCase( NODE_FILL_SOLID ) ) {\r
+ setFillType( NodeFill.SOLID );\r
+ }\r
+ else if ( fill.equalsIgnoreCase( NODE_FILL_GRADIENT ) ) {\r
+ setFillType( NodeFill.GRADIENT );\r
}\r
else {\r
- _font = null;\r
+ setFillType( NodeFill.DEFAULT );\r
}\r
}\r
\r
_font_color = font_color;\r
}\r
\r
- public final void setFontSize( final byte font_size ) {\r
- _font_size = font_size;\r
+ public final void setFontName( final String font_name ) {\r
+ if ( !ForesterUtil.isEmpty( font_name ) ) {\r
+ _font_name = font_name;\r
+ }\r
+ else {\r
+ _font_name = null;\r
+ }\r
+ _font = null;\r
+ }\r
+\r
+ public final void setFontSize( final int font_size ) {\r
+ if ( ( font_size != DEFAULT_FONT_SIZE ) && ( font_size < 0 ) ) {\r
+ throw new IllegalArgumentException( "negative font size: " + font_size );\r
+ }\r
+ else if ( font_size > Byte.MAX_VALUE ) {\r
+ throw new IllegalArgumentException( "font size is too large: " + font_size );\r
+ }\r
+ _font_size = ( byte ) font_size;\r
+ _font = null;\r
+ }\r
+\r
+ public final void setFontStyle( final FontType font_style ) {\r
+ _font_style = font_style;\r
+ _font = null;\r
+ }\r
+\r
+ public final void setFontStyle( final int font_style ) {\r
+ if ( ( font_style == ( Font.BOLD + Font.ITALIC ) ) ) {\r
+ setFontStyle( FontType.BOLD_ITALIC );\r
+ }\r
+ else if ( font_style == Font.ITALIC ) {\r
+ setFontStyle( FontType.ITALIC );\r
+ }\r
+ else if ( font_style == Font.BOLD ) {\r
+ setFontStyle( FontType.BOLD );\r
+ }\r
+ else {\r
+ setFontStyle( FontType.PLAIN );\r
+ }\r
+ }\r
+\r
+ public final void setFontStyle( final String font_style ) {\r
+ if ( font_style.equalsIgnoreCase( FONT_STYLE_BOLD ) ) {\r
+ setFontStyle( FontType.BOLD );\r
+ }\r
+ else if ( font_style.equalsIgnoreCase( FONT_STYLE_ITALIC ) ) {\r
+ setFontStyle( FontType.ITALIC );\r
+ }\r
+ else if ( font_style.equalsIgnoreCase( FONT_STYLE_BOLD_ITALIC ) ) {\r
+ setFontStyle( FontType.BOLD_ITALIC );\r
+ }\r
+ else {\r
+ setFontStyle( FontType.PLAIN );\r
+ }\r
}\r
\r
- public final void setFontType( final FontType font_type ) {\r
- _font_type = font_type;\r
+ public final void setNodeColor( final Color node_color ) {\r
+ _node_color = node_color;\r
}\r
\r
public final void setShape( final NodeShape shape ) {\r
_shape = shape;\r
}\r
\r
+ public final void setShape( final String shape ) {\r
+ if ( shape.equalsIgnoreCase( NODE_SHAPE_CIRCLE ) ) {\r
+ setShape( NodeShape.CIRCLE );\r
+ }\r
+ else if ( shape.equalsIgnoreCase( NODE_SHAPE_RECTANGLE ) ) {\r
+ setShape( NodeShape.RECTANGLE );\r
+ }\r
+ else {\r
+ setShape( NodeShape.DEFAULT );\r
+ }\r
+ }\r
+\r
public final void setSize( final float size ) {\r
+ if ( ( size != DEFAULT_SIZE ) && ( size < 0 ) ) {\r
+ throw new IllegalArgumentException( "negative size: " + size );\r
+ }\r
_size = size;\r
}\r
\r
- public final void setTransparancy( final float transparancy ) {\r
- _transparancy = transparancy;\r
+ public final void setTransparency( final float transparency ) {\r
+ _transparency = transparency;\r
}\r
\r
@Override\r
\r
@Override\r
public final void toPhyloXML( final Writer writer, final int level, final String indentation ) throws IOException {\r
- throw new UnsupportedOperationException();\r
+ for( final Property p : toProperties() ) {\r
+ p.toPhyloXML( writer, level, indentation );\r
+ }\r
}\r
\r
@Override\r
return asText().toString();\r
}\r
\r
+ private String colorToHex( final Color c ) {\r
+ return String.format( "#%02x%02x%02x", c.getRed(), c.getGreen(), c.getBlue() );\r
+ }\r
+\r
private final void init() {\r
- setFont( null );\r
- setFontType( FontType.NORMAL );\r
+ setFontName( null );\r
+ setFontStyle( FontType.PLAIN );\r
setFontSize( DEFAULT_FONT_SIZE );\r
setFontColor( null );\r
setShape( NodeShape.DEFAULT );\r
setFillType( NodeFill.DEFAULT );\r
- setBorderColor( null );\r
- setFillColor( null );\r
+ setNodeColor( null );\r
setSize( DEFAULT_SIZE );\r
- setTransparancy( DEFAULT_TRANSPARANCY );\r
+ setTransparency( DEFAULT_TRANSPARENCY );\r
+ _font = null;\r
}\r
\r
private final List<Property> toProperties() {\r
final List<Property> properties = new ArrayList<Property>();\r
- properties.add( new Property( SIZE_REF, String.valueOf( getSize() ), "", SIZE_TYPE, AppliesTo.NODE ) );\r
- properties.add( new Property( SIZE_REF, String.valueOf( getShape() ), "", SIZE_TYPE, AppliesTo.NODE ) );\r
- properties.add( new Property( SIZE_REF, String.valueOf( getFillType() ), "", SIZE_TYPE, AppliesTo.NODE ) );\r
- properties.add( new Property( SIZE_REF, String.valueOf( getTransparancy() ), "", SIZE_TYPE, AppliesTo.NODE ) );\r
- properties.add( new Property( SIZE_REF, String.valueOf( getFillColor() ), "", SIZE_TYPE, AppliesTo.NODE ) );\r
- properties.add( new Property( SIZE_REF, String.valueOf( getBorderColor() ), "", SIZE_TYPE, AppliesTo.NODE ) );\r
+ if ( !ForesterUtil.isEmpty( getFontName() ) ) {\r
+ properties.add( new Property( FONT_REF, getFontName(), "", FONT_TYPE, AppliesTo.NODE ) );\r
+ }\r
+ if ( getFontSize() != DEFAULT_FONT_SIZE ) {\r
+ properties.add( new Property( FONT_SIZE_REF,\r
+ String.valueOf( getFontSize() ),\r
+ "",\r
+ FONT_SIZE_TYPE,\r
+ AppliesTo.NODE ) );\r
+ }\r
+ if ( getFontStyle() != FontType.PLAIN ) {\r
+ String font_style = "";\r
+ if ( getFontStyle() == FontType.ITALIC ) {\r
+ font_style = FONT_STYLE_ITALIC;\r
+ }\r
+ else if ( getFontStyle() == FontType.BOLD ) {\r
+ font_style = FONT_STYLE_BOLD;\r
+ }\r
+ else if ( getFontStyle() == FontType.BOLD_ITALIC ) {\r
+ font_style = FONT_STYLE_BOLD_ITALIC;\r
+ }\r
+ else {\r
+ throw new RuntimeException( "unknown font style" + getShape() );\r
+ }\r
+ properties.add( new Property( FONT_STYLE_REF, font_style, "", FONT_STYLE_TYPE, AppliesTo.NODE ) );\r
+ }\r
+ if ( getFontColor() != null ) {\r
+ properties.add( new Property( FONT_COLOR_REF,\r
+ colorToHex( getFontColor() ),\r
+ "",\r
+ FONT_COLOR_TYPE,\r
+ AppliesTo.NODE ) );\r
+ }\r
+ if ( getShape() != NodeShape.DEFAULT ) {\r
+ String shape = null;\r
+ if ( getShape() == NodeShape.RECTANGLE ) {\r
+ shape = NODE_SHAPE_RECTANGLE;\r
+ }\r
+ else if ( getShape() == NodeShape.CIRCLE ) {\r
+ shape = NODE_SHAPE_CIRCLE;\r
+ }\r
+ else {\r
+ throw new RuntimeException( "unknown node shape" + getShape() );\r
+ }\r
+ properties.add( new Property( NODE_SHAPE_REF, shape, "", NODE_SHAPE_TYPE, AppliesTo.NODE ) );\r
+ }\r
+ if ( getSize() != DEFAULT_SIZE ) {\r
+ properties.add( new Property( NODE_SIZE_REF,\r
+ String.valueOf( getSize() ),\r
+ "",\r
+ NODE_SIZE_TYPE,\r
+ AppliesTo.NODE ) );\r
+ }\r
+ if ( getNodeColor() != null ) {\r
+ properties.add( new Property( NODE_COLOR_REF,\r
+ colorToHex( getNodeColor() ),\r
+ "",\r
+ NODE_COLOR_TYPE,\r
+ AppliesTo.NODE ) );\r
+ }\r
+ if ( getFillType() != NodeFill.DEFAULT ) {\r
+ String fill = null;\r
+ if ( getFillType() == NodeFill.GRADIENT ) {\r
+ fill = NODE_FILL_GRADIENT;\r
+ }\r
+ else if ( getFillType() == NodeFill.NONE ) {\r
+ fill = NODE_FILL_NONE;\r
+ }\r
+ else if ( getFillType() == NodeFill.SOLID ) {\r
+ fill = NODE_FILL_SOLID;\r
+ }\r
+ else {\r
+ throw new RuntimeException( "unknown fill type " + getFillType() );\r
+ }\r
+ properties.add( new Property( NODE_FILL_TYPE_REF, fill, "", NODE_FILL_TYPE_TYPE, AppliesTo.NODE ) );\r
+ }\r
+ if ( getTransparency() != DEFAULT_TRANSPARENCY ) {\r
+ properties.add( new Property( NODE_TRANSPARENCY_REF,\r
+ String.valueOf( getTransparency() ),\r
+ "",\r
+ NODE_TRANSPARENCY_TYPE,\r
+ AppliesTo.NODE ) );\r
+ }\r
return properties;\r
}\r
\r
public enum FontType {\r
- BOLD, BOLD_ITALIC, ITALIC, NORMAL\r
+ BOLD, BOLD_ITALIC, ITALIC, PLAIN\r
}\r
\r
public enum NodeFill {\r