# HG changeset patch # User Felix Wolfsteller # Date 1340714906 0 # Node ID 05c84d65988a7d0a67906614e7b2222beca9ea98 # Parent f1e09a003f78c9f04b2b436c2cf021dd7fbe30d7 Extracted legenditemaggregation from xychartgenerator. flys-artifacts/trunk@4798 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r f1e09a003f78 -r 05c84d65988a flys-artifacts/ChangeLog --- 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 + + 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 * src/main/java/de/intevation/flys/exports/XYChartGenerator.java: diff -r f1e09a003f78 -r 05c84d65988a flys-artifacts/src/main/java/de/intevation/flys/exports/LegendProcessor.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> entries = new LinkedHashMap>(); + for (Iterator i = old.iterator(); i.hasNext();) { + LegendItem item = (LegendItem) i.next(); + String hash = legendItemHash(item); + List itemList = entries.get(hash); + if (itemList == null) { + itemList = new ArrayList(); + } + 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> cursor: entries.entrySet()) { + List 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 : diff -r f1e09a003f78 -r 05c84d65988a flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java --- 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> entries = new LinkedHashMap>(); - for (Iterator i = old.iterator(); i.hasNext();) { - LegendItem item = (LegendItem) i.next(); - String hash = legendItemHash(item); - List itemList = entries.get(hash); - if (itemList == null) { - itemList = new ArrayList(); - } - 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> cursor: entries.entrySet()) { - List 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); }