teichmann@5831: package org.dive4elements.river.artifacts.services; sascha@3162: teichmann@5831: import org.dive4elements.river.artifacts.model.fixings.QWI; sascha@3162: teichmann@5831: import org.dive4elements.river.java2d.ShapeUtils; sascha@3162: teichmann@5831: import org.dive4elements.river.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@3729: String createLabel(QWI 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@3170: this("dd.MM.yyyy"); sascha@3170: } sascha@3170: sascha@3170: public DateFormatLabelGenerator(String format) { sascha@3170: this(new SimpleDateFormat(format)); sascha@3162: } sascha@3162: sascha@3162: public DateFormatLabelGenerator(DateFormat format) { sascha@3162: this.format = format; sascha@3162: } sascha@3162: sascha@3162: @Override sascha@3729: public String createLabel(QWI 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@3729: 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@3729: 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@3729: protected static ShapeRenderer.Entry classify(QWI 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@3403: Color color = Color.blue; sascha@3162: sascha@3164: return new ShapeRenderer.Entry(shape, color, filled); sascha@3162: } sascha@3162: sascha@3729: public void add(QWI 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@3729: 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@3729: protected void extendDateRange(QWI 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@3729: protected void extendArea(QWI 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@3173: public void addLegendItems( sascha@3173: LegendItemCollection lic, sascha@3173: ShapeRenderer.LabelGenerator lg sascha@3173: ) { sascha@3162: for (ShapeRenderer.Entry entry: knownShapes.keySet()) { sascha@3162: lic.add(legendItem( sascha@3173: lg.createLabel(entry), 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 :