Mercurial > dive4elements > river
diff flys-artifacts/src/main/java/de/intevation/flys/exports/LegendProcessor.java @ 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 | |
children | 89dc2db3a202 |
line wrap: on
line diff
--- /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 :