[PATCH] Area chart layers may now have an 'arebgpattern'. Real pattern yet to be defined
Wald Commits
scm-commit at wald.intevation.org
Thu Feb 22 18:46:42 CET 2018
# HG changeset patch
# User gernotbelger
# Date 1519321597 -3600
# Node ID d9c89651bd6780feb3cbc0f1c0e3b0e505032d31
# Parent 31dff17c68287f0fd1182f8ec96dd3a3c44bae7e
Area chart layers may now have an 'arebgpattern'. Real pattern yet to be defined.
diff -r 31dff17c6828 -r d9c89651bd67 artifacts/src/main/java/org/dive4elements/river/jfree/AreaFillPattern.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/AreaFillPattern.java Thu Feb 22 18:46:37 2018 +0100
@@ -0,0 +1,75 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.jfree;
+
+import java.awt.Color;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.LookupOp;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Fill patterns for area styles.
+ * REMARK: if this enum is changed, probably the ui in StyleEditorWindow must be changed too
+ *
+ * @author Gernot Belger
+ */
+public enum AreaFillPattern {
+
+ pattern1("/images/areapatterns/pattern1.png");
+
+ private static Logger log = Logger.getLogger(AreaFillPattern.class);
+
+ private static final BufferedImage MISSING_IMAGE = new BufferedImage(16, 16, BufferedImage.TYPE_INT_RGB);
+
+ private final String imagePath;
+
+ private BufferedImage image = null;
+
+ AreaFillPattern(final String imagePath) {
+ this.imagePath = imagePath;
+ }
+
+ public BufferedImage getImage(final Color color) {
+
+ if (this.image == null)
+ this.image = loadImage();
+
+ if (color == null)
+ return this.image;
+
+ /*
+ * apply color and transparency, the .png must be encoded as 32bit images (rgba), with only black as non transparent
+ * color
+ */
+ final int numComponents = this.image.getColorModel().getNumComponents();
+ if (numComponents != 4) {
+ log.warn(String.format("Pattern image must be a 32bit image (rgba): %s", this.imagePath));
+ return this.image;
+ }
+
+ final BufferedImageOp lookup = new LookupOp(new ColorMapper(Color.black, color), null);
+ return lookup.filter(this.image, null);
+ }
+
+ private BufferedImage loadImage() {
+ try {
+ return ImageIO.read(getClass().getResource(this.imagePath));
+ }
+ catch (final IOException e) {
+ log.error(String.format("failed ot load pattern: %s", this.imagePath), e);
+ return MISSING_IMAGE;
+ }
+ }
+}
\ No newline at end of file
diff -r 31dff17c6828 -r d9c89651bd67 artifacts/src/main/java/org/dive4elements/river/jfree/ColorMapper.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/ColorMapper.java Thu Feb 22 18:46:37 2018 +0100
@@ -0,0 +1,43 @@
+/** Copyright (C) 2017 by Bundesanstalt für Gewässerkunde
+ * Software engineering by
+ * Björnsen Beratende Ingenieure GmbH
+ * Dr. Schumacher Ingenieurbüro für Wasser und Umwelt
+ *
+ * This file is Free Software under the GNU AGPL (>=v3)
+ * and comes with ABSOLUTELY NO WARRANTY! Check out the
+ * documentation coming with Dive4Elements River for details.
+ */
+package org.dive4elements.river.jfree;
+
+import java.awt.Color;
+import java.awt.image.LookupTable;
+
+final class ColorMapper extends LookupTable {
+
+ private final int[] from;
+ private final int[] to;
+
+ public ColorMapper(final Color from, final Color to) {
+ super(0, 4);
+
+ this.from = new int[] { from.getRed(), from.getGreen(), from.getBlue(), from.getAlpha(), };
+ this.to = new int[] { to.getRed(), to.getGreen(), to.getBlue(), to.getAlpha(), };
+ }
+
+ @Override
+ public int[] lookupPixel(final int[] src, final int[] dest) {
+ final int[] out = dest == null ? new int[src.length] : dest;
+
+ // REMARK: only compare rgb, so we even keep the transparency level
+ if (src[0] == this.from[0] && src[1] == this.from[1] && src[2] == this.from[2]) {
+ out[0] = this.to[0];
+ out[1] = this.to[1];
+ out[2] = this.to[2];
+ out[2] = src[3];
+ } else {
+ System.arraycopy(src, 0, out, 0, src.length);
+ }
+
+ return out;
+ }
+}
\ No newline at end of file
diff -r 31dff17c6828 -r d9c89651bd67 artifacts/src/main/java/org/dive4elements/river/jfree/StableXYDifferenceRenderer.java
--- a/artifacts/src/main/java/org/dive4elements/river/jfree/StableXYDifferenceRenderer.java Thu Feb 22 18:44:28 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/StableXYDifferenceRenderer.java Thu Feb 22 18:46:37 2018 +0100
@@ -407,9 +407,6 @@
* @see #getPositivePaint()
*/
public void setPositivePaint(Paint paint) {
- if (paint == null) {
- throw new IllegalArgumentException("Null 'paint' argument.");
- }
this.positivePaint = paint;
fireChangeEvent();
}
@@ -433,9 +430,6 @@
* @see #getNegativePaint()
*/
public void setNegativePaint(Paint paint) {
- if (paint == null) {
- throw new IllegalArgumentException("Null 'paint' argument.");
- }
this.negativePaint = paint;
notifyListeners(new RendererChangeEvent(this));
}
@@ -1774,9 +1768,13 @@
}
if (l_path.intersects(x_dataArea)) {
- x_graphics.setPaint(x_positive ? getPositivePaint()
- : getNegativePaint());
+
+ final Paint paint = x_positive ? getPositivePaint(): getNegativePaint();
+ if( paint != null ) {
+ x_graphics.setPaint(paint);
x_graphics.fill(l_path);
+ }
+
if (drawOutline) {
x_graphics.setStroke(this.outlineStroke);
x_graphics.setPaint(this.outlinePaint);
diff -r 31dff17c6828 -r d9c89651bd67 artifacts/src/main/java/org/dive4elements/river/jfree/StyledAreaSeriesCollection.java
--- a/artifacts/src/main/java/org/dive4elements/river/jfree/StyledAreaSeriesCollection.java Thu Feb 22 18:44:28 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/jfree/StyledAreaSeriesCollection.java Thu Feb 22 18:46:37 2018 +0100
@@ -10,7 +10,12 @@
import java.awt.BasicStroke;
import java.awt.Color;
+import java.awt.Paint;
import java.awt.Stroke;
+import java.awt.TexturePaint;
+import java.awt.geom.Ellipse2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
import org.jfree.data.xy.XYSeriesCollection;
@@ -23,6 +28,7 @@
* The display options can be used to control the z-order and the axis of the
* dataset.
*/
+// FIXME: bad abstraction: the only purpose of this derivation is to apply specific styles. This should rather be solved similar to the XYSTyle.
public class StyledAreaSeriesCollection extends XYSeriesCollection {
private static final long serialVersionUID = 5274940965666948237L;
@@ -71,6 +77,7 @@
applyOutlineStyle(renderer);
applyShowLine(renderer);
applyShowAreaLabel(renderer);
+ applyPointStyle(renderer);
if (mode == FILL_MODE.UNDER) {
renderer.setAreaCalculationMode(
StableXYDifferenceRenderer.CALCULATE_NEGATIVE_AREA);
@@ -89,19 +96,17 @@
return renderer;
}
-
- private void applyFillColor(StableXYDifferenceRenderer renderer) {
- Color paint = theme.parseAreaBackgroundColor();
-
- int transparency = theme.parseAreaTransparency();
- if (transparency > 0 && paint != null) {
- paint = new Color(
- paint.getRed(),
- paint.getGreen(),
- paint.getBlue(),
- (int)((100 - transparency) * 2.55f));
+ private void applyFillColor(final StableXYDifferenceRenderer renderer) {
+
+ final boolean showArea = theme.parseShowArea();
+ if( !showArea ) {
+ renderer.setPositivePaint(null);
+ renderer.setNegativePaint(null);
+ return;
}
+ Paint paint = parseFillPaint();
+
if (paint != null && this.getMode() == FILL_MODE.ABOVE) {
renderer.setPositivePaint(paint);
renderer.setNegativePaint(new Color(0,0,0,0));
@@ -113,11 +118,40 @@
else {
if (paint == null)
paint = new Color(177, 117, 102);
+
renderer.setPositivePaint(paint);
renderer.setNegativePaint(paint);
}
}
+ private Paint parseFillPaint() {
+ final Color paint = this.theme.parseAreaBackgroundColor();
+ final int transparency = theme.parseAreaTransparency();
+
+ final Color alphaPaint = withAlpha(paint, transparency);
+
+ final AreaFillPattern pattern = this.theme.parseAreaBackgroundPattern();
+
+ if( pattern == null )
+ return alphaPaint;
+
+ final BufferedImage image = pattern.getImage(alphaPaint);
+
+ final Rectangle2D anchor = new Rectangle2D.Double(0,0, image.getWidth(), image.getHeight());
+ return new TexturePaint(image, anchor);
+ }
+
+ private Color withAlpha(final Color color, final int transparency) {
+
+ if (transparency <= 0 || color == null)
+ return color;
+
+ return new Color(
+ color.getRed(),
+ color.getGreen(),
+ color.getBlue(),
+ (int)((100 - transparency) * 2.55f));
+ }
private void applyShowShape(StableXYDifferenceRenderer renderer) {
boolean show = theme.parseAreaShowBorder();
@@ -126,7 +160,9 @@
private void applyShowLine(StableXYDifferenceRenderer renderer) {
- boolean show = theme.parseShowLine();
+ /* FIXME: strange: this will enable/disable showing the 'point' shapes at each vertex. */
+ /* FIXME: this will also now be overridden by the option 'showpoints' */
+ final boolean show = theme.parseShowLine();
renderer.setShapesVisible(show);
}
@@ -161,6 +197,27 @@
renderer.setOutlineStroke(stroke);
}
+ private void applyPointStyle(final StableXYDifferenceRenderer renderer) {
+
+ final boolean showPoints = this.theme.parseShowPoints();
+ renderer.setShapesVisible(showPoints);
+
+ if( showPoints )
+ {
+ final int size = theme.parsePointWidth();
+ final int dim = 2 * size;
+
+ final Ellipse2D pointShape = new Ellipse2D.Double(-size, -size, dim, dim);
+ final Color pointColor = theme.parsePointColor();
+
+ renderer.setSeriesPaint(0, pointColor);
+ renderer.setSeriesPaint(1, pointColor);
+
+ renderer.setSeriesShape(0, pointShape);
+ renderer.setSeriesShape(1, pointShape);
+ }
+ }
+
public boolean shouldCalculateRange() {
return theme.parseCalculateRange();
}
diff -r 31dff17c6828 -r d9c89651bd67 artifacts/src/main/java/org/dive4elements/river/themes/ThemeDocument.java
--- a/artifacts/src/main/java/org/dive4elements/river/themes/ThemeDocument.java Thu Feb 22 18:44:28 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/themes/ThemeDocument.java Thu Feb 22 18:46:37 2018 +0100
@@ -13,6 +13,7 @@
import java.util.HashMap;
import java.util.Map;
+import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.dive4elements.artifacts.CallMeta;
import org.dive4elements.river.artifacts.model.MapserverStyle;
@@ -21,6 +22,7 @@
import org.dive4elements.river.artifacts.model.MapserverStyle.Label;
import org.dive4elements.river.artifacts.model.MapserverStyle.Style;
import org.dive4elements.river.artifacts.resources.Resources;
+import org.dive4elements.river.jfree.AreaFillPattern;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
@@ -102,6 +104,8 @@
public final static String AREA_BACKGROUND_COLOR = "areabgcolor";
+ private static final String AREA_BACKGROUND_PATTERN = "areabgpattern";
+
public final static String SYMBOL = "symbol";
public final static String SHOW_MINIMUM = "showminimum";
@@ -825,5 +829,19 @@
private String getCalculateRangeString() {
return getValue(CALCULATE_RANGE);
}
+
+ public AreaFillPattern parseAreaBackgroundPattern() {
+ final String patternName = getValue(AREA_BACKGROUND_PATTERN);
+ if( StringUtils.isBlank(patternName) )
+ return null;
+
+ try {
+ return AreaFillPattern.valueOf(patternName);
+ }
+ catch (Exception e) {
+ log.error(String.format("%s: invalid pattern name: %s", AREA_BACKGROUND_PATTERN, patternName), e);
+ return null;
+ }
+ }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
diff -r 31dff17c6828 -r d9c89651bd67 artifacts/src/main/resources/images/areapatterns/pattern1.png
Binary file artifacts/src/main/resources/images/areapatterns/pattern1.png has changed
diff -r 31dff17c6828 -r d9c89651bd67 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Thu Feb 22 18:44:28 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.java Thu Feb 22 18:46:37 2018 +0100
@@ -1178,6 +1178,8 @@
String areabgcolor();
+ String areabgpattern();
+
String areashowborder();
String areashowbg();
@@ -1423,13 +1425,17 @@
String error_no_sedimentloadinfo_data();
String sinfo();
-
+
String sinfo_flowdepth_export();
String sinfo_flowdepth_report();
String sinfo_flow_depth();
- String sinfo_flowdepth_twinpanel_no_pair_selected();
+ String sinfo_flowdepth_twinpanel_no_pair_selected();
+
+ String sinfo_flow_depths();
+
+ String sinfo_tkhs();
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
\ No newline at end of file
diff -r 31dff17c6828 -r d9c89651bd67 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Thu Feb 22 18:44:28 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants.properties Thu Feb 22 18:46:37 2018 +0100
@@ -636,6 +636,7 @@
showmiddleheight = Show middle depth
fillcolor = Fill Color
areabgcolor = Fill Color
+areabgpattern = Fill Pattern
areashowborder = Show area border
areashowbg = Show area background
areabordercolor = Border color
@@ -761,4 +762,6 @@
sinfo_flowdepth_export = Flie\u00dftiefen Export
sinfo_flowdepth_report = Flie\u00dftiefen Bericht
sinfo_flow_depth = Flie\u00dftiefen
-sinfo_flowdepth_twinpanel_no_pair_selected = Error - at least one input pair must be selected
\ No newline at end of file
+sinfo_flowdepth_twinpanel_no_pair_selected = Error - at least one input pair must be selected
+sinfo_flow_depths = Flie\u00dftiefen
+sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file
diff -r 31dff17c6828 -r d9c89651bd67 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Thu Feb 22 18:44:28 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_de.properties Thu Feb 22 18:46:37 2018 +0100
@@ -635,11 +635,12 @@
showborder = Linie anzeigen
transparent = Transparent
transparency = Transparenz
-showarea = Show area
+showarea = Fl\u00e4che anzeigen
showarealabel = Fl\u00e4che beschriften
showmiddleheight = Mittlere Tiefe anzeigen
fillcolor = F\u00fcllfarbe
areabgcolor = F\u00fcllfarbe
+areabgpattern = Fl\u00e4chentyp
areashowborder = Fl\u00e4chenumrandung
areashowbg = Fl\u00e4chenhintergrund
areabordercolor = Umrandungsfarbe
@@ -753,4 +754,6 @@
sinfo_flowdepth_export = Flie\u00dftiefen Export
sinfo_flowdepth_report = Flie\u00dftiefen Bericht
sinfo_flow_depth = Flie\u00dftiefen
-sinfo_flowdepth_twinpanel_no_pair_selected = Fehler - kein Paar zur Differenzenbildung gew\u00e4hlt.
\ No newline at end of file
+sinfo_flowdepth_twinpanel_no_pair_selected = Fehler - kein Paar zur Differenzenbildung gew\u00e4hlt.
+sinfo_flow_depths = Flie\u00dftiefen
+sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file
diff -r 31dff17c6828 -r d9c89651bd67 gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties Thu Feb 22 18:44:28 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/FLYSConstants_en.properties Thu Feb 22 18:46:37 2018 +0100
@@ -615,6 +615,7 @@
showmiddleheight = Show middle depth
fillcolor = Fill Color
areabgcolor = Fill Color
+areabgpattern = Fill Pattern
areashowborder = Show area border
areashowbg = Show area background
areabordercolor = Border color
@@ -790,4 +791,6 @@
sinfo_flowdepth_export = Flie\u00dftiefen Export
sinfo_flowdepth_report = Flie\u00dftiefen Bericht
sinfo_flow_depth = Flie\u00dftiefen
-sinfo_flowdepth_twinpanel_no_pair_selected = Error - at least one input pair must be selected
\ No newline at end of file
+sinfo_flowdepth_twinpanel_no_pair_selected = Error - at least one input pair must be selected
+sinfo_flow_depths = Flie\u00dftiefen
+sinfo_tkhs = Transportk\u00f6rperh\u00f6hen
\ No newline at end of file
diff -r 31dff17c6828 -r d9c89651bd67 gwt-client/src/main/java/org/dive4elements/river/client/client/ui/StyleEditorWindow.java
--- a/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/StyleEditorWindow.java Thu Feb 22 18:44:28 2018 +0100
+++ b/gwt-client/src/main/java/org/dive4elements/river/client/client/ui/StyleEditorWindow.java Thu Feb 22 18:46:37 2018 +0100
@@ -294,6 +294,7 @@
// Done via array to keep the order.
String[] sets = {"showlines",
+ "showborder",
"showpoints",
"linetype",
"linesize",
@@ -372,6 +373,7 @@
* @return The dynamic form for the attribute property.
*/
protected DynamicForm createPropertyUI(
+ // FIXME: display name (which comes from the server side) is not used but i10n happens on client side,,
String dname,
String name,
String type,
@@ -535,6 +537,9 @@
f.setValueMap(valueMap);
f.setValue(value);
}
+ else if (type.equals("areapattern")) {
+ f = createAreaPetternUi(name, value);
+ }
else if (type.equals("font")) {
f = new SelectItem(name, MSG.getString(name));
LinkedHashMap<String, String> valueMap =
@@ -587,6 +592,33 @@
}
+ private FormItem createAreaPetternUi(String name, String value) {
+ final FormItem f = new SelectItem(name, MSG.getString(name));
+
+ f.setImageURLPrefix(GWT.getHostPageBaseURL() + "images/areapattern-");
+ f.setImageURLSuffix(".png");
+ f.setValueIconHeight(20);
+ f.setValueIconWidth(80);
+
+ final LinkedHashMap<String, String> valueMap = new LinkedHashMap<String, String>();
+ final Map<String, String> valueIcons = new LinkedHashMap<String, String>();
+
+ // FIXME: ugly, using knowledge of available patterns at this point, creating redundancy with AreaFillPattern enum.
+ // But the whole code does it like that, so this is 'flys style'
+ final String[] patterns = new String[] {"pattern1", "x"};
+ for (int i = 0; i < patterns.length; i++) {
+ final String pattern = patterns[i];
+
+ valueMap.put(pattern, "");
+ valueIcons.put(pattern, pattern);
+ }
+
+ f.setValueIcons(valueIcons);
+ f.setValueMap(valueMap);
+ f.setValue(value);
+ return f;
+ }
+
protected FormItem createLineSizeUI(FormItem f) {
LinkedHashMap<String, String> valueIcons =
new LinkedHashMap<String, String>();
diff -r 31dff17c6828 -r d9c89651bd67 gwt-client/src/main/webapp/images/areapattern-pattern1.png
Binary file gwt-client/src/main/webapp/images/areapattern-pattern1.png has changed
diff -r 31dff17c6828 -r d9c89651bd67 gwt-client/src/main/webapp/images/areapattern-x.png
Binary file gwt-client/src/main/webapp/images/areapattern-x.png has changed
More information about the Dive4Elements-commits
mailing list