# HG changeset patch # User Ingo Weinzierl # Date 1325688228 0 # Node ID a026d005accd83a155dfc9f014745a8ce0e89daf # Parent 27ada2e4243d82a5bf928ad136ec85b93385698f Moved JFreeChart specific classes to de.intevation.flys.jfree and added required imports. flys-artifacts/trunk@3585 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 27ada2e4243d -r a026d005accd flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Wed Jan 04 14:25:10 2012 +0000 +++ b/flys-artifacts/ChangeLog Wed Jan 04 14:43:48 2012 +0000 @@ -1,3 +1,24 @@ +2012-01-04 Ingo Weinzierl + + * src/main/java/de/intevation/flys/exports/StyledXYSeries.java, + src/main/java/de/intevation/flys/exports/StyledAreaSeriesCollection.java, + src/main/java/de/intevation/flys/exports/EnhancedLineAndShapeRenderer.java: + Moved to de.intevation.flys.jfree. + + * src/main/java/de/intevation/flys/jfree/StyledXYSeries.java, + src/main/java/de/intevation/flys/jfree/StyledAreaSeriesCollection.java, + src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java: + Moved from de.intevation.flys.exports. + + * src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java, + src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java, + src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java, + src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java, + src/main/java/de/intevation/flys/exports/XYChartGenerator.java, + src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java, + src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java: + Added necessary imports. + 2012-01-04 Ingo Weinzierl * src/main/java/de/intevation/flys/exports/EnhancedLineAndShapeRenderer.java: diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java Wed Jan 04 14:25:10 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveGenerator.java Wed Jan 04 14:43:48 2012 +0000 @@ -21,6 +21,7 @@ import de.intevation.flys.jfree.FLYSAnnotation; import de.intevation.flys.jfree.StickyAxisAnnotation; +import de.intevation.flys.jfree.StyledXYSeries; /** diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java Wed Jan 04 14:25:10 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/CrossSectionGenerator.java Wed Jan 04 14:43:48 2012 +0000 @@ -10,15 +10,16 @@ import org.w3c.dom.Document; +import de.intevation.artifacts.DataProvider; + import de.intevation.artifactdatabase.state.ArtifactAndFacet; - import de.intevation.flys.model.CrossSectionLine; import de.intevation.flys.artifacts.model.FacetTypes; import de.intevation.flys.artifacts.model.CrossSectionFacet; - -import de.intevation.artifacts.DataProvider; +import de.intevation.flys.jfree.StyledAreaSeriesCollection; +import de.intevation.flys.jfree.StyledXYSeries; /** * An OutGenerator that generates cross section graphs. diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java Wed Jan 04 14:25:10 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveGenerator.java Wed Jan 04 14:43:48 2012 +0000 @@ -25,6 +25,7 @@ import de.intevation.flys.utils.FLYSUtils; import de.intevation.flys.jfree.FLYSAnnotation; +import de.intevation.flys.jfree.StyledXYSeries; /** * An OutGenerator that generates discharge curves. diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java Wed Jan 04 14:25:10 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java Wed Jan 04 14:43:48 2012 +0000 @@ -14,6 +14,7 @@ import de.intevation.flys.artifacts.model.WKms; import de.intevation.flys.jfree.FLYSAnnotation; +import de.intevation.flys.jfree.StyledXYSeries; /** diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java Wed Jan 04 14:25:10 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveGenerator.java Wed Jan 04 14:43:48 2012 +0000 @@ -21,6 +21,7 @@ import de.intevation.flys.artifacts.resources.Resources; import de.intevation.flys.jfree.FLYSAnnotation; +import de.intevation.flys.jfree.StyledXYSeries; /** diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/EnhancedLineAndShapeRenderer.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/EnhancedLineAndShapeRenderer.java Wed Jan 04 14:25:10 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -package de.intevation.flys.exports; - -import java.awt.Graphics2D; -import java.awt.Shape; -import java.awt.geom.Rectangle2D; -import java.util.HashMap; -import java.util.Map; - -import org.apache.log4j.Logger; - -import org.jfree.chart.axis.ValueAxis; -import org.jfree.chart.entity.EntityCollection; -import org.jfree.chart.plot.CrosshairState; -import org.jfree.chart.plot.PlotOrientation; -import org.jfree.chart.plot.XYPlot; -import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; -import org.jfree.data.xy.XYDataset; -import org.jfree.ui.RectangleEdge; -import org.jfree.util.BooleanList; -import org.jfree.util.ShapeUtilities; - - -public class EnhancedLineAndShapeRenderer extends XYLineAndShapeRenderer { - - private static final Logger logger = - Logger.getLogger(EnhancedLineAndShapeRenderer.class); - - protected BooleanList isMinimumShapeVisible; - protected BooleanList isMaximumShapeVisible; - - protected Map seriesMinimum; - protected Map seriesMaximum; - - - public EnhancedLineAndShapeRenderer(boolean lines, boolean shapes) { - super(lines, shapes); - this.isMinimumShapeVisible = new BooleanList(); - this.isMaximumShapeVisible = new BooleanList(); - this.seriesMinimum = new HashMap(); - this.seriesMaximum = new HashMap(); - } - - - public boolean getItemShapeVisible(XYDataset dataset, int series, int item){ - if (super.getItemShapeVisible(series, item)) { - return true; - } - - if (isMinimumShapeVisible(series) && isMinimum(dataset, series, item)) { - return true; - } - - if (isMaximumShapeVisible(series) && isMaximum(dataset, series, item)) { - return true; - } - - return false; - } - - - /** - * Overrides XYLineAndShapeRenderer.drawSecondaryPass() to call an adapted - * method getItemShapeVisible() which now takes an XYDataset. So, 99% of - * code equal the code in XYLineAndShapeRenderer. - */ - @Override - protected void drawSecondaryPass( - Graphics2D g2, - XYPlot plot, - XYDataset dataset, - int pass, - int series, - int item, - ValueAxis domainAxis, - Rectangle2D dataArea, - ValueAxis rangeAxis, - CrosshairState crosshairState, - EntityCollection entities - ) { - Shape entityArea = null; - - // get the data point... - double x1 = dataset.getXValue(series, item); - double y1 = dataset.getYValue(series, item); - if (Double.isNaN(y1) || Double.isNaN(x1)) { - return; - } - - PlotOrientation orientation = plot.getOrientation(); - RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); - RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); - double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation); - double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation); - - if (getItemShapeVisible(dataset, series, item)) { - Shape shape = getItemShape(series, item); - if (orientation == PlotOrientation.HORIZONTAL) { - shape = ShapeUtilities.createTranslatedShape(shape, transY1, - transX1); - } - else if (orientation == PlotOrientation.VERTICAL) { - shape = ShapeUtilities.createTranslatedShape(shape, transX1, - transY1); - } - entityArea = shape; - if (shape.intersects(dataArea)) { - if (getItemShapeFilled(series, item)) { - if (getUseFillPaint()) { - g2.setPaint(getItemFillPaint(series, item)); - } - else { - g2.setPaint(getItemPaint(series, item)); - } - g2.fill(shape); - } - if (getDrawOutlines()) { - if (getUseOutlinePaint()) { - g2.setPaint(getItemOutlinePaint(series, item)); - } - else { - g2.setPaint(getItemPaint(series, item)); - } - g2.setStroke(getItemOutlineStroke(series, item)); - g2.draw(shape); - } - } - } - - double xx = transX1; - double yy = transY1; - if (orientation == PlotOrientation.HORIZONTAL) { - xx = transY1; - yy = transX1; - } - - // draw the item label if there is one... - if (isItemLabelVisible(series, item)) { - drawItemLabel(g2, orientation, dataset, series, item, xx, yy, - (y1 < 0.0)); - } - - int domainAxisIndex = plot.getDomainAxisIndex(domainAxis); - int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis); - updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex, - rangeAxisIndex, transX1, transY1, orientation); - - // add an entity for the item, but only if it falls within the data - // area... - if (entities != null && isPointInRect(dataArea, xx, yy)) { - addEntity(entities, entityArea, dataset, series, item, xx, yy); - } - } - - - public void setIsMinimumShapeVisisble(int series, boolean isVisible) { - this.isMinimumShapeVisible.setBoolean(series, isVisible); - } - - - public boolean isMinimumShapeVisible(int series) { - return isMinimumShapeVisible.getBoolean(series); - } - - - public void setIsMaximumShapeVisible(int series, boolean isVisible) { - this.isMaximumShapeVisible.setBoolean(series, isVisible); - } - - - public boolean isMaximumShapeVisible(int series) { - return isMaximumShapeVisible.getBoolean(series); - } - - - public boolean isMinimum(XYDataset dataset, int series, int item) { - return dataset.getYValue(series, item) == getMinimum(dataset, series); - } - - - public double getMinimum(XYDataset dataset, int series) { - Integer key = Integer.valueOf(series); - Double old = seriesMinimum.get(Integer.valueOf(series)); - - if (old != null) { - return old.doubleValue(); - } - - logger.debug("Compute minimum of Series: " + series); - - double min = Double.MAX_VALUE; - - for (int i = 0, n = dataset.getItemCount(series); i < n; i++) { - double tmpValue = dataset.getYValue(series, i); - - if (tmpValue < min) { - min = tmpValue; - } - } - - seriesMinimum.put(key, Double.valueOf(min)); - - return min; - } - - - public boolean isMaximum(XYDataset dataset, int series, int item) { - return dataset.getYValue(series, item) == getMaximum(dataset, series); - } - - - public double getMaximum(XYDataset dataset, int series) { - Integer key = Integer.valueOf(series); - Double old = seriesMaximum.get(Integer.valueOf(series)); - - if (old != null) { - return old.doubleValue(); - } - - logger.debug("Compute maximum of Series: " + series); - - double max = -Double.MAX_VALUE; - - for (int i = 0, n = dataset.getItemCount(series); i < n; i++) { - double tmpValue = dataset.getYValue(series, i); - - if (tmpValue > max) { - max = tmpValue; - } - } - - seriesMaximum.put(key, Double.valueOf(max)); - - return max; - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java Wed Jan 04 14:25:10 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java Wed Jan 04 14:43:48 2012 +0000 @@ -22,6 +22,8 @@ import de.intevation.flys.artifacts.model.WQKms; import de.intevation.flys.jfree.FLYSAnnotation; +import de.intevation.flys.jfree.StyledAreaSeriesCollection; +import de.intevation.flys.jfree.StyledXYSeries; import de.intevation.flys.utils.FLYSUtils; import de.intevation.flys.utils.DataUtil; diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/StyledAreaSeriesCollection.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/StyledAreaSeriesCollection.java Wed Jan 04 14:25:10 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -package de.intevation.flys.exports; - -import java.awt.Color; -import java.awt.Stroke; -import java.awt.BasicStroke; - -import org.apache.log4j.Logger; - -import org.w3c.dom.Document; - -import org.jfree.data.xy.XYSeriesCollection; - -import de.intevation.flys.utils.ThemeUtil; -import de.intevation.flys.jfree.StableXYDifferenceRenderer; - - -/** - * One or more dataseries to draw a polygon (either "open up/downwards", or - * the area between two curves), a theme-document and further display options. - * The theme-document will later "style" the graphical representation. - * The display options can be used to control the z-order and the axis of the - * dataset. - */ -public class StyledAreaSeriesCollection extends XYSeriesCollection { - /** Mode, how to draw/which areas to fill. */ - public enum FILL_MODE {UNDER, ABOVE, BETWEEN}; - - /** MODE in use. */ - protected FILL_MODE mode; - - /** The theme-document with attributes about actual visual representation. */ - protected Document theme; - - /** Own logger. */ - private static final Logger logger = - Logger.getLogger(StyledAreaSeriesCollection.class); - - - /** - * @param theme the theme-document. - */ - public StyledAreaSeriesCollection(Document theme) { - this.theme = theme; - this.mode = FILL_MODE.BETWEEN; - } - - - /** Gets the Fill mode. */ - public FILL_MODE getMode() { - return this.mode; - } - - - /** Sets the Fill mode. */ - public void setMode(FILL_MODE fMode) { - this.mode = fMode; - } - - - /** - * Applies line color, size and type attributes to renderer, also - * whether to draw lines and/or points. - */ - public StableXYDifferenceRenderer applyTheme( - StableXYDifferenceRenderer renderer - ) { - applyFillColor(renderer); - applyShowShape(renderer); - applyOutlineColor(renderer); - applyOutlineStyle(renderer); - - return renderer; - } - - - /** - * Blindly (for now) apply the postiviepaint of renderer. - */ - protected void applyFillColor(StableXYDifferenceRenderer renderer) { - // Get color. - Color paint = ThemeUtil.parseFillColorField(theme); - // Get half-transparency flag. - if (ThemeUtil.parseTransparency(theme)) { - paint = new Color(paint.getRed(), paint.getGreen(), paint.getBlue(), - 128); - } - if (paint != null && this.getMode() == FILL_MODE.ABOVE) { - renderer.setPositivePaint(paint); - renderer.setNegativePaint(new Color(0,0,0,0)); - } - else if (paint != null && this.getMode() == FILL_MODE.UNDER) { - renderer.setNegativePaint(paint); - renderer.setPositivePaint(new Color(0,0,0,0)); - } - else { - if (paint == null) paint = new Color(177, 117, 102); - renderer.setPositivePaint(paint); - renderer.setNegativePaint(paint); - } - } - - /** - * Blindly (for now) apply the postiviepaint of renderer. - */ - protected void applyShowShape(StableXYDifferenceRenderer renderer) { - boolean show = ThemeUtil.parseShowBorder(theme); - renderer.setDrawOutline(show); - } - - protected void applyShowLine(StableXYDifferenceRenderer renderer) { - boolean show = ThemeUtil.parseShowLine(theme); - renderer.setShapesVisible(show); - } - - /** - * - */ - protected void applyOutlineColor(StableXYDifferenceRenderer renderer) { - Color c = ThemeUtil.parseLineColorField(theme); - renderer.setOutlinePaint(c); - } - - protected void applyOutlineWidth(StableXYDifferenceRenderer renderer) { - int size = ThemeUtil.parseLineWidth(theme); - } - - protected void applyOutlineStyle(StableXYDifferenceRenderer renderer) { - float[] dashes = ThemeUtil.parseLineStyle(theme); - int size = ThemeUtil.parseLineWidth(theme); - - Stroke stroke = null; - - if (dashes.length <= 1) { - stroke = new BasicStroke(Integer.valueOf(size)); - } - else { - stroke = new BasicStroke(Integer.valueOf(size), - BasicStroke.CAP_BUTT, - BasicStroke.JOIN_ROUND, - 1.0f, - dashes, - 0.0f); - } - - renderer.setOutlineStroke(stroke); - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/StyledXYSeries.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/StyledXYSeries.java Wed Jan 04 14:25:10 2012 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,142 +0,0 @@ -package de.intevation.flys.exports; - -import java.awt.BasicStroke; -import java.awt.Color; -import java.awt.geom.Ellipse2D; - -import org.apache.log4j.Logger; - -import org.w3c.dom.Document; - -import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; -import org.jfree.data.xy.XYSeries; - -import de.intevation.flys.utils.ThemeUtil; - -/** - * Dataseries in two dimensions with additional theme-document and further - * display options. - * The theme-document will later "style" the graphical representation. - * The display options can be used to control the z-order and the axis of the - * dataseries. - */ -public class StyledXYSeries extends XYSeries { - - protected Document theme; - - private static final Logger logger = Logger.getLogger(StyledXYSeries.class); - - - public StyledXYSeries(String key, Document theme) { - this(key, true, theme); - } - - - /** - * @param sorted whether or not to sort the points. Sorting will move NANs - * to one extrema which can cause problems in certain - * algorithms. - */ - public StyledXYSeries(String key, boolean sorted, Document theme) { - super(key, sorted); - this.theme = theme; - } - - - /** - * Applies line color, size and type attributes to renderer, also - * whether to draw lines and/or points. - */ - public XYLineAndShapeRenderer applyTheme(XYLineAndShapeRenderer r, int idx){ - applyLineColor(r, idx); - applyLineSize(r, idx); - applyLineType(r, idx); - applyShowLine(r, idx); - applyShowPoints(r, idx); - applyShowMinimum(r, idx); - applyShowMaximum(r, idx); - - return r; - } - - - /** Set line color to renderer. */ - protected void applyLineColor(XYLineAndShapeRenderer r, int idx) { - Color c = ThemeUtil.parseLineColorField(theme); - r.setSeriesPaint(idx, c); - } - - - protected void applyLineSize(XYLineAndShapeRenderer r, int idx) { - int size = ThemeUtil.parseLineWidth(theme); - r.setSeriesStroke( - idx, - new BasicStroke(Integer.valueOf(size))); - } - - - protected void applyLineType(XYLineAndShapeRenderer r, int idx) { - int size = ThemeUtil.parseLineWidth(theme); - float[] dashes = ThemeUtil.parseLineStyle(theme); - - // Do not apply the dashed style. - if (dashes.length <= 1) { - return; - } - - r.setSeriesStroke( - idx, - new BasicStroke(Integer.valueOf(size), - BasicStroke.CAP_BUTT, - BasicStroke.JOIN_ROUND, - 1.0f, - dashes, - 0.0f)); - } - - - /** - * Sets form and visibility of points. - */ - protected void applyShowPoints(XYLineAndShapeRenderer r, int idx) { - boolean show = ThemeUtil.parseShowPoints(theme); - int size = ThemeUtil.parseLineWidth(theme); - r.setSeriesShape(idx, new Ellipse2D.Double(- size, - - size, - 2 * size, - 2 * size)); - r.setSeriesShapesVisible(idx, show); - r.setDrawOutlines(true); - } - - - protected void applyShowLine(XYLineAndShapeRenderer r, int idx) { - boolean show = ThemeUtil.parseShowLine(theme); - r.setSeriesLinesVisible(idx, show); - } - - - protected void applyShowMinimum(XYLineAndShapeRenderer r, int idx) { - if (!(r instanceof EnhancedLineAndShapeRenderer)) { - return; - } - - boolean visible = ThemeUtil.parseShowMinimum(theme); - - EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r; - er.setIsMinimumShapeVisisble(idx, visible); - } - - - protected void applyShowMaximum(XYLineAndShapeRenderer r, int idx) { - if (!(r instanceof EnhancedLineAndShapeRenderer)) { - return; - } - - boolean visible = ThemeUtil.parseShowMaximum(theme); - - EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r; - er.setIsMaximumShapeVisible(idx, visible); - } -} -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java --- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java Wed Jan 04 14:25:10 2012 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java Wed Jan 04 14:43:48 2012 +0000 @@ -52,9 +52,12 @@ import de.intevation.flys.exports.ChartExportHelper; +import de.intevation.flys.jfree.EnhancedLineAndShapeRenderer; import de.intevation.flys.jfree.FLYSAnnotation; import de.intevation.flys.jfree.StableXYDifferenceRenderer; import de.intevation.flys.jfree.StickyAxisAnnotation; +import de.intevation.flys.jfree.StyledAreaSeriesCollection; +import de.intevation.flys.jfree.StyledXYSeries; import de.intevation.flys.utils.ThemeAccess; diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java Wed Jan 04 14:43:48 2012 +0000 @@ -0,0 +1,236 @@ +package de.intevation.flys.jfree; + +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.geom.Rectangle2D; +import java.util.HashMap; +import java.util.Map; + +import org.apache.log4j.Logger; + +import org.jfree.chart.axis.ValueAxis; +import org.jfree.chart.entity.EntityCollection; +import org.jfree.chart.plot.CrosshairState; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYDataset; +import org.jfree.ui.RectangleEdge; +import org.jfree.util.BooleanList; +import org.jfree.util.ShapeUtilities; + + +public class EnhancedLineAndShapeRenderer extends XYLineAndShapeRenderer { + + private static final Logger logger = + Logger.getLogger(EnhancedLineAndShapeRenderer.class); + + protected BooleanList isMinimumShapeVisible; + protected BooleanList isMaximumShapeVisible; + + protected Map seriesMinimum; + protected Map seriesMaximum; + + + public EnhancedLineAndShapeRenderer(boolean lines, boolean shapes) { + super(lines, shapes); + this.isMinimumShapeVisible = new BooleanList(); + this.isMaximumShapeVisible = new BooleanList(); + this.seriesMinimum = new HashMap(); + this.seriesMaximum = new HashMap(); + } + + + public boolean getItemShapeVisible(XYDataset dataset, int series, int item){ + if (super.getItemShapeVisible(series, item)) { + return true; + } + + if (isMinimumShapeVisible(series) && isMinimum(dataset, series, item)) { + return true; + } + + if (isMaximumShapeVisible(series) && isMaximum(dataset, series, item)) { + return true; + } + + return false; + } + + + /** + * Overrides XYLineAndShapeRenderer.drawSecondaryPass() to call an adapted + * method getItemShapeVisible() which now takes an XYDataset. So, 99% of + * code equal the code in XYLineAndShapeRenderer. + */ + @Override + protected void drawSecondaryPass( + Graphics2D g2, + XYPlot plot, + XYDataset dataset, + int pass, + int series, + int item, + ValueAxis domainAxis, + Rectangle2D dataArea, + ValueAxis rangeAxis, + CrosshairState crosshairState, + EntityCollection entities + ) { + Shape entityArea = null; + + // get the data point... + double x1 = dataset.getXValue(series, item); + double y1 = dataset.getYValue(series, item); + if (Double.isNaN(y1) || Double.isNaN(x1)) { + return; + } + + PlotOrientation orientation = plot.getOrientation(); + RectangleEdge xAxisLocation = plot.getDomainAxisEdge(); + RectangleEdge yAxisLocation = plot.getRangeAxisEdge(); + double transX1 = domainAxis.valueToJava2D(x1, dataArea, xAxisLocation); + double transY1 = rangeAxis.valueToJava2D(y1, dataArea, yAxisLocation); + + if (getItemShapeVisible(dataset, series, item)) { + Shape shape = getItemShape(series, item); + if (orientation == PlotOrientation.HORIZONTAL) { + shape = ShapeUtilities.createTranslatedShape(shape, transY1, + transX1); + } + else if (orientation == PlotOrientation.VERTICAL) { + shape = ShapeUtilities.createTranslatedShape(shape, transX1, + transY1); + } + entityArea = shape; + if (shape.intersects(dataArea)) { + if (getItemShapeFilled(series, item)) { + if (getUseFillPaint()) { + g2.setPaint(getItemFillPaint(series, item)); + } + else { + g2.setPaint(getItemPaint(series, item)); + } + g2.fill(shape); + } + if (getDrawOutlines()) { + if (getUseOutlinePaint()) { + g2.setPaint(getItemOutlinePaint(series, item)); + } + else { + g2.setPaint(getItemPaint(series, item)); + } + g2.setStroke(getItemOutlineStroke(series, item)); + g2.draw(shape); + } + } + } + + double xx = transX1; + double yy = transY1; + if (orientation == PlotOrientation.HORIZONTAL) { + xx = transY1; + yy = transX1; + } + + // draw the item label if there is one... + if (isItemLabelVisible(series, item)) { + drawItemLabel(g2, orientation, dataset, series, item, xx, yy, + (y1 < 0.0)); + } + + int domainAxisIndex = plot.getDomainAxisIndex(domainAxis); + int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis); + updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex, + rangeAxisIndex, transX1, transY1, orientation); + + // add an entity for the item, but only if it falls within the data + // area... + if (entities != null && isPointInRect(dataArea, xx, yy)) { + addEntity(entities, entityArea, dataset, series, item, xx, yy); + } + } + + + public void setIsMinimumShapeVisisble(int series, boolean isVisible) { + this.isMinimumShapeVisible.setBoolean(series, isVisible); + } + + + public boolean isMinimumShapeVisible(int series) { + return isMinimumShapeVisible.getBoolean(series); + } + + + public void setIsMaximumShapeVisible(int series, boolean isVisible) { + this.isMaximumShapeVisible.setBoolean(series, isVisible); + } + + + public boolean isMaximumShapeVisible(int series) { + return isMaximumShapeVisible.getBoolean(series); + } + + + public boolean isMinimum(XYDataset dataset, int series, int item) { + return dataset.getYValue(series, item) == getMinimum(dataset, series); + } + + + public double getMinimum(XYDataset dataset, int series) { + Integer key = Integer.valueOf(series); + Double old = seriesMinimum.get(Integer.valueOf(series)); + + if (old != null) { + return old.doubleValue(); + } + + logger.debug("Compute minimum of Series: " + series); + + double min = Double.MAX_VALUE; + + for (int i = 0, n = dataset.getItemCount(series); i < n; i++) { + double tmpValue = dataset.getYValue(series, i); + + if (tmpValue < min) { + min = tmpValue; + } + } + + seriesMinimum.put(key, Double.valueOf(min)); + + return min; + } + + + public boolean isMaximum(XYDataset dataset, int series, int item) { + return dataset.getYValue(series, item) == getMaximum(dataset, series); + } + + + public double getMaximum(XYDataset dataset, int series) { + Integer key = Integer.valueOf(series); + Double old = seriesMaximum.get(Integer.valueOf(series)); + + if (old != null) { + return old.doubleValue(); + } + + logger.debug("Compute maximum of Series: " + series); + + double max = -Double.MAX_VALUE; + + for (int i = 0, n = dataset.getItemCount(series); i < n; i++) { + double tmpValue = dataset.getYValue(series, i); + + if (tmpValue > max) { + max = tmpValue; + } + } + + seriesMaximum.put(key, Double.valueOf(max)); + + return max; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/jfree/StyledAreaSeriesCollection.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StyledAreaSeriesCollection.java Wed Jan 04 14:43:48 2012 +0000 @@ -0,0 +1,148 @@ +package de.intevation.flys.jfree; + +import java.awt.Color; +import java.awt.Stroke; +import java.awt.BasicStroke; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +import org.jfree.data.xy.XYSeriesCollection; + +import de.intevation.flys.utils.ThemeUtil; +import de.intevation.flys.jfree.StableXYDifferenceRenderer; + + +/** + * One or more dataseries to draw a polygon (either "open up/downwards", or + * the area between two curves), a theme-document and further display options. + * The theme-document will later "style" the graphical representation. + * The display options can be used to control the z-order and the axis of the + * dataset. + */ +public class StyledAreaSeriesCollection extends XYSeriesCollection { + /** Mode, how to draw/which areas to fill. */ + public enum FILL_MODE {UNDER, ABOVE, BETWEEN}; + + /** MODE in use. */ + protected FILL_MODE mode; + + /** The theme-document with attributes about actual visual representation. */ + protected Document theme; + + /** Own logger. */ + private static final Logger logger = + Logger.getLogger(StyledAreaSeriesCollection.class); + + + /** + * @param theme the theme-document. + */ + public StyledAreaSeriesCollection(Document theme) { + this.theme = theme; + this.mode = FILL_MODE.BETWEEN; + } + + + /** Gets the Fill mode. */ + public FILL_MODE getMode() { + return this.mode; + } + + + /** Sets the Fill mode. */ + public void setMode(FILL_MODE fMode) { + this.mode = fMode; + } + + + /** + * Applies line color, size and type attributes to renderer, also + * whether to draw lines and/or points. + */ + public StableXYDifferenceRenderer applyTheme( + StableXYDifferenceRenderer renderer + ) { + applyFillColor(renderer); + applyShowShape(renderer); + applyOutlineColor(renderer); + applyOutlineStyle(renderer); + + return renderer; + } + + + /** + * Blindly (for now) apply the postiviepaint of renderer. + */ + protected void applyFillColor(StableXYDifferenceRenderer renderer) { + // Get color. + Color paint = ThemeUtil.parseFillColorField(theme); + // Get half-transparency flag. + if (ThemeUtil.parseTransparency(theme)) { + paint = new Color(paint.getRed(), paint.getGreen(), paint.getBlue(), + 128); + } + if (paint != null && this.getMode() == FILL_MODE.ABOVE) { + renderer.setPositivePaint(paint); + renderer.setNegativePaint(new Color(0,0,0,0)); + } + else if (paint != null && this.getMode() == FILL_MODE.UNDER) { + renderer.setNegativePaint(paint); + renderer.setPositivePaint(new Color(0,0,0,0)); + } + else { + if (paint == null) paint = new Color(177, 117, 102); + renderer.setPositivePaint(paint); + renderer.setNegativePaint(paint); + } + } + + /** + * Blindly (for now) apply the postiviepaint of renderer. + */ + protected void applyShowShape(StableXYDifferenceRenderer renderer) { + boolean show = ThemeUtil.parseShowBorder(theme); + renderer.setDrawOutline(show); + } + + protected void applyShowLine(StableXYDifferenceRenderer renderer) { + boolean show = ThemeUtil.parseShowLine(theme); + renderer.setShapesVisible(show); + } + + /** + * + */ + protected void applyOutlineColor(StableXYDifferenceRenderer renderer) { + Color c = ThemeUtil.parseLineColorField(theme); + renderer.setOutlinePaint(c); + } + + protected void applyOutlineWidth(StableXYDifferenceRenderer renderer) { + int size = ThemeUtil.parseLineWidth(theme); + } + + protected void applyOutlineStyle(StableXYDifferenceRenderer renderer) { + float[] dashes = ThemeUtil.parseLineStyle(theme); + int size = ThemeUtil.parseLineWidth(theme); + + Stroke stroke = null; + + if (dashes.length <= 1) { + stroke = new BasicStroke(Integer.valueOf(size)); + } + else { + stroke = new BasicStroke(Integer.valueOf(size), + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_ROUND, + 1.0f, + dashes, + 0.0f); + } + + renderer.setOutlineStroke(stroke); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r 27ada2e4243d -r a026d005accd flys-artifacts/src/main/java/de/intevation/flys/jfree/StyledXYSeries.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StyledXYSeries.java Wed Jan 04 14:43:48 2012 +0000 @@ -0,0 +1,142 @@ +package de.intevation.flys.jfree; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.geom.Ellipse2D; + +import org.apache.log4j.Logger; + +import org.w3c.dom.Document; + +import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; +import org.jfree.data.xy.XYSeries; + +import de.intevation.flys.utils.ThemeUtil; + +/** + * Dataseries in two dimensions with additional theme-document and further + * display options. + * The theme-document will later "style" the graphical representation. + * The display options can be used to control the z-order and the axis of the + * dataseries. + */ +public class StyledXYSeries extends XYSeries { + + protected Document theme; + + private static final Logger logger = Logger.getLogger(StyledXYSeries.class); + + + public StyledXYSeries(String key, Document theme) { + this(key, true, theme); + } + + + /** + * @param sorted whether or not to sort the points. Sorting will move NANs + * to one extrema which can cause problems in certain + * algorithms. + */ + public StyledXYSeries(String key, boolean sorted, Document theme) { + super(key, sorted); + this.theme = theme; + } + + + /** + * Applies line color, size and type attributes to renderer, also + * whether to draw lines and/or points. + */ + public XYLineAndShapeRenderer applyTheme(XYLineAndShapeRenderer r, int idx){ + applyLineColor(r, idx); + applyLineSize(r, idx); + applyLineType(r, idx); + applyShowLine(r, idx); + applyShowPoints(r, idx); + applyShowMinimum(r, idx); + applyShowMaximum(r, idx); + + return r; + } + + + /** Set line color to renderer. */ + protected void applyLineColor(XYLineAndShapeRenderer r, int idx) { + Color c = ThemeUtil.parseLineColorField(theme); + r.setSeriesPaint(idx, c); + } + + + protected void applyLineSize(XYLineAndShapeRenderer r, int idx) { + int size = ThemeUtil.parseLineWidth(theme); + r.setSeriesStroke( + idx, + new BasicStroke(Integer.valueOf(size))); + } + + + protected void applyLineType(XYLineAndShapeRenderer r, int idx) { + int size = ThemeUtil.parseLineWidth(theme); + float[] dashes = ThemeUtil.parseLineStyle(theme); + + // Do not apply the dashed style. + if (dashes.length <= 1) { + return; + } + + r.setSeriesStroke( + idx, + new BasicStroke(Integer.valueOf(size), + BasicStroke.CAP_BUTT, + BasicStroke.JOIN_ROUND, + 1.0f, + dashes, + 0.0f)); + } + + + /** + * Sets form and visibility of points. + */ + protected void applyShowPoints(XYLineAndShapeRenderer r, int idx) { + boolean show = ThemeUtil.parseShowPoints(theme); + int size = ThemeUtil.parseLineWidth(theme); + r.setSeriesShape(idx, new Ellipse2D.Double(- size, + - size, + 2 * size, + 2 * size)); + r.setSeriesShapesVisible(idx, show); + r.setDrawOutlines(true); + } + + + protected void applyShowLine(XYLineAndShapeRenderer r, int idx) { + boolean show = ThemeUtil.parseShowLine(theme); + r.setSeriesLinesVisible(idx, show); + } + + + protected void applyShowMinimum(XYLineAndShapeRenderer r, int idx) { + if (!(r instanceof EnhancedLineAndShapeRenderer)) { + return; + } + + boolean visible = ThemeUtil.parseShowMinimum(theme); + + EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r; + er.setIsMinimumShapeVisisble(idx, visible); + } + + + protected void applyShowMaximum(XYLineAndShapeRenderer r, int idx) { + if (!(r instanceof EnhancedLineAndShapeRenderer)) { + return; + } + + boolean visible = ThemeUtil.parseShowMaximum(theme); + + EnhancedLineAndShapeRenderer er = (EnhancedLineAndShapeRenderer) r; + er.setIsMaximumShapeVisible(idx, visible); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :