# HG changeset patch # User Sascha L. Teichmann # Date 1321136787 0 # Node ID eb671699fbc27629b682f392ca0cb38bce67e6bb # Parent d67a9ca116c38804223e4e6fd0a52683f4007d95 CrossSectionApp: Draw water, too. flys-artifacts/trunk@3242 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r d67a9ca116c3 -r eb671699fbc2 flys-artifacts/ChangeLog --- a/flys-artifacts/ChangeLog Sat Nov 12 12:07:39 2011 +0000 +++ b/flys-artifacts/ChangeLog Sat Nov 12 22:26:27 2011 +0000 @@ -1,3 +1,11 @@ +2011-11-12 Sascha L. Teichmann + + * src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java: + Draw water, too. + + * src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java: + First code to split datasets by NaNs. WIP. + 2011-11-12 Sascha L. Teichmann * src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java: diff -r d67a9ca116c3 -r eb671699fbc2 flys-artifacts/src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java --- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java Sat Nov 12 12:07:39 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java Sat Nov 12 22:26:27 2011 +0000 @@ -22,6 +22,7 @@ import java.awt.event.ItemListener; import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; import java.io.File; import java.io.FileWriter; @@ -36,6 +37,12 @@ import java.util.Map; import java.util.TreeMap; +import java.awt.Color; +import java.awt.Paint; +import java.awt.TexturePaint; + +import java.awt.image.BufferedImage; + import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; @@ -91,9 +98,12 @@ protected boolean [] drawCrossSection; protected boolean [] drawWaterLevel; protected boolean [] drawGround; + protected boolean [] drawFill; protected Map>> km2lines; + protected static final Paint TRANSPARENT = createTransparentPaint(); + public class CrossSectionTableModel extends AbstractTableModel { @Override @@ -103,13 +113,14 @@ case 1: return "Peilung"; case 2: return "Wasserstand"; case 3: return "Boden"; + case 4: return "Wasser"; } return ""; } @Override public int getColumnCount() { - return 4; + return 5; } @Override @@ -125,6 +136,7 @@ case 1: return drawCrossSection[row]; case 2: return drawWaterLevel[row]; case 3: return drawGround[row]; + case 4: return drawFill[row]; } return null; } @@ -147,6 +159,11 @@ fireTableCellUpdated(row, col); } break; + case 4: + if (change(drawFill, row, (Boolean)value)) { + fireTableCellUpdated(row, col); + } + break; } } @@ -157,6 +174,7 @@ case 1: return Boolean.class; case 2: return Boolean.class; case 3: return Boolean.class; + case 4: return Boolean.class; } return null; } @@ -166,7 +184,7 @@ int rowIndex, int columnIndex ) { - return columnIndex >= 1 && columnIndex <= 3; + return columnIndex >= 1 && columnIndex <= 4; } } // class CrossSectionTableModel @@ -248,11 +266,12 @@ crossSections = crossSections(RIVER); km2lines = loadAllLines(crossSections); - drawCrossSection = new boolean[crossSections.size()]; - Arrays.fill(drawCrossSection, true); - drawWaterLevel = new boolean[crossSections.size()]; - drawGround = new boolean[crossSections.size()]; + int CS = crossSections.size(); + Arrays.fill(drawCrossSection = new boolean[CS], true); + drawWaterLevel = new boolean[CS]; + drawGround = new boolean[CS]; + drawFill = new boolean[CS]; Object [] clis = createCrossSectionLineItems(km2lines); @@ -427,6 +446,29 @@ new XYSeriesCollection(series), null)); } + public void generateFill( + List points, + String legend, + List> datasets + ) { + if (points == null || points.isEmpty() || lastWaterLevel == null) { + return; + } + + double [][] data = Lines.createWaterLines(points, lastWaterLevel); + double [][] values = CrossSectionLine.fetchCrossSectionProfile(points); + + DefaultXYDataset dataset = new DefaultXYDataset(); + + dataset.addSeries(legend + "-Linie", values); + dataset.addSeries(legend + "-Fl\u00e4che", data); + + datasets.add(new Pair( + dataset, + new StableXYDifferenceRenderer( + TRANSPARENT, Color.blue, false))); + } + public void generateProfile( List points, String legend, @@ -462,6 +504,9 @@ double [][] values = CrossSectionLine.fetchCrossSectionProfile(points); DefaultXYDataset dataset = new DefaultXYDataset(); + + XYSeries series = new XYSeries(legend, false); + dataset.addSeries(legend, values); StableXYDifferenceRenderer renderer = @@ -483,10 +528,26 @@ List points = null; CrossSection cs = crossSections.get(i); + if (drawFill[i]) { + for (Pair csl: csli.lines) { + if (csl.getA() == cs) { + if (points == null) { + points = csl.getB().fetchCrossSectionLinesPoints(); + } + + generateFill( + points, cs.getDescription(), datasets); + break; + } + } + } + if (drawCrossSection[i]) { for (Pair csl: csli.lines) { if (csl.getA() == cs) { - points = csl.getB().fetchCrossSectionLinesPoints(); + if (points == null) { + points = csl.getB().fetchCrossSectionLinesPoints(); + } generateProfile( points, cs.getDescription(), datasets); @@ -498,7 +559,7 @@ if (drawWaterLevel[i]) { for (Pair csl: csli.lines) { if (csl.getA() == cs) { - if (points != null) { + if (points == null) { points = csl.getB().fetchCrossSectionLinesPoints(); } generateWaterLevels(points, datasets); @@ -510,7 +571,7 @@ if (drawGround[i]) { for (Pair csl: csli.lines) { if (csl.getA() == cs) { - if (points != null) { + if (points == null) { points = csl.getB().fetchCrossSectionLinesPoints(); } generateGround( @@ -574,6 +635,14 @@ return chart; } + protected static Paint createTransparentPaint() { + BufferedImage texture = new BufferedImage( + 1, 1, BufferedImage.TYPE_4BYTE_ABGR); + + return new TexturePaint( + texture, new Rectangle2D.Double(0d, 0d, 0d, 0d)); + } + public static void main(String [] args) { CrossSectionApp csa = new CrossSectionApp("Querprofile"); csa.pack(); diff -r d67a9ca116c3 -r eb671699fbc2 flys-artifacts/src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java --- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java Sat Nov 12 12:07:39 2011 +0000 +++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/StableXYDifferenceRenderer.java Sat Nov 12 22:26:27 2011 +0000 @@ -86,8 +86,10 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; +import java.util.List; import org.jfree.chart.LegendItem; import org.jfree.chart.axis.ValueAxis; @@ -101,6 +103,7 @@ import org.jfree.chart.plot.XYPlot; import org.jfree.chart.urls.XYURLGenerator; import org.jfree.data.xy.XYDataset; +import org.jfree.data.xy.DefaultXYDataset; import org.jfree.io.SerialUtilities; import org.jfree.ui.RectangleEdge; import org.jfree.util.PaintUtilities; @@ -111,6 +114,8 @@ import org.jfree.chart.renderer.xy.XYItemRenderer; import org.jfree.chart.renderer.xy.XYItemRendererState; +import gnu.trove.TDoubleArrayList; + /** * A renderer for an {@link XYPlot} that highlights the differences between two * series. The example shown here is generated by the @@ -359,6 +364,56 @@ return 2; } + public static List splitByNaNs(XYDataset dataset) { + List datasets = new ArrayList(); + + switch (dataset.getSeriesCount()) { + case 0: + return datasets; + case 1: + int N = dataset.getItemCount(0); + TDoubleArrayList xs = new TDoubleArrayList(N); + TDoubleArrayList ys = new TDoubleArrayList(N); + for (int i = 0; i < N; ++i) { + double x = dataset.getXValue(0, i); + double y = dataset.getYValue(0, i); + if (Double.isNaN(x) || Double.isNaN(y)) { + if (!xs.isEmpty()) { + DefaultXYDataset ds = new DefaultXYDataset(); + datasets.add(ds); + ds.addSeries( + dataset.getSeriesKey(0), + new double [][] { + xs.toNativeArray(), + ys.toNativeArray() }); + xs.reset(); + ys.reset(); + } + } + else { + xs.add(x); + ys.add(y); + } + } + if (!xs.isEmpty()) { + DefaultXYDataset ds = new DefaultXYDataset(); + datasets.add(ds); + ds.addSeries( + dataset.getSeriesKey(0), + new double [][] { + xs.toNativeArray(), + ys.toNativeArray() }); + } + break; + default: // two or more + // TODO: split two parts + datasets.add(dataset); + break; + } + + return datasets; + } + /** * Draws the visual representation of a single data item. * @@ -391,9 +446,11 @@ int pass) { switch (pass) { case 0: - drawItemPass0(g2, dataArea, info, - plot, domainAxis, rangeAxis, - dataset, series, item, crosshairState); + for (XYDataset ds: splitByNaNs(dataset)) { + drawItemPass0(g2, dataArea, info, + plot, domainAxis, rangeAxis, + dataset, series, item, crosshairState); + } break; case 1: drawItemPass1(g2, dataArea, info,