diff flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java @ 3023:e19ff9086035

Avoid collisions between line labels. flys-artifacts/trunk@4590 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Tue, 05 Jun 2012 15:03:11 +0000
parents 9cea02b51241
children da3e58694cae
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java	Tue Jun 05 14:56:57 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/jfree/EnhancedLineAndShapeRenderer.java	Tue Jun 05 15:03:11 2012 +0000
@@ -21,11 +21,13 @@
 import org.jfree.data.xy.XYSeries;
 import org.jfree.data.xy.XYSeriesCollection;
 import org.jfree.ui.RectangleEdge;
+import org.jfree.ui.TextAnchor;
 import org.jfree.util.BooleanList;
 import org.jfree.util.ShapeUtilities;
+import org.jfree.text.TextUtilities;
 
 import de.intevation.flys.jfree.HasLabel;
-
+import de.intevation.flys.jfree.JFreeUtil;
 
 /**
  * Renderer with additional the additional functionality of renderering minima
@@ -87,6 +89,10 @@
     }
 
 
+    /**
+     * Whether or not a specific item in a series (maybe the maxima) should
+     * be rendered with shape.
+     */
     public boolean getItemShapeVisible(XYDataset dataset, int series, int item){
         if (super.getItemShapeVisible(series, item)) {
             return true;
@@ -104,11 +110,17 @@
     }
 
 
+    /**
+     * Rectangle used to draw maximums shape.
+     */
     public Shape getMaximumShape(int series, int column) {
         return new Rectangle2D.Double(-5d, -5d, 10d, 10d);
     }
 
 
+    /**
+     * Rectangle used to draw minimums shape.
+     */
     public Shape getMinimumShape(int series, int column) {
         return new Rectangle2D.Double(-5d, -5d, 10d, 10d);
     }
@@ -272,13 +284,13 @@
         }
 
         // Draw label of line.
-        // TODO add colision detection
         if (isShowLineLabel(series) && isMinimumX (dataset, series, item)) {
             XYSeries xYSeries = ((XYSeriesCollection) dataset).getSeries(series);
             String waterlevelLabel = (xYSeries instanceof HasLabel)
                 ? ((HasLabel)xYSeries).getLabel()
                 : xYSeries.getKey().toString();
             // TODO Force water of some German rivers to flow direction mountains.
+
             Font oldFont = g2.getFont();
 
             Color oldColor = g2.getColor();
@@ -286,6 +298,21 @@
             g2.setColor(this.getLineLabelTextColor(series));
             g2.setBackground(Color.black);
 
+            // Move to right until no collisions exist anymore
+            Shape hotspot = TextUtilities.calculateRotatedStringBounds(
+                waterlevelLabel, g2, (float)xx, (float)yy-3f, TextAnchor.CENTER_LEFT,
+                0f, TextAnchor.CENTER_LEFT);
+            while (JFreeUtil.collides(hotspot, entities, CollisionFreeLineLabelEntity.class)) {
+                xx += 5f;
+                hotspot = TextUtilities.calculateRotatedStringBounds(
+                    waterlevelLabel, g2, (float)xx, (float)yy-3f, TextAnchor.CENTER_LEFT,
+                    0f, TextAnchor.CENTER_LEFT);
+            }
+
+            // Register to avoid collissions.
+            entities.add(new CollisionFreeLineLabelEntity(hotspot,
+                1, "", ""));
+
             // Fill background.
             if (isShowLineLabelBG(series)) {
                 drawTextBox(g2, waterlevelLabel, (float)xx, (float)yy-3f,
@@ -311,6 +338,9 @@
     }
 
 
+    /**
+     * Sets whether or not the minimum should be rendered with shape.
+     */
     public void setIsMinimumShapeVisisble(int series, boolean isVisible) {
         this.isMinimumShapeVisible.setBoolean(series, isVisible);
     }

http://dive4elements.wald.intevation.org