ingo@2074: package de.intevation.flys.jfree;
ingo@2074: 
ingo@2074: import java.awt.Color;
ingo@2074: import java.awt.Stroke;
ingo@2074: import java.awt.BasicStroke;
ingo@2074: 
ingo@2074: import org.apache.log4j.Logger;
ingo@2074: 
ingo@2074: import org.w3c.dom.Document;
ingo@2074: 
ingo@2074: import org.jfree.data.xy.XYSeriesCollection;
ingo@2074: 
ingo@2074: import de.intevation.flys.utils.ThemeUtil;
felix@2666: import de.intevation.flys.utils.ThemeAccess;
ingo@2074: import de.intevation.flys.jfree.StableXYDifferenceRenderer;
ingo@2074: 
ingo@2074: 
ingo@2074: /**
ingo@2074:  * One or more dataseries to draw a polygon (either "open up/downwards", or
ingo@2074:  * the area between two curves), a theme-document and further display options.
ingo@2074:  * The theme-document will later "style" the graphical representation.
ingo@2074:  * The display options can be used to control the z-order and the axis of the 
ingo@2074:  * dataset.
ingo@2074:  */
ingo@2074: public class StyledAreaSeriesCollection extends XYSeriesCollection {
ingo@2074:     /** Mode, how to draw/which areas to fill. */
ingo@2074:     public enum FILL_MODE {UNDER, ABOVE, BETWEEN};
ingo@2074: 
ingo@2074:     /** MODE in use. */
ingo@2074:     protected FILL_MODE mode;
ingo@2074: 
ingo@2074:     /** The theme-document with attributes about actual visual representation. */
ingo@2074:     protected Document theme;
ingo@2074: 
ingo@2074:     /** Own logger. */
ingo@2074:     private static final Logger logger =
ingo@2074:         Logger.getLogger(StyledAreaSeriesCollection.class);
ingo@2074: 
ingo@2074: 
ingo@2074:     /**
ingo@2074:      * @param theme the theme-document.
ingo@2074:      */
ingo@2074:     public StyledAreaSeriesCollection(Document theme) {
ingo@2074:         this.theme = theme;
ingo@2074:         this.mode = FILL_MODE.BETWEEN;
ingo@2074:    }
ingo@2074: 
ingo@2074: 
ingo@2074:     /** Gets the Fill mode. */
ingo@2074:     public FILL_MODE getMode() {
ingo@2074:         return this.mode;
ingo@2074:     }
ingo@2074: 
ingo@2074: 
ingo@2074:     /** Sets the Fill mode. */
ingo@2074:     public void setMode(FILL_MODE fMode) {
ingo@2074:         this.mode = fMode;
ingo@2074:     }
ingo@2074: 
ingo@2074: 
ingo@2074:     /**
ingo@2074:      * Applies line color, size and type attributes to renderer, also
ingo@2074:      * whether to draw lines and/or points.
ingo@2074:      */
ingo@2074:     public StableXYDifferenceRenderer applyTheme(
ingo@2074:         StableXYDifferenceRenderer renderer
ingo@2074:     ) {
ingo@2074:         applyFillColor(renderer);
ingo@2074:         applyShowShape(renderer);
ingo@2074:         applyOutlineColor(renderer);
ingo@2074:         applyOutlineStyle(renderer);
felix@2666:         applyShowArea(renderer);
felix@2666:         if (mode == FILL_MODE.UNDER) {
felix@2666:             renderer.setAreaCalculationMode(StableXYDifferenceRenderer.CALCULATE_NEGATIVE_AREA);
felix@2666:         }
felix@2666:         else if (mode == FILL_MODE.ABOVE) {
felix@2666:             renderer.setAreaCalculationMode(StableXYDifferenceRenderer.CALCULATE_POSITIVE_AREA);
felix@2666:         }
felix@2666:         else {
felix@2666:             renderer.setAreaCalculationMode(StableXYDifferenceRenderer.CALCULATE_ALL_AREA);
felix@2666:         }
felix@2667: 
felix@2667:         // Apply text style.
felix@2666:         new ThemeAccess(theme).parseTextStyle().apply(renderer);
ingo@2074:         return renderer;
ingo@2074:     }
ingo@2074: 
ingo@2074: 
ingo@2074:     /**
ingo@2074:      * Blindly (for now) apply the postiviepaint of renderer.
ingo@2074:      */
ingo@2074:     protected void applyFillColor(StableXYDifferenceRenderer renderer) {
ingo@2074:         // Get color.
ingo@2074:         Color paint = ThemeUtil.parseFillColorField(theme);
ingo@2074:         // Get half-transparency flag.
ingo@2074:         if (ThemeUtil.parseTransparency(theme)) {
ingo@2074:             paint = new Color(paint.getRed(), paint.getGreen(), paint.getBlue(),
ingo@2074:                 128);
ingo@2074:         }
ingo@2074:         if (paint != null && this.getMode() == FILL_MODE.ABOVE) {
ingo@2074:             renderer.setPositivePaint(paint);
ingo@2074:             renderer.setNegativePaint(new Color(0,0,0,0));
ingo@2074:         }
ingo@2074:         else if (paint != null && this.getMode() == FILL_MODE.UNDER) {
ingo@2074:             renderer.setNegativePaint(paint);
ingo@2074:             renderer.setPositivePaint(new Color(0,0,0,0));
ingo@2074:         }
ingo@2074:         else {
ingo@2074:             if (paint == null) paint = new Color(177, 117, 102);
ingo@2074:             renderer.setPositivePaint(paint);
ingo@2074:             renderer.setNegativePaint(paint);
ingo@2074:         }
ingo@2074:     }
ingo@2074: 
ingo@2074:     /**
ingo@2074:      * Blindly (for now) apply the postiviepaint of renderer.
ingo@2074:      */
ingo@2074:     protected void applyShowShape(StableXYDifferenceRenderer renderer) {
ingo@2074:         boolean show = ThemeUtil.parseShowBorder(theme);
ingo@2074:         renderer.setDrawOutline(show);
ingo@2074:     }
ingo@2074: 
ingo@2074:     protected void applyShowLine(StableXYDifferenceRenderer renderer) {
ingo@2074:         boolean show = ThemeUtil.parseShowLine(theme);
ingo@2074:         renderer.setShapesVisible(show);
ingo@2074:     }
ingo@2074: 
ingo@2074:     /**
ingo@2074:      *
ingo@2074:      */
ingo@2074:     protected void applyOutlineColor(StableXYDifferenceRenderer renderer) {
ingo@2074:         Color c = ThemeUtil.parseLineColorField(theme);
ingo@2074:         renderer.setOutlinePaint(c);
ingo@2074:     }
ingo@2074: 
ingo@2074:     protected void applyOutlineWidth(StableXYDifferenceRenderer renderer) {
ingo@2074:         int size = ThemeUtil.parseLineWidth(theme);
ingo@2074:     }
ingo@2074: 
felix@2666:     /** Inform renderer whether it should draw a label. */
felix@2666:     protected void applyShowArea(StableXYDifferenceRenderer renderer) {
felix@2666:         renderer.setLabelArea(ThemeUtil.parseShowArea(theme));
felix@2666:     }
felix@2666: 
ingo@2074:     protected void applyOutlineStyle(StableXYDifferenceRenderer renderer) {
ingo@2074:         float[] dashes = ThemeUtil.parseLineStyle(theme);
ingo@2074:         int size       = ThemeUtil.parseLineWidth(theme);
ingo@2074: 
ingo@2074:         Stroke stroke = null;
ingo@2074: 
ingo@2074:         if (dashes.length <= 1) {
ingo@2074:             stroke = new BasicStroke(Integer.valueOf(size));
ingo@2074:         }
ingo@2074:         else {
ingo@2074:             stroke = new BasicStroke(Integer.valueOf(size),
ingo@2074:                 BasicStroke.CAP_BUTT,
ingo@2074:                 BasicStroke.JOIN_ROUND,
ingo@2074:                 1.0f,
ingo@2074:                 dashes,
ingo@2074:                 0.0f);
ingo@2074:         }
ingo@2074: 
ingo@2074:         renderer.setOutlineStroke(stroke);
ingo@2074:     }
ingo@2074: }
ingo@2074: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :