view flys-artifacts/src/main/java/de/intevation/flys/jfree/CollisionFreeXYTextAnnotation.java @ 2157:c4ceade9d50e

Added new Annotation class that prevents collisions (to replace StickyAxisAnnotation). flys-artifacts/trunk@3742 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Fri, 20 Jan 2012 13:20:37 +0000
parents
children c68f4f227c09
line wrap: on
line source
package de.intevation.flys.jfree;

import org.apache.log4j.Logger;

import java.util.Iterator;

import java.awt.Shape;
import java.awt.geom.Rectangle2D;
import java.awt.Color;
import java.awt.Font;
import java.awt.BasicStroke;

import org.jfree.chart.annotations.XYTextAnnotation;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.entity.XYAnnotationEntity;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.Plot;

import org.jfree.text.TextUtilities;

import org.jfree.ui.RectangleEdge;

import de.intevation.flys.utils.ThemeAccess;

/**
 * Custom Annotations class that is drawn only if no collisions with other
 * already drawn CustomAnnotations in current plot are found.
 */
public class CollisionFreeXYTextAnnotation extends XYTextAnnotation {

    /** Logger for this class. */
    private static Logger logger =
        Logger.getLogger(CollisionFreeXYTextAnnotation.class);

    public CollisionFreeXYTextAnnotation(String text, float x, double y) {
        super(text, x, y);
    }


    /**
     * Draw the Annotation only if it does not collide with other
     * already drawn Annotations- texts.
     *
     * @param g2            the graphics device.
     * @param plot          the plot.
     * @param dataArea      the data area.
     * @param domainAxis    the domain axis.
     * @param rangeAxis     the range axis.
     * @param rendererIndex the render index.
     * @param info          state information, escpecially collects info about
     *                      already drawn shapes (and thus annotations), used
     *                      for collision detection.
     */
    @Override
    public void draw(
        java.awt.Graphics2D g2,
        XYPlot plot,
        java.awt.geom.Rectangle2D dataArea,
        ValueAxis domainAxis,
        ValueAxis rangeAxis,
        int rendererIndex,
        PlotRenderingInfo info
    ) {
        // From superclass, adjusted access only.
        PlotOrientation orientation = plot.getOrientation();
        RectangleEdge domainEdge = Plot.resolveDomainAxisLocation(
                plot.getDomainAxisLocation(), orientation);
        RectangleEdge rangeEdge = Plot.resolveRangeAxisLocation(
                plot.getRangeAxisLocation(), orientation);

        float anchorX = (float) domainAxis.valueToJava2D(
                this.getX(), dataArea, domainEdge);
        float anchorY = (float) rangeAxis.valueToJava2D(
                this.getY(), dataArea, rangeEdge);

        if (orientation == PlotOrientation.HORIZONTAL) {
            float tempAnchor = anchorX;
            anchorX = anchorY;
            anchorY = tempAnchor;
        }

        g2.setFont(getFont());
        Shape hotspot = TextUtilities.calculateRotatedStringBounds(
                getText(), g2, anchorX, anchorY, getTextAnchor(),
                getRotationAngle(), getRotationAnchor());

        // Deviation from superclass: prevent collision.
        Rectangle2D hotspotBox = hotspot.getBounds2D();
        for (Iterator i = info.getOwner().getEntityCollection().iterator();
                i.hasNext(); ) {
            Object next = i.next();
            // Collision with other stuff than XYAnnotations are okay.
            if (next instanceof XYAnnotationEntity) {
                XYAnnotationEntity drawnShape = (XYAnnotationEntity) next;
                if (drawnShape.getArea().intersects(hotspotBox)) {
                    // Found collision, early stop.
                    return;
                }
            }
        }

        if (this.getBackgroundPaint() != null) {
            g2.setPaint(this.getBackgroundPaint());
            g2.fill(hotspot);
        }
        g2.setPaint(getPaint());
        TextUtilities.drawRotatedString(getText(), g2, anchorX, anchorY,
                getTextAnchor(), getRotationAngle(), getRotationAnchor());
        if (this.isOutlineVisible()) {
            g2.setStroke(this.getOutlineStroke());
            g2.setPaint(this.getOutlinePaint());
            g2.draw(hotspot);
        }

        String toolTip = getToolTipText();
        String url = getURL();
        if (toolTip != null || url != null) {
            addEntity(info, hotspot, rendererIndex, toolTip, url);
        }
        else {
            addEntity(info, hotspot, rendererIndex,
                "CollisionFreeXYTextAnnotation",
                "CollisionFreeXYTextAnnotation");
        }
    }


    /*
    public void applyTheme(ThemeAccess ta) {
        lineWidth       = ta.parseLineWidth();
        lineColor       = ta.parseLineColorField();
        textColor       = ta.parseTextColor();
        font            = ta.parseTextFont();
        textOrientation = ta.parseTextOrientation();
        textBackground  = ta.parseTextBackground();
        showBackground  = ta.parseShowTextBackground();
    }
    */
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org