Mercurial > dive4elements > gnv-client
view 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 source
/* * 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 :