    001    /* ===========================================================
    002     * JFreeChart : a free chart library for the Java(tm) platform
    003     * ===========================================================
    004     *
    005     * (C) Copyright 2000-2011, by Object Refinery Limited and Contributors.
    006     *
    007     * Project Info:  http://www.jfree.org/jfreechart/index.html
    008     *
    009     * This library is free software; you can redistribute it and/or modify it
    010     * under the terms of the GNU Lesser General Public License as published by
    011     * the Free Software Foundation; either version 2.1 of the License, or
    012     * (at your option) any later version.
    013     *
    014     * This library is distributed in the hope that it will be useful, but
    015     * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    016     * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
    017     * License for more details.
    018     *
    019     * You should have received a copy of the GNU Lesser General Public
    020     * License along with this library; if not, write to the Free Software
    021     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
    022     * USA.
    023     *
    024     * [Oracle and Java are registered trademarks of Oracle and/or its affiliates.
    025     * Other names may be trademarks of their respective owners.]
    026     *
    027     * ---------------------
    028     * WindItemRenderer.java
    029     * ---------------------
    030     * (C) Copyright 2001-2008, by Achilleus Mantzios and Contributors.
    031     *
    032     * Original Author:  Achilleus Mantzios;
    033     * Contributor(s):   David Gilbert (for Object Refinery Limited);
    034     *
    035     * Changes
    036     * -------
    037     * 06-Feb-2002 : Version 1, based on code contributed by Achilleus
    038     *               Mantzios (DG);
    039     * 28-Mar-2002 : Added a property change listener mechanism so that renderers
    040     *               no longer need to be immutable.  Changed StrictMath --> Math
    041     *               to retain JDK1.2 compatibility (DG);
    042     * 09-Apr-2002 : Changed return type of the drawItem method to void, reflecting
    043     *               the change in the XYItemRenderer method (DG);
    044     * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
    045     * 21-Jan-2003 : Added new constructor (DG);
    046     * 25-Mar-2003 : Implemented Serializable (DG);
    047     * 01-May-2003 : Modified drawItem() method signature (DG);
    048     * 20-Aug-2003 : Implemented Cloneable and PublicCloneable (DG);
    049     * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
    050     * 25-Feb-2004 : Replaced CrosshairInfo with CrosshairState (DG);
    051     * 15-Jul-2004 : Switched getX() with getXValue() and getY() with
    052     *               getYValue() (DG);
    053     * ------------- JFREECHART 1.0.x ---------------------------------------------
    054     * 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
    055     *
    056     */
    057
    058    package org.jfree.chart.renderer.xy;
    059
    060    import java.awt.Color;
    061    import java.awt.Font;
    062    import java.awt.Graphics2D;
    063    import java.awt.Paint;
    064    import java.awt.Stroke;
    065    import java.awt.geom.Line2D;
    066    import java.awt.geom.Rectangle2D;
    067    import java.io.Serializable;
    068
    069    import org.jfree.chart.axis.ValueAxis;
    070    import org.jfree.chart.plot.CrosshairState;
    071    import org.jfree.chart.plot.PlotRenderingInfo;
    072    import org.jfree.chart.plot.XYPlot;
    073    import org.jfree.data.xy.WindDataset;
    074    import org.jfree.data.xy.XYDataset;
    075    import org.jfree.ui.RectangleEdge;
    076    import org.jfree.util.PublicCloneable;
    077
    078    /**
    079     * A specialised renderer for displaying wind intensity/direction data.
    080     * The example shown here is generated by the <code>WindChartDemo1.java</code>
    081     * program included in the JFreeChart demo collection:
    082     * <br><br>
    083     * <img src="../../../../../images/WindItemRendererSample.png"
    084     * alt="WindItemRendererSample.png" />
    085     */
    086    public class WindItemRenderer extends AbstractXYItemRenderer
    087            implements XYItemRenderer, Cloneable, PublicCloneable, Serializable {
    088
    089        /** For serialization. */
    090        private static final long serialVersionUID = 8078914101916976844L;
    091
    092        /**
    093         * Creates a new renderer.
    094         */
    095        public WindItemRenderer() {
    096            super();
    097        }
    098
    099        /**
    100         * Draws the visual representation of a single data item.
    101         *
    102         * @param g2  the graphics device.
    103         * @param state  the renderer state.
    104         * @param plotArea  the area within which the plot is being drawn.
    105         * @param info  optional information collection.
    106         * @param plot  the plot (can be used to obtain standard color
    107         *              information etc).
    108         * @param domainAxis  the horizontal axis.
    109         * @param rangeAxis  the vertical axis.
    110         * @param dataset  the dataset.
    111         * @param series  the series index (zero-based).
    112         * @param item  the item index (zero-based).
    113         * @param crosshairState  crosshair information for the plot
    114         *                        (<code>null</code> permitted).
    115         * @param pass  the pass index.
    116         */
    117        public void drawItem(Graphics2D g2,
    118                             XYItemRendererState state,
    119                             Rectangle2D plotArea,
    120                             PlotRenderingInfo info,
    121                             XYPlot plot,
    122                             ValueAxis domainAxis,
    123                             ValueAxis rangeAxis,
    124                             XYDataset dataset,
    125                             int series,
    126                             int item,
    127                             CrosshairState crosshairState,
    128                             int pass) {
    129
    130            WindDataset windData = (WindDataset) dataset;
    131
    132            Paint seriesPaint = getItemPaint(series, item);
    133            Stroke seriesStroke = getItemStroke(series, item);
    134            g2.setPaint(seriesPaint);
    135            g2.setStroke(seriesStroke);
    136
    137            // get the data point...
    138
    139            Number x = windData.getX(series, item);
    140            Number windDir = windData.getWindDirection(series, item);
    141            Number wforce = windData.getWindForce(series, item);
    142            double windForce = wforce.doubleValue();
    143
    144            double wdirt = Math.toRadians(windDir.doubleValue() * (-30.0) - 90.0);
    145
    146            double ax1, ax2, ay1, ay2, rax2, ray2;
    147
    148            RectangleEdge domainAxisLocation = plot.getDomainAxisEdge();
    149            RectangleEdge rangeAxisLocation = plot.getRangeAxisEdge();
    150            ax1 = domainAxis.valueToJava2D(x.doubleValue(), plotArea,
    151                    domainAxisLocation);
    152            ay1 = rangeAxis.valueToJava2D(0.0, plotArea, rangeAxisLocation);
    153
    154            rax2 = x.doubleValue() + (windForce * Math.cos(wdirt) * 8000000.0);
    155            ray2 = windForce * Math.sin(wdirt);
    156
    157            ax2 = domainAxis.valueToJava2D(rax2, plotArea, domainAxisLocation);
    158            ay2 = rangeAxis.valueToJava2D(ray2, plotArea, rangeAxisLocation);
    159
    160            int diri = windDir.intValue();
    161            int forcei = wforce.intValue();
    162            String dirforce = diri + "-" + forcei;
    163            Line2D line = new Line2D.Double(ax1, ay1, ax2, ay2);
    164
    165            g2.draw(line);
    166            g2.setPaint(Color.blue);
    167            g2.setFont(new Font("Dialog", 1, 9));
    168
    169            g2.drawString(dirforce, (float) ax1, (float) ay1);
    170
    171            g2.setPaint(seriesPaint);
    172            g2.setStroke(seriesStroke);
    173
    174            double alx2, aly2, arx2, ary2;
    175            double ralx2, raly2, rarx2, rary2;
    176
    177            double aldir = Math.toRadians(windDir.doubleValue()
    178                    * (-30.0) - 90.0 - 5.0);
    179            ralx2 = wforce.doubleValue() * Math.cos(aldir) * 8000000 * 0.8
    180            + x.doubleValue();
    181            raly2 = wforce.doubleValue() * Math.sin(aldir) * 0.8;
    182
    183            alx2 = domainAxis.valueToJava2D(ralx2, plotArea, domainAxisLocation);
    184            aly2 = rangeAxis.valueToJava2D(raly2, plotArea, rangeAxisLocation);
    185
    186            line = new Line2D.Double(alx2, aly2, ax2, ay2);
    187            g2.draw(line);
    188
    189            double ardir = Math.toRadians(windDir.doubleValue()
    190                    * (-30.0) - 90.0 + 5.0);
    191            rarx2 = wforce.doubleValue() * Math.cos(ardir) * 8000000 * 0.8
    192                    + x.doubleValue();
    193            rary2 = wforce.doubleValue() * Math.sin(ardir) * 0.8;
    194
    195            arx2 = domainAxis.valueToJava2D(rarx2, plotArea, domainAxisLocation);
    196            ary2 = rangeAxis.valueToJava2D(rary2, plotArea, rangeAxisLocation);
    197
    198            line = new Line2D.Double(arx2, ary2, ax2, ay2);
    199            g2.draw(line);
    200
    201        }
    202
    203        /**
    204         * Returns a clone of the renderer.
    205         *
    206         * @return A clone.
    207         *
    208         * @throws CloneNotSupportedException  if the renderer cannot be cloned.
    209         */
    210        public Object clone() throws CloneNotSupportedException {
    211            return super.clone();
    212        }
    213
    214    }