# HG changeset patch # User Ingo Weinzierl # Date 1306915267 0 # Node ID bb484489d3df1dfd6a84fb98840b5dc3e4613c6d # Parent d299e220d89c62e6a8248cce80c91e4bec98ac19 Introduced a new output generators for creating chart info documents. flys-artifacts/trunk@2032 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r d299e220d89c -r bb484489d3df flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Tue May 31 14:56:18 2011 +0000 +++ b/flys-artifacts/ChangeLog Wed Jun 01 08:01:07 2011 +0000 @@ -1,3 +1,33 @@ +2011-06-01 Ingo Weinzierl + + * src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java: New. A + chart info generator generates a document that contains meta information + for a specific chart. Concrete instances of this abstract class need to + instantiate concrete ChartGenerators and dispatch nearly all methods of + an OutGenerator (init(), doOut(), setMaster()) to this instance. The + generate() method is implemented in the ChartInfoGenerator itself. It + creates a chart with help of the ChartGenerator instance and builds a + document that contains meta information of this chart. + + * src/main/java/de/intevation/flys/exports/InfoGeneratorHelper.java: New. + This helper is used to create the chart info document. At the moment, + the only information that is included in this document is a + transformation matrix to transform image coordinates into chart + coordinates. + + NOTE: The transformation matrix creation needs some work to support + charts with inverted X axis. + + * src/main/java/de/intevation/flys/exports/LongitudinalSectionInfoGenerator.java, + src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionInfoGenerator.java, + src/main/java/de/intevation/flys/exports/DurationCurveInfoGenerator.java, + src/main/java/de/intevation/flys/exports/DischargeCurveInfoGenerator.java, + src/main/java/de/intevation/flys/exports/ComputedDischargeCurveInfoGenerator.java: + Concrete instances of ChartInfoGenerator that create the chart info for + the currently supported chart types. + + * doc/conf/conf.xml: Registered new OutGenerators. + 2011-05-31 Ingo Weinzierl * src/main/java/de/intevation/flys/collections/FLYSArtifactCollection.java: diff -r d299e220d89c -r bb484489d3df flys-artifacts/doc/conf/conf.xml --- a/flys-artifacts/doc/conf/conf.xml Tue May 31 14:56:18 2011 +0000 +++ b/flys-artifacts/doc/conf/conf.xml Wed Jun 01 08:01:07 2011 +0000 @@ -50,10 +50,15 @@ de.intevation.flys.exports.DischargeCurveGenerator + de.intevation.flys.exports.DischargeCurveInfoGenerator de.intevation.flys.exports.ComputedDischargeCurveGenerator + de.intevation.flys.exports.ComputedDischargeCurveInfoGenerator de.intevation.flys.exports.LongitudinalSectionGenerator + de.intevation.flys.exports.LongitudinalSectionInfoGenerator de.intevation.flys.exports.DurationCurveGenerator + de.intevation.flys.exports.DurationCurveInfoGenerator de.intevation.flys.exports.DischargeLongitudinalSectionGenerator + de.intevation.flys.exports.DischargeLongitudinalSectionInfoGenerator de.intevation.flys.exports.WaterlevelExporter de.intevation.flys.exports.DurationCurveExporter de.intevation.flys.exports.ComputedDischargeCurveExporter diff -r d299e220d89c -r bb484489d3df flys-artifacts/src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ChartInfoGenerator.java Wed Jun 01 08:01:07 2011 +0000 @@ -0,0 +1,124 @@ +package de.intevation.flys.exports; + +import java.awt.Transparency; +import java.io.IOException; +import java.io.OutputStream; + +import org.w3c.dom.Document; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartRenderingInfo; +import org.jfree.chart.JFreeChart; + +import de.intevation.artifacts.Artifact; +import de.intevation.artifacts.CallContext; + +import de.intevation.artifacts.common.utils.XMLUtils; + + +/** + * An OutGenerator that generates meta information for charts. A concrete + * ChartInfoGenerator need to instantiate a concrete ChartGenerator and dispatch + * the methods to that instance. The only thing this ChartInfoGenerator needs + * to, is to overrite the generate() method which doesn't write the chart image + * to the OutputStream but a Document that contains some meta information of the + * created chart. + * + * @author Ingo Weinzierl + */ +public abstract class ChartInfoGenerator implements OutGenerator { + + /** The logger used in this generator.*/ + private static Logger logger = + Logger.getLogger(ChartInfoGenerator.class); + + + /** The OutGenerator that creates the charts.*/ + protected OutGenerator generator; + + protected OutputStream out; + + + + public ChartInfoGenerator(OutGenerator generator) { + this.generator = generator; + } + + + /** + * Dispatches the operation to the instantiated generator. + * + * @param request + * @param out + * @param context + */ + public void init(Document request, OutputStream out, CallContext context) { + this.out = out; + + generator.init(request, out, context); + } + + + /** + * Dispatches the operation to the instantiated generator. + * + * @param master + */ + public void setMasterArtifact(Artifact master) { + generator.setMasterArtifact(master); + } + + + /** + * Dispatches the operation to the instantiated generator. + * + * @param artifacts + * @param facet + * @param attr + */ + public void doOut(Artifact artifact, String facet, Document attr) { + generator.doOut(artifact, facet, attr); + } + + + /** + * This method generates the chart using a concrete ChartGenerator but + * doesn't write the chart itself to the OutputStream but a Document that + * contains meta information of the created chart. + */ + @Override + public void generate() + throws IOException + { + logger.debug("ChartInfoGenerator.generate"); + + JFreeChart chart = generateChart(); + + int[] size = getSize(); + + ChartRenderingInfo info = new ChartRenderingInfo(); + + chart.createBufferedImage(size[0], size[1], Transparency.BITMASK, info); + + Document doc = InfoGeneratorHelper.createInfoDocument(chart, info); + + XMLUtils.toStream(doc, out); + } + + + /** + * Creates a chart object. + * + * @return a chart object. + */ + protected abstract JFreeChart generateChart(); + + /** + * Returns the size of the generated chart. + * + * @return the size of the generated chart. + */ + protected abstract int[] getSize(); +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d299e220d89c -r bb484489d3df flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveInfoGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/ComputedDischargeCurveInfoGenerator.java Wed Jun 01 08:01:07 2011 +0000 @@ -0,0 +1,71 @@ +package de.intevation.flys.exports; + +import java.awt.Color; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +/** + * A ChartInfoGenerator that generates meta information for specific computed + * discharge curves. + * + * @author Ingo Weinzierl + */ +public class ComputedDischargeCurveInfoGenerator extends ChartInfoGenerator { + + private static Logger logger = + Logger.getLogger(ComputedDischargeCurveInfoGenerator.class); + + + public ComputedDischargeCurveInfoGenerator() { + super(new ComputedDischargeCurveGenerator()); + } + + + protected int[] getSize() { + ComputedDischargeCurveGenerator gen = + (ComputedDischargeCurveGenerator) generator; + + return gen.getSize(); + } + + + /** + * Creates a chart object. + * + * @return a chart object. + */ + protected JFreeChart generateChart() { + logger.debug("DischargeCurveInfoGenerator.generateChart"); + + ComputedDischargeCurveGenerator gen = + (ComputedDischargeCurveGenerator) generator; + + JFreeChart chart = ChartFactory.createXYLineChart( + gen.getChartTitle(), + gen.getXAxisLabel(), + gen.getYAxisLabel(), + null, + PlotOrientation.VERTICAL, + true, + false, + false); + + chart.setBackgroundPaint(Color.WHITE); + chart.getPlot().setBackgroundPaint(Color.WHITE); + + XYPlot plot = (XYPlot) chart.getPlot(); + + gen.addDatasets(chart); + gen.addSubtitles(chart); + gen.adjustPlot(plot); + gen.adjustAxes(plot); + + return chart; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d299e220d89c -r bb484489d3df flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveInfoGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeCurveInfoGenerator.java Wed Jun 01 08:01:07 2011 +0000 @@ -0,0 +1,72 @@ +package de.intevation.flys.exports; + +import java.awt.Color; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + + +/** + * A ChartInfoGenerator that generates meta information for specific discharge + * curves. + * + * @author Ingo Weinzierl + */ +public class DischargeCurveInfoGenerator extends ChartInfoGenerator { + + /** The logger used in this generator.*/ + private static Logger logger = + Logger.getLogger(DischargeCurveInfoGenerator.class); + + + + public DischargeCurveInfoGenerator() { + super(new DischargeCurveGenerator()); + } + + + protected int[] getSize() { + DischargeCurveGenerator gen = (DischargeCurveGenerator) generator; + + return gen.getSize(); + } + + + /** + * Creates a chart object. + * + * @return a chart object. + */ + protected JFreeChart generateChart() { + logger.debug("DischargeCurveInfoGenerator.generateChart"); + + DischargeCurveGenerator gen = (DischargeCurveGenerator) generator; + + JFreeChart chart = ChartFactory.createXYLineChart( + gen.getChartTitle(), + gen.getXAxisLabel(), + gen.getYAxisLabel(), + null, + PlotOrientation.VERTICAL, + true, + false, + false); + + chart.setBackgroundPaint(Color.WHITE); + chart.getPlot().setBackgroundPaint(Color.WHITE); + + XYPlot plot = (XYPlot) chart.getPlot(); + + gen.addDatasets(chart); + gen.addSubtitles(chart); + gen.adjustPlot(plot); + gen.adjustAxes(plot); + + return chart; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d299e220d89c -r bb484489d3df flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionInfoGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionInfoGenerator.java Wed Jun 01 08:01:07 2011 +0000 @@ -0,0 +1,72 @@ +package de.intevation.flys.exports; + +import java.awt.Color; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +/** + * A ChartInfoGenerator that generates meta information for specific discharge + * longitudinal section curves. + * + * @author Ingo Weinzierl + */ +public class DischargeLongitudinalSectionInfoGenerator +extends ChartInfoGenerator +{ + private static Logger logger = + Logger.getLogger(DischargeLongitudinalSectionInfoGenerator.class); + + + public DischargeLongitudinalSectionInfoGenerator() { + super(new DischargeLongitudinalSectionGenerator()); + } + + + protected int[] getSize() { + DischargeLongitudinalSectionGenerator gen = + (DischargeLongitudinalSectionGenerator) generator; + + return gen.getSize(); + } + + + /** + * Creates a chart object. + * + * @return a chart object. + */ + protected JFreeChart generateChart() { + logger.debug("DischargeCurveInfoGenerator.generateChart"); + + DischargeLongitudinalSectionGenerator gen = + (DischargeLongitudinalSectionGenerator) generator; + + JFreeChart chart = ChartFactory.createXYLineChart( + gen.getChartTitle(), + gen.getXAxisLabel(), + gen.getYAxisLabel(), + null, + PlotOrientation.VERTICAL, + true, + false, + false); + + chart.setBackgroundPaint(Color.WHITE); + chart.getPlot().setBackgroundPaint(Color.WHITE); + + XYPlot plot = (XYPlot) chart.getPlot(); + + gen.addDatasets(chart); + gen.addSubtitles(chart); + gen.adjustPlot(plot); + gen.adjustAxes(plot); + + return chart; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d299e220d89c -r bb484489d3df flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveInfoGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DurationCurveInfoGenerator.java Wed Jun 01 08:01:07 2011 +0000 @@ -0,0 +1,72 @@ +package de.intevation.flys.exports; + +import java.awt.Color; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +/** + * A ChartInfoGenerator that generates meta information for specific duration + * curves. + * + * @author Ingo Weinzierl + */ +public class DurationCurveInfoGenerator +extends ChartInfoGenerator +{ + private static Logger logger = + Logger.getLogger(DurationCurveInfoGenerator.class); + + + public DurationCurveInfoGenerator() { + super(new DurationCurveGenerator()); + } + + + protected int[] getSize() { + DurationCurveGenerator gen = + (DurationCurveGenerator) generator; + + return gen.getSize(); + } + + + /** + * Creates a chart object. + * + * @return a chart object. + */ + protected JFreeChart generateChart() { + logger.debug("DischargeCurveInfoGenerator.generateChart"); + + DurationCurveGenerator gen = + (DurationCurveGenerator) generator; + + JFreeChart chart = ChartFactory.createXYLineChart( + gen.getChartTitle(), + gen.getXAxisLabel(), + gen.getYAxisLabel(), + null, + PlotOrientation.VERTICAL, + true, + false, + false); + + chart.setBackgroundPaint(Color.WHITE); + chart.getPlot().setBackgroundPaint(Color.WHITE); + + XYPlot plot = (XYPlot) chart.getPlot(); + + gen.addDatasets(chart); + gen.addSubtitles(chart); + gen.adjustPlot(plot); + gen.adjustAxes(plot); + + return chart; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d299e220d89c -r bb484489d3df flys-artifacts/src/main/java/de/intevation/flys/exports/InfoGeneratorHelper.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/InfoGeneratorHelper.java Wed Jun 01 08:01:07 2011 +0000 @@ -0,0 +1,160 @@ +package de.intevation.flys.exports; + +import java.awt.geom.AffineTransform; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.Rectangle2D; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartRenderingInfo; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.XYPlot; +import org.jfree.data.Range; + +import de.intevation.artifacts.common.ArtifactNamespaceContext; +import de.intevation.artifacts.common.utils.XMLUtils; +import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator; + + +/** + * This class helps generating chart info documents. + * + * @author Ingo Weinzierl + */ +public class InfoGeneratorHelper { + + private static final Logger logger = + Logger.getLogger(InfoGeneratorHelper.class); + + + private InfoGeneratorHelper() { + } + + + /** + * Triggers the creation of the chart info document. + * + * @param chart The JFreeChart chart. + * @param info An info object that has been created while chart creation. + * + * @return the info document. + */ + public static Document createInfoDocument( + JFreeChart chart, + ChartRenderingInfo info) + { + logger.debug("InfoGeneratorHelper.createInfoDocument"); + + Document doc = XMLUtils.newDocument(); + + ElementCreator cr = new ElementCreator( + doc, + ArtifactNamespaceContext.NAMESPACE_URI, + ArtifactNamespaceContext.NAMESPACE_PREFIX); + + Element chartinfo = cr.create("chartinfo"); + + chartinfo.appendChild(createTransformationElement(cr, chart, info)); + + doc.appendChild(chartinfo); + + return doc; + } + + + /** + * This method appends the values of a transformation matrix to transform + * image pixel coordinates into chart coordinates. + * + * @param cr The ElementCreator. + * @param chart The chart object. + * @param info The ChartRenderingInfo that is filled while chart creation. + * + * @return an element that contains one or more transformation matrix. + */ + protected static Element createTransformationElement( + ElementCreator cr, + JFreeChart chart, + ChartRenderingInfo info) + { + logger.debug("InfoGeneratorHelper.createTransformationElement"); + + Element tf = cr.create("transformation-matrix"); + + Rectangle2D dataArea = info.getPlotInfo().getDataArea(); + + XYPlot plot = (XYPlot) chart.getPlot(); + Range xRange = plot.getDomainAxis().getRange(); + Range yRange = plot.getRangeAxis().getRange(); + + double[] tm = createTransformationMatrix(dataArea, xRange, yRange); + + cr.addAttr(tf, "sx", String.valueOf(tm[0]), true); + cr.addAttr(tf, "sy", String.valueOf(tm[1]), true); + cr.addAttr(tf, "tx", String.valueOf(tm[2]), true); + cr.addAttr(tf, "ty", String.valueOf(tm[3]), true); + + return tf; + } + + + /** + * This method determines a transformation matrix to transform pixel + * coordinates of the chart image into chart coordinates. + * + * @param dataArea The rectangle that contains the data points of the chart. + * @param xRange The x axis range. + * @param yRange The y axis range. + * + * @return a double array as follows: [sx, sy, tx, ty]. + */ + protected static double[] createTransformationMatrix( + Rectangle2D dataArea, + Range xRange, + Range yRange) + { + double offsetX = dataArea.getX(); + double width = dataArea.getWidth() - 1; + double offsetY = dataArea.getY(); + double height = dataArea.getHeight(); + + double lowerX = xRange.getLowerBound(); + double upperX = xRange.getUpperBound(); + double lowerY = yRange.getLowerBound(); + double upperY = yRange.getUpperBound(); + + double dMoveX = upperX - lowerX; + double fMoveX = width * lowerX; + double dMoveY = lowerY - upperY; + double fMoveY = height * upperY; + + AffineTransform t1 = AffineTransform.getTranslateInstance( + offsetX - ( fMoveX / dMoveX ), + offsetY - ( fMoveY / dMoveY ) ); + + AffineTransform t2 = AffineTransform.getScaleInstance( + width / (upperX - lowerX), + height / (lowerY - upperY)); + + t1.concatenate(t2); + + try { + t1.invert(); + + double[] c = new double[6]; + t1.getMatrix(c); + + return new double[] { c[0], c[3], c[4], c[5] }; + } + catch (NoninvertibleTransformException e) { + // do nothing + logger.warn("Matrix is not invertible."); + } + + return new double[] { 1d, 1d, 0d, 0d }; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r d299e220d89c -r bb484489d3df flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionInfoGenerator.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionInfoGenerator.java Wed Jun 01 08:01:07 2011 +0000 @@ -0,0 +1,72 @@ +package de.intevation.flys.exports; + +import java.awt.Color; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.plot.XYPlot; + +/** + * A ChartInfoGenerator that generates meta information for specific + * longitudinal section curves. + * + * @author Ingo Weinzierl + */ +public class LongitudinalSectionInfoGenerator +extends ChartInfoGenerator +{ + private static Logger logger = + Logger.getLogger(LongitudinalSectionInfoGenerator.class); + + + public LongitudinalSectionInfoGenerator() { + super(new LongitudinalSectionGenerator()); + } + + + protected int[] getSize() { + LongitudinalSectionGenerator gen = + (LongitudinalSectionGenerator) generator; + + return gen.getSize(); + } + + + /** + * Creates a chart object. + * + * @return a chart object. + */ + protected JFreeChart generateChart() { + logger.debug("DischargeCurveInfoGenerator.generateChart"); + + LongitudinalSectionGenerator gen = + (LongitudinalSectionGenerator) generator; + + JFreeChart chart = ChartFactory.createXYLineChart( + gen.getChartTitle(), + gen.getXAxisLabel(), + gen.getYAxisLabel(), + null, + PlotOrientation.VERTICAL, + true, + false, + false); + + chart.setBackgroundPaint(Color.WHITE); + chart.getPlot().setBackgroundPaint(Color.WHITE); + + XYPlot plot = (XYPlot) chart.getPlot(); + + gen.addDatasets(chart); + gen.addSubtitles(chart); + gen.adjustPlot(plot); + gen.adjustAxes(plot); + + return chart; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :