Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java @ 1119:7c4f81f74c47
merged gnv-artifacts
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:00 +0200 |
parents | f953c9a559d8 |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java Fri Sep 28 12:14:00 2012 +0200 @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2010 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ + +package de.intevation.gnv.chart; + +import de.intevation.gnv.jfreechart.PolygonDataset; +import de.intevation.gnv.jfreechart.PolygonPlot; +import de.intevation.gnv.jfreechart.PolygonRenderer; +import de.intevation.gnv.jfreechart.PolygonSeries; + +import de.intevation.gnv.math.AttributedXYColumns; + +import de.intevation.gnv.raster.Palette; + +import java.awt.Color; +import java.awt.Paint; + +import java.text.NumberFormat; + +import java.util.HashSet; +import java.util.Locale; +import java.util.Map; + +import org.jfree.chart.JFreeChart; + +import org.jfree.chart.axis.NumberAxis; +import org.jfree.chart.axis.SymbolAxis; +import org.jfree.chart.axis.ValueAxis; + +import org.jfree.chart.plot.PlotOrientation; + +import org.jfree.chart.renderer.LookupPaintScale; + +import org.jfree.chart.title.PaintScaleLegend; +import org.jfree.chart.title.TextTitle; + +import org.jfree.data.Range; + +import org.jfree.ui.RectangleEdge; +import org.jfree.ui.RectangleInsets; + +/** + * This class represents a 2D chart containing polygon data. + * + * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a> + * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> + */ +public class VerticalCrossSectionChart +implements Chart +{ + /** + * Lookup class for retrieving a color which corresponds to a specific + * integer value. + */ + public static final class PalettePaintLookup + implements PolygonRenderer.PaintLookup + { + /** + * Object storing information about value ranges and its coresponding + * colors and descriptions. + */ + private Palette palette; + + /** + * Map containing some special <code>Paint</code> like ground fillcolor. + */ + private Map<Integer, Paint> special; + + /** + * Constructor + * + * @param palette See {@link #palette} + */ + public PalettePaintLookup(Palette palette) { + this(palette, null); + } + + /** + * Constructor + * + * @param palette See {@link #palette} + * @param special See {@link #special} + */ + public PalettePaintLookup( + Palette palette, + Map<Integer, Paint> special + ) { + this.palette = palette; + this.special = special; + } + + /** + * @param index Index of a <code>Paint</code> + * + * @return <code>Paint</code> object for a given index. + */ + public Paint getPaint(int index) { + if (special != null) { + Paint paint = special.get(index); + if (paint != null) { + return paint; + } + } + return index < 0 + ? Color.black + : palette.getColor(index); + } + } // class PalettePaintLookup + + /** + * This class is used to turn labels which represent a number into a + * specific format. + */ + public static class LocalizedLabelGenerator + extends PolygonRenderer.DefaultLabelGenerator + { + /** + * <code>NumberFormat</code> which is used to turn a number into a + * specific format. + */ + protected NumberFormat format; + + /** + * Constructor + */ + public LocalizedLabelGenerator() { + } + + /** + * Constructor + * + * @param format See {@link #format} + */ + public LocalizedLabelGenerator(NumberFormat format) { + this.format = format; + } + + /** + * If label is a <code>Number</code>, it is turned into a format + * specified by {@link #format}. + * + * @param label Label to format. + * + * @return String representation of label. + */ + @Override + protected String toString(Object label) { + return label instanceof Number + ? format.format(((Number)label).doubleValue()) + : super.toString(label); + } + } // class LocalizedLabelGenerator + + public static double MARGIN_TOP = 0.05d; + public static double MARGIN_BOTTOM = 0.00d; + public static double MARGIN_LEFT = 0.00d; + public static double MARGIN_RIGHT = 0.05d; + + /** + * JFreeChart object stored at this place after chart creation. + */ + protected JFreeChart chart; + + /** + * Stores {@link de.intevation.gnv.jfreechart.PolygonDataset} which is used + * to create a vertical cross chart. + */ + protected AttributedXYColumns columns; + + /** + * Map which contains colors to fill polygons draw by this chart. + */ + protected Map<Integer, Paint> special; + + /** + * Object used to map value intervals to specific colors and descriptions. + */ + protected Palette palette; + + /** + * Locale object used for i18n support. + */ + protected Locale locale; + + /** + * Labels for decorating the chart. + */ + protected ChartLabels labels; + + /** + * Default Constructor + */ + public VerticalCrossSectionChart() { + } + + /** + * Constructor for VerticalCrossSectionChart creation. + * + * @param columns See {@link #columns} + * @param palette See {@link #palette} + * @param locale See {@link #locale} + * @param labels See {@link #labels} + */ + public VerticalCrossSectionChart( + AttributedXYColumns columns, + Palette palette, + Locale locale, + ChartLabels labels + ) { + this(columns, palette, null, locale, labels); + } + + /** + * Constructor for VerticalCrossSectionChart creation. + * + * @param columns See {@link #columns} + * @param palette See {@link #palette} + * @param special See {@link #special} + * @param locale See {@link #locale} + * @param labels See {@link #labels} + */ + public VerticalCrossSectionChart( + AttributedXYColumns columns, + Palette palette, + Map<Integer, Paint> special, + Locale locale, + ChartLabels labels + ) { + this.columns = columns; + this.palette = palette; + this.special = special; + this.locale = locale; + this.labels = labels; + } + + /** + * This method is used to create a JFreeChart from this object. A 2D plot is + * drawn and a legend panel is created containing each value range. + * + * @return JFreeChart object + */ + protected JFreeChart createChart() { + + boolean legendB = false; + boolean tooltips = false; + boolean urls = false; + + PlotOrientation po = PlotOrientation.HORIZONTAL; + PolygonDataset data = columns.getPolygonDataset(); + + HashSet<Integer> usedColors = new HashSet<Integer>(); + + for (int i = data.getSeriesCount()-1; i >= 0; --i) { + PolygonSeries ps = data.getSeries(i); + Integer fill = (Integer)ps.getAttribute("fill"); + if (fill != null + && (special != null && !special.containsKey(fill))) { + usedColors.add(fill); + } + } + + NumberFormat format = NumberFormat.getInstance(locale); + format.setMinimumFractionDigits(0); + format.setMaximumFractionDigits(2); + + PolygonRenderer renderer = new PolygonRenderer( + new PalettePaintLookup(palette, special), + new LocalizedLabelGenerator(format)); + + ValueAxis domainAxis = new NumberAxis(this.labels.getDomainAxisLabel()); + ValueAxis rangeAxis = new NumberAxis(this.labels.getRangeAxisLabel()); + + PolygonPlot plot = new PolygonPlot( + data, + renderer, + domainAxis, + rangeAxis, + null); + + plot.setOutlinePaint(Color.WHITE); + + String [] labels = new String[usedColors.size()]; + + int colors = palette.getSize(); + LookupPaintScale lookupPaint = + new LookupPaintScale(-0.5d, labels.length-0.5d, Color.white); + + Color color = null; + + for (int i = 0, j = labels.length-1; i < colors && j >= 0; i++) { + if (usedColors.contains(i)) { + Palette.Entry entry = palette.getEntryByIndex(i); + color = entry.getColor(); + labels[j] = entry.getDescription(); + lookupPaint.add(j-0.5d, color); + --j; + } + } + + JFreeChart chart = new JFreeChart( + this.labels.getTitle(), + JFreeChart.DEFAULT_TITLE_FONT, + plot, + legendB); + + chart.removeLegend(); + chart.addSubtitle(new TextTitle(this.labels.getSubtitle())); + + SymbolAxis scale = new SymbolAxis(this.labels.getParameterName(), labels); + scale.setRange(-1.5d, labels.length+0.5d); + scale.setGridBandsVisible(false); + scale.setPlot(plot); + + PaintScaleLegend legend = new PaintScaleLegend( + lookupPaint, scale); + legend.setMargin(new RectangleInsets(3d, 10d, 3d, 10d)); + legend.setPosition(RectangleEdge.LEFT); + legend.setAxisOffset(5d); + + chart.addSubtitle(legend); + + // XXX Workaround, because Axes labels are cut at the + // left/right/top/bottom edge. The following lines add a white border + // between data area and plot border. + // see http://www.jfree.org/phpBB2/viewtopic.php?f=3&t=22177&start=0&hilit=axis+labels+cut + ValueAxis xAxis = plot.getDomainAxis(); + Range xRange = xAxis.getRange(); + xRange = Range.expand(xRange, MARGIN_LEFT, MARGIN_RIGHT); + xAxis.setRange(xRange); + plot.setDomainAxis(xAxis); + + ValueAxis yAxis = plot.getRangeAxis(); + Range yRange = yAxis.getRange(); + yRange = Range.expand(yRange, MARGIN_BOTTOM, MARGIN_TOP); + yAxis.setRange(yRange); + plot.setRangeAxis(yAxis); + + chart.setPadding(new RectangleInsets(10d, 10d, 10d, 10d)); + + return chart; + } + + /** + * @see de.intevation.gnv.chart.Chart#generateChart() + */ + public JFreeChart generateChart() { + if (chart == null) { + chart = createChart(); + } + + return chart; + } + + /** + * Set the background paint of {@link #chart}. + * @param paint + */ + public void setBackgroundPaint(Paint paint) { + chart.setBackgroundPaint(paint); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :