changeset 3183:05c84d65988a

Extracted legenditemaggregation from xychartgenerator. flys-artifacts/trunk@4798 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Tue, 26 Jun 2012 12:48:26 +0000
parents f1e09a003f78
children 12440c6b8b66
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/exports/LegendProcessor.java flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java
diffstat 3 files changed, 160 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Tue Jun 26 10:55:39 2012 +0000
+++ b/flys-artifacts/ChangeLog	Tue Jun 26 12:48:26 2012 +0000
@@ -1,3 +1,13 @@
+2012-06-26	Felix Wolfsteller	<felix.wolfsteller@intevation.de>
+
+	Legend Item Aggregation refactoring.
+
+	* src/main/java/de/intevation/flys/exports/LegendProcessor.java:
+	  New (extracted from XYChartGenerator).
+
+	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
+	  Extracted legend item aggregation to LegendProcessor.
+
 2012-06-26	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/flys/exports/XYChartGenerator.java:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/LegendProcessor.java	Tue Jun 26 12:48:26 2012 +0000
@@ -0,0 +1,148 @@
+package de.intevation.flys.exports;
+
+import java.awt.geom.Line2D;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.LegendItem;
+import org.jfree.chart.LegendItemCollection;
+import org.jfree.chart.plot.XYPlot;
+
+
+/** Class to process Plots legends. */
+public abstract class LegendProcessor {
+
+    /** (Empty) shape for aggregated Legend Items. */
+    private static final Line2D.Double SPACE = new Line2D.Double(0,0,0,0);
+ 
+
+    /** Prevent instantiations. */
+    private LegendProcessor() {
+    }
+
+
+    /**
+     * Create a hash from a legenditem.
+     * This hash can then be used to merge legend items labels.
+     * @return hash for given legenditem to identify mergeables.
+     */
+    protected static String legendItemHash(LegendItem li) {
+        // TODO Do proper implementation. Ensure that only mergable sets are created.
+        // getFillPaint()
+        // getFillPaintTransformer()
+        // getLabel()
+        // getLine()
+        // getLinePaint()
+        // getLineStroke()
+        // getOutminePaint()
+        // getOutlineStroke()
+        // Shape getShape()
+        // String getToolTipText()
+        // String getURLText()
+        // boolean isLineVisible()
+        // boolean isShapeFilled()
+        // boolean isShapeOutlineVisible()
+        // boolean isShapeVisible()
+        String hash = li.getLinePaint().toString();
+        String label = li.getLabel();
+        if (label.startsWith("W (") || label.startsWith("W(")) {
+            hash += "-W-";
+        }
+        else if (label.startsWith("Q(") || label.startsWith("Q (")) {
+            hash += "-Q-";
+        }
+
+        // WQ.java holds example of using regex Matcher/Pattern.
+
+        return hash;
+    }
+
+
+    /**
+     * Create new legend entries, dependent on settings.
+     * @param plot The plot for which to modify the legend.
+     * @param threshold How many items are needed for aggregation to
+     *        be triggered?
+     */
+    public static void aggregateLegendEntries(XYPlot plot, int threshold) {
+        LegendItemCollection old = plot.getLegendItems();
+        // Find "similar" entries if aggregation is enabled.
+
+        int maxListSize = 0;
+        int AGGR_THRESHOLD = threshold;
+
+        if (AGGR_THRESHOLD > old.getItemCount() || AGGR_THRESHOLD <= 0){
+            return;
+        }
+
+        HashMap<String, List<LegendItem>> entries = new LinkedHashMap<String, List<LegendItem>>();
+        for (Iterator i = old.iterator(); i.hasNext();) {
+            LegendItem item = (LegendItem) i.next();
+            String hash = legendItemHash(item);
+            List<LegendItem> itemList = entries.get(hash);
+            if (itemList == null) {
+                itemList = new ArrayList<LegendItem>();
+            }
+            itemList.add(item);
+
+            if (itemList.size() > maxListSize) {
+                maxListSize = itemList.size();
+            }
+
+            entries.put(legendItemHash(item), itemList);
+        }
+
+        if (maxListSize < AGGR_THRESHOLD) {
+            // No need to do anything.
+            return;
+        }
+
+        // Run over collected entries, merge their names and create new
+        // entry if needed.
+        LegendItemCollection newLegend = new LegendItemCollection();
+        for (Map.Entry<String, List<LegendItem>> cursor: entries.entrySet()) {
+            List<LegendItem> itemList = cursor.getValue();
+            if (itemList.size() >= AGGR_THRESHOLD) {
+                // Now do merging.
+                LegendItem item = (LegendItem) itemList.get(0);
+                // Unfortunately we cannot clone and just setDescription, as this
+                // method was added in JFreeChart 1.0.14 (we are at .13).
+
+                // Remove the shapes of all but the first items,
+                // to prevent "overfill" of legenditemblock.
+                for (int i = 0; i < itemList.size(); i++) {
+                    if (i != 0) {
+                        LegendItem litem = itemList.get(i);
+
+                        // Make shape and line really small.
+                        LegendItem merged = new LegendItem(
+                            "," + litem.getLabel(), litem.getDescription(), litem.getToolTipText(),
+                            litem.getURLText(), false, SPACE,
+                            false, litem.getFillPaint(), false,
+                            litem.getOutlinePaint(), litem.getOutlineStroke(), false,
+                            SPACE, litem.getLineStroke(), litem.getLinePaint());
+                        newLegend.add(merged);
+                    }
+                    else {
+                        newLegend.add(itemList.get(i));
+                    }
+                }
+            }
+            else {
+                // Do not merge entries.
+                for (LegendItem li: itemList) {
+                    newLegend.add(li);
+                }
+            }
+        }
+
+        plot.setFixedLegendItems (newLegend);
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Tue Jun 26 10:55:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Tue Jun 26 12:48:26 2012 +0000
@@ -11,9 +11,7 @@
 
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
-import java.util.LinkedHashMap;
 import java.util.Map;
 
 import org.w3c.dom.Document;
@@ -260,6 +258,7 @@
         addAnnotationsToRenderer(plot);
 
         aggregateLegendEntries(plot);
+        // LegendItemAggregator benutzen und so umbauen, dass er eine Liste von LegendItems frisst.
 
         return chart;
     }
@@ -1305,10 +1304,6 @@
      * @param plot The plot for which to modify the legend.
      */
     public void aggregateLegendEntries(XYPlot plot) {
-        LegendItemCollection old = plot.getLegendItems();
-        // Find "similar" entries if aggregation is enabled.
-
-        int maxListSize = 0;
         int AGGR_THRESHOLD = 0;
 
         Integer threshold = getChartSettings().getLegendSection()
@@ -1316,72 +1311,7 @@
 
         AGGR_THRESHOLD = (threshold != null) ? threshold.intValue() : 0;
 
-        if (AGGR_THRESHOLD > old.getItemCount() || AGGR_THRESHOLD <= 0){
-            return;
-        }
-
-        HashMap<String, List<LegendItem>> entries = new LinkedHashMap<String, List<LegendItem>>();
-        for (Iterator i = old.iterator(); i.hasNext();) {
-            LegendItem item = (LegendItem) i.next();
-            String hash = legendItemHash(item);
-            List<LegendItem> itemList = entries.get(hash);
-            if (itemList == null) {
-                itemList = new ArrayList<LegendItem>();
-            }
-            itemList.add(item);
-
-            if (itemList.size() > maxListSize) {
-                maxListSize = itemList.size();
-            }
-
-            entries.put(legendItemHash(item), itemList);
-        }
-
-        if (maxListSize < AGGR_THRESHOLD) {
-            // No need to do anything.
-            return;
-        }
-
-        // Run over collected entries, merge their names and create new
-        // entry if needed.
-        LegendItemCollection newLegend = new LegendItemCollection();
-        for (Map.Entry<String, List<LegendItem>> cursor: entries.entrySet()) {
-            List<LegendItem> itemList = cursor.getValue();
-            if (itemList.size() >= AGGR_THRESHOLD) {
-                // Now do merging.
-                LegendItem item = (LegendItem) itemList.get(0);
-                // Unfortunately we cannot clone and just setDescription, as this
-                // method was added in JFreeChart 1.0.14 (we are at .13).
-
-                // Remove the shapes of all but the first items,
-                // to prevent "overfill" of legenditemblock.
-                for (int i = 0; i < itemList.size(); i++) {
-                    if (i != 0) {
-                        LegendItem litem = itemList.get(i);
-
-                        // Make shape and line really small.
-                        LegendItem merged = new LegendItem(
-                            ", " + litem.getLabel(), litem.getDescription(), litem.getToolTipText(),
-                            litem.getURLText(), false, SPACE,
-                            false, litem.getFillPaint(), false,
-                            litem.getOutlinePaint(), litem.getOutlineStroke(), false,
-                            SPACE, litem.getLineStroke(), litem.getLinePaint());
-                        newLegend.add(merged);
-                    }
-                    else {
-                        newLegend.add(itemList.get(i));
-                    }
-                }
-            }
-            else {
-                // Do not merge entries.
-                for (LegendItem li: itemList) {
-                    newLegend.add(li);
-                }
-            }
-        }
-
-        plot.setFixedLegendItems (newLegend);
+        LegendProcessor.aggregateLegendEntries(plot, AGGR_THRESHOLD);
     }
 
 

http://dive4elements.wald.intevation.org