sascha@3162: package de.intevation.flys.artifacts.services; sascha@3162: sascha@3162: import de.intevation.flys.artifacts.model.fixings.QW; sascha@3162: sascha@3162: import de.intevation.flys.java2d.ShapeUtils; sascha@3162: sascha@3162: import de.intevation.flys.jfree.ShapeRenderer; sascha@3162: sascha@3162: import java.awt.BasicStroke; sascha@3162: import java.awt.Color; sascha@3162: import java.awt.Paint; sascha@3162: import java.awt.Shape; sascha@3162: sascha@3162: import java.awt.geom.Rectangle2D; sascha@3162: sascha@3162: import java.text.DateFormat; sascha@3162: import java.text.SimpleDateFormat; sascha@3162: sascha@3162: import java.util.ArrayList; sascha@3162: import java.util.Date; sascha@3162: import java.util.HashMap; sascha@3162: import java.util.List; sascha@3162: import java.util.Map; sascha@3162: sascha@3162: import org.jfree.chart.LegendItem; sascha@3162: import org.jfree.chart.LegendItemCollection; sascha@3162: sascha@3162: import org.jfree.chart.labels.XYItemLabelGenerator; sascha@3162: sascha@3162: import org.jfree.chart.renderer.xy.StandardXYItemRenderer; sascha@3162: sascha@3162: import org.jfree.data.xy.XYDataset; sascha@3162: import org.jfree.data.xy.XYSeries; sascha@3162: import org.jfree.data.xy.XYSeriesCollection; sascha@3162: sascha@3162: public class QWSeriesCollection sascha@3162: extends XYSeriesCollection sascha@3162: implements XYItemLabelGenerator sascha@3162: { sascha@3162: public interface LabelGenerator { sascha@3162: String createLabel(QW qw); sascha@3162: } // interface LabelGenerator sascha@3162: sascha@3162: public static class DateFormatLabelGenerator sascha@3162: implements LabelGenerator sascha@3162: { sascha@3162: protected DateFormat format; sascha@3162: sascha@3162: public DateFormatLabelGenerator() { sascha@3162: this(new SimpleDateFormat("dd.MM.yyyy")); sascha@3162: } sascha@3162: sascha@3162: public DateFormatLabelGenerator(DateFormat format) { sascha@3162: this.format = format; sascha@3162: } sascha@3162: sascha@3162: @Override sascha@3162: public String createLabel(QW qw) { sascha@3162: Date date = qw.getDate(); sascha@3162: return date != null ? format.format(date) : ""; sascha@3162: } sascha@3162: } // class DateFormatLabelGenerator sascha@3162: sascha@3162: public static final LabelGenerator SIMPLE_GENERATOR = sascha@3162: new DateFormatLabelGenerator(); sascha@3162: sascha@3162: protected Date minDate; sascha@3162: protected Date maxDate; sascha@3162: sascha@3162: protected List> labels; sascha@3162: sascha@3162: protected Rectangle2D area; sascha@3162: sascha@3162: protected LabelGenerator labelGenerator; sascha@3162: sascha@3162: protected Map knownShapes = sascha@3162: new HashMap(); sascha@3162: sascha@3162: public QWSeriesCollection() { sascha@3162: labels = new ArrayList>(); sascha@3162: labelGenerator = SIMPLE_GENERATOR; sascha@3162: } sascha@3162: sascha@3162: public QWSeriesCollection(LabelGenerator labelGenerator) { sascha@3162: this(); sascha@3162: this.labelGenerator = labelGenerator; sascha@3162: } sascha@3162: sascha@3162: protected static ShapeRenderer.Entry classify(QW qw) { sascha@3164: boolean interpolated = qw.getInterpolated(); sascha@3164: sascha@3164: Shape shape = interpolated sascha@3162: ? ShapeUtils.INTERPOLATED_SHAPE sascha@3162: : ShapeUtils.MEASURED_SHAPE; sascha@3162: sascha@3164: boolean filled = !interpolated; sascha@3164: Color color = interpolated sascha@3164: ? Color.green sascha@3164: : Color.blue; sascha@3162: sascha@3164: return new ShapeRenderer.Entry(shape, color, filled); sascha@3162: } sascha@3162: sascha@3162: public void add(QW qw) { sascha@3162: sascha@3162: ShapeRenderer.Entry key = classify(qw); sascha@3162: sascha@3162: Integer seriesNo = knownShapes.get(key); sascha@3162: sascha@3162: XYSeries series; sascha@3162: sascha@3162: if (seriesNo == null) { sascha@3162: seriesNo = Integer.valueOf(getSeriesCount()); sascha@3162: knownShapes.put(key, seriesNo); sascha@3162: series = new XYSeries(seriesNo, false); sascha@3162: addSeries(series); sascha@3162: labels.add(new ArrayList()); sascha@3162: } sascha@3162: else { sascha@3162: series = getSeries(seriesNo); sascha@3162: } sascha@3162: sascha@3162: series.add(qw.getQ(), qw.getW()); sascha@3162: sascha@3162: labels.get(seriesNo).add(qw); sascha@3162: sascha@3162: extendDateRange(qw); sascha@3162: extendArea(qw); sascha@3162: } sascha@3162: sascha@3162: protected void extendDateRange(QW qw) { sascha@3162: Date date = qw.getDate(); sascha@3162: if (date != null) { sascha@3162: if (minDate == null) { sascha@3162: minDate = maxDate = date; sascha@3162: } sascha@3162: else { sascha@3162: if (date.compareTo(minDate) < 0) { sascha@3162: minDate = date; sascha@3162: } sascha@3162: if (date.compareTo(maxDate) > 0) { sascha@3162: maxDate = date; sascha@3162: } sascha@3162: } sascha@3162: } sascha@3162: } sascha@3162: sascha@3162: protected void extendArea(QW qw) { sascha@3162: if (area == null) { sascha@3162: area = new Rectangle2D.Double( sascha@3162: qw.getQ(), qw.getW(), 0d, 0d); sascha@3162: } sascha@3162: else { sascha@3162: area.add(qw.getQ(), qw.getW()); sascha@3162: } sascha@3162: } sascha@3162: sascha@3162: public Rectangle2D getArea() { sascha@3162: return area; sascha@3162: } sascha@3162: sascha@3162: public Date getMinDate() { sascha@3162: return minDate; sascha@3162: } sascha@3162: sascha@3162: public Date getMaxDate() { sascha@3162: return maxDate; sascha@3162: } sascha@3162: sascha@3162: public LabelGenerator getLabelGenerator() { sascha@3162: return labelGenerator; sascha@3162: } sascha@3162: sascha@3162: @Override sascha@3162: public String generateLabel(XYDataset dataset, int series, int item) { sascha@3162: return labelGenerator.createLabel(labels.get(series).get(item)); sascha@3162: } sascha@3162: sascha@3162: public StandardXYItemRenderer createRenderer() { sascha@3162: StandardXYItemRenderer renderer = new ShapeRenderer(knownShapes); sascha@3162: renderer.setBaseItemLabelGenerator(this); sascha@3162: renderer.setBaseSeriesVisibleInLegend(false); sascha@3162: renderer.setBaseItemLabelsVisible(true); sascha@3162: return renderer; sascha@3162: } sascha@3162: sascha@3162: public static final LegendItem legendItem( sascha@3162: String label, sascha@3162: Paint paint, sascha@3162: Shape shape, sascha@3162: boolean filled sascha@3162: ) { sascha@3162: BasicStroke stroke = new BasicStroke(); sascha@3162: return new LegendItem( sascha@3162: label, // label sascha@3162: null, // description sascha@3162: null, // tooltip sascha@3162: null, // url sascha@3162: true, // shape visible sascha@3162: shape, // shape sascha@3162: filled, // shape filled sascha@3162: filled ? paint : Color.white, // fill paint sascha@3162: true, // shape outline sascha@3162: paint, // outline paint sascha@3162: stroke, // outline stroke sascha@3162: false, // line visible sascha@3162: shape, // line sascha@3162: stroke, // line stroke sascha@3162: Color.white); sascha@3162: } sascha@3162: sascha@3162: public void addLegendItems(LegendItemCollection lic) { sascha@3162: for (ShapeRenderer.Entry entry: knownShapes.keySet()) { sascha@3162: // TODO: i18n sascha@3162: String label = entry.getFilled() sascha@3162: ? "gemessene Werte" sascha@3162: : "interpolierte Werte"; sascha@3162: lic.add(legendItem( sascha@3162: label, sascha@3162: entry.getPaint(), sascha@3162: entry.getShape(), sascha@3162: entry.getFilled())); sascha@3162: } sascha@3162: } sascha@3162: } sascha@3162: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :