Save This Page
Home » jcommon-1.0.13 » org.jfree » chart » renderer » xy » [javadoc | source]
    1   /* ===========================================================
    2    * JFreeChart : a free chart library for the Java(tm) platform
    3    * ===========================================================
    4    *
    5    * (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
    6    *
    7    * Project Info:  http://www.jfree.org/jfreechart/index.html
    8    *
    9    * This library is free software; you can redistribute it and/or modify it 
   10    * under the terms of the GNU Lesser General Public License as published by 
   11    * the Free Software Foundation; either version 2.1 of the License, or 
   12    * (at your option) any later version.
   13    *
   14    * This library is distributed in the hope that it will be useful, but 
   15    * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
   16    * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
   17    * License for more details.
   18    *
   19    * You should have received a copy of the GNU Lesser General Public
   20    * License along with this library; if not, write to the Free Software
   21    * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
   22    * USA.  
   23    *
   24    * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
   25    * in the United States and other countries.]
   26    *
   27    * --------------------
   28    * XYAreaRenderer2.java
   29    * --------------------
   30    * (C) Copyright 2004-2007, by Hari and Contributors.
   31    *
   32    * Original Author:  Hari (ourhari@hotmail.com);
   33    * Contributor(s):   David Gilbert (for Object Refinery Limited);
   34    *                   Richard Atkinson;
   35    *                   Christian W. Zuckschwerdt;
   36    *
   37    * Changes:
   38    * --------
   39    * 03-Apr-2002 : Version 1, contributed by Hari.  This class is based on the 
   40    *               StandardXYItemRenderer class (DG);
   41    * 09-Apr-2002 : Removed the translated zero from the drawItem method - 
   42    *               overridden the initialise() method to calculate it (DG);
   43    * 30-May-2002 : Added tool tip generator to constructor to match super 
   44    *               class (DG);
   45    * 25-Jun-2002 : Removed unnecessary local variable (DG);
   46    * 05-Aug-2002 : Small modification to drawItem method to support URLs for 
   47    *               HTML image maps (RA);
   48    * 01-Oct-2002 : Fixed errors reported by Checkstyle (DG);
   49    * 07-Nov-2002 : Renamed AreaXYItemRenderer --> XYAreaRenderer (DG);
   50    * 25-Mar-2003 : Implemented Serializable (DG);
   51    * 01-May-2003 : Modified drawItem() method signature (DG);
   52    * 27-Jul-2003 : Made line and polygon properties protected rather than 
   53    *               private (RA);
   54    * 30-Jul-2003 : Modified entity constructor (CZ);
   55    * 20-Aug-2003 : Implemented Cloneable and PublicCloneable (DG);
   56    * 16-Sep-2003 : Changed ChartRenderingInfo --> PlotRenderingInfo (DG);
   57    * 07-Oct-2003 : Added renderer state (DG);
   58    * 08-Dec-2003 : Modified hotspot for chart entity (DG);
   59    * 10-Feb-2004 : Changed the drawItem() method to make cut-and-paste 
   60    *               overriding easier.  Also moved state class into this 
   61    *               class (DG);
   62    * 25-Feb-2004 : Replaced CrosshairInfo with CrosshairState.  Renamed 
   63    *               XYToolTipGenerator --> XYItemLabelGenerator (DG);
   64    * 15-Jul-2004 : Switched getX() with getXValue() and getY() with 
   65    *               getYValue() (DG);
   66    * 11-Nov-2004 : Now uses ShapeUtilities to translate shapes (DG);
   67    * 19-Jan-2005 : Now accesses only primitives from the dataset (DG);
   68    * 21-Mar-2005 : Override getLegendItem() (DG);
   69    * 20-Apr-2005 : Use generators for legend tooltips and URLs (DG);
   70    * ------------- JFREECHART 1.0.x ---------------------------------------------
   71    * 30-Nov-2006 : Fixed equals() and clone() implementations (DG);
   72    * 06-Feb-2007 : Fixed bug 1086307, crosshairs with multiple axes (DG);
   73    * 20-Apr-2007 : Updated getLegendItem() and drawItem() for renderer 
   74    *               change (DG); 
   75    * 17-May-2007 : Set datasetIndex and seriesIndex in getLegendItem() (DG);
   76    * 18-May-2007 : Set dataset and seriesKey for LegendItem (DG);
   77    *
   78    */
   79   
   80   package org.jfree.chart.renderer.xy;
   81   
   82   
   83   import java.awt.Graphics2D;
   84   import java.awt.Paint;
   85   import java.awt.Polygon;
   86   import java.awt.Shape;
   87   import java.awt.Stroke;
   88   import java.awt.geom.GeneralPath;
   89   import java.awt.geom.Rectangle2D;
   90   import java.io.IOException;
   91   import java.io.ObjectInputStream;
   92   import java.io.ObjectOutputStream;
   93   import java.io.Serializable;
   94   
   95   import org.jfree.chart.LegendItem;
   96   import org.jfree.chart.axis.ValueAxis;
   97   import org.jfree.chart.entity.EntityCollection;
   98   import org.jfree.chart.entity.XYItemEntity;
   99   import org.jfree.chart.event.RendererChangeEvent;
  100   import org.jfree.chart.labels.XYSeriesLabelGenerator;
  101   import org.jfree.chart.labels.XYToolTipGenerator;
  102   import org.jfree.chart.plot.CrosshairState;
  103   import org.jfree.chart.plot.PlotOrientation;
  104   import org.jfree.chart.plot.PlotRenderingInfo;
  105   import org.jfree.chart.plot.XYPlot;
  106   import org.jfree.chart.urls.XYURLGenerator;
  107   import org.jfree.data.xy.XYDataset;
  108   import org.jfree.io.SerialUtilities;
  109   import org.jfree.util.PublicCloneable;
  110   import org.jfree.util.ShapeUtilities;
  111   
  112   /**
  113    * Area item renderer for an {@link XYPlot}.  
  114    */
  115   public class XYAreaRenderer2 extends AbstractXYItemRenderer 
  116                                implements XYItemRenderer, 
  117                                           Cloneable,
  118                                           PublicCloneable,
  119                                           Serializable {
  120   
  121       /** For serialization. */
  122       private static final long serialVersionUID = -7378069681579984133L;
  123   
  124       /** A flag that controls whether or not the outline is shown. */
  125       private boolean showOutline;
  126   
  127       /** 
  128        * The shape used to represent an area in each legend item (this should 
  129        * never be <code>null</code>). 
  130        */
  131       private transient Shape legendArea;
  132   
  133       /**
  134        * Constructs a new renderer.
  135        */
  136       public XYAreaRenderer2() {
  137           this(null, null);
  138       }
  139   
  140       /**
  141        * Constructs a new renderer.
  142        *
  143        * @param labelGenerator  the tool tip generator to use.  <code>null</code> 
  144        *                        is none.
  145        * @param urlGenerator  the URL generator (null permitted).
  146        */
  147       public XYAreaRenderer2(XYToolTipGenerator labelGenerator, 
  148                              XYURLGenerator urlGenerator) {
  149           super();
  150           this.showOutline = false;
  151           setBaseToolTipGenerator(labelGenerator);
  152           setURLGenerator(urlGenerator);
  153           GeneralPath area = new GeneralPath();
  154           area.moveTo(0.0f, -4.0f);
  155           area.lineTo(3.0f, -2.0f);
  156           area.lineTo(4.0f, 4.0f);
  157           area.lineTo(-4.0f, 4.0f);
  158           area.lineTo(-3.0f, -2.0f);
  159           area.closePath();
  160           this.legendArea = area;
  161       }
  162   
  163       /**
  164        * Returns a flag that controls whether or not outlines of the areas are 
  165        * drawn.
  166        *
  167        * @return The flag.
  168        * 
  169        * @see #setOutline(boolean)
  170        */
  171       public boolean isOutline() {
  172           return this.showOutline;
  173       }
  174   
  175       /**
  176        * Sets a flag that controls whether or not outlines of the areas are 
  177        * drawn, and sends a {@link RendererChangeEvent} to all registered 
  178        * listeners.
  179        *
  180        * @param show  the flag.
  181        * 
  182        * @see #isOutline()
  183        */
  184       public void setOutline(boolean show) {
  185           this.showOutline = show;
  186           fireChangeEvent();
  187       }
  188   
  189       /**
  190        * This method should not be used.
  191        *
  192        * @return <code>false</code> always.
  193        * 
  194        * @deprecated This method was included in the API by mistake and serves
  195        *     no useful purpose.  It has always returned <code>false</code>.
  196        *   
  197        */
  198       public boolean getPlotLines() {
  199           return false;
  200       }
  201   
  202       /**
  203        * Returns the shape used to represent an area in the legend.
  204        * 
  205        * @return The legend area (never <code>null</code>).
  206        * 
  207        * @see #setLegendArea(Shape)
  208        */
  209       public Shape getLegendArea() {
  210           return this.legendArea;   
  211       }
  212       
  213       /**
  214        * Sets the shape used as an area in each legend item and sends a 
  215        * {@link RendererChangeEvent} to all registered listeners.
  216        * 
  217        * @param area  the area (<code>null</code> not permitted).
  218        * 
  219        * @see #getLegendArea()
  220        */
  221       public void setLegendArea(Shape area) {
  222           if (area == null) {
  223               throw new IllegalArgumentException("Null 'area' argument.");   
  224           }
  225           this.legendArea = area;
  226           fireChangeEvent();
  227       }
  228   
  229       /**
  230        * Returns a default legend item for the specified series.  Subclasses 
  231        * should override this method to generate customised items.
  232        *
  233        * @param datasetIndex  the dataset index (zero-based).
  234        * @param series  the series index (zero-based).
  235        *
  236        * @return A legend item for the series.
  237        */
  238       public LegendItem getLegendItem(int datasetIndex, int series) {
  239           LegendItem result = null;
  240           XYPlot xyplot = getPlot();
  241           if (xyplot != null) {
  242               XYDataset dataset = xyplot.getDataset(datasetIndex);
  243               if (dataset != null) {
  244                   XYSeriesLabelGenerator lg = getLegendItemLabelGenerator();
  245                   String label = lg.generateLabel(dataset, series);
  246                   String description = label;
  247                   String toolTipText = null;
  248                   if (getLegendItemToolTipGenerator() != null) {
  249                       toolTipText = getLegendItemToolTipGenerator().generateLabel(
  250                               dataset, series);
  251                   }
  252                   String urlText = null;
  253                   if (getLegendItemURLGenerator() != null) {
  254                       urlText = getLegendItemURLGenerator().generateLabel(
  255                               dataset, series);
  256                   }
  257                   Paint paint = lookupSeriesPaint(series);
  258                   result = new LegendItem(label, description, toolTipText, 
  259                           urlText, this.legendArea, paint);
  260                   result.setDataset(dataset);
  261                   result.setDatasetIndex(datasetIndex);
  262                   result.setSeriesKey(dataset.getSeriesKey(series));
  263                   result.setSeriesIndex(series);
  264               }
  265           }
  266           return result;
  267       }
  268       
  269       /**
  270        * Draws the visual representation of a single data item.
  271        *
  272        * @param g2  the graphics device.
  273        * @param state  the renderer state.
  274        * @param dataArea  the area within which the data is being drawn.
  275        * @param info  collects information about the drawing.
  276        * @param plot  the plot (can be used to obtain standard color 
  277        *              information etc).
  278        * @param domainAxis  the domain axis.
  279        * @param rangeAxis  the range axis.
  280        * @param dataset  the dataset.
  281        * @param series  the series index (zero-based).
  282        * @param item  the item index (zero-based).
  283        * @param crosshairState  crosshair information for the plot 
  284        *                        (<code>null</code> permitted).
  285        * @param pass  the pass index.
  286        */
  287       public void drawItem(Graphics2D g2,
  288                            XYItemRendererState state,
  289                            Rectangle2D dataArea,
  290                            PlotRenderingInfo info,
  291                            XYPlot plot,
  292                            ValueAxis domainAxis,
  293                            ValueAxis rangeAxis,
  294                            XYDataset dataset,
  295                            int series,
  296                            int item,
  297                            CrosshairState crosshairState,
  298                            int pass) {
  299           
  300           if (!getItemVisible(series, item)) {
  301               return;   
  302           }
  303           // get the data point...
  304           double x1 = dataset.getXValue(series, item);
  305           double y1 = dataset.getYValue(series, item);
  306           if (Double.isNaN(y1)) {
  307               y1 = 0.0;
  308           }
  309           
  310           double transX1 = domainAxis.valueToJava2D(x1, dataArea, 
  311                   plot.getDomainAxisEdge());
  312           double transY1 = rangeAxis.valueToJava2D(y1, dataArea, 
  313                   plot.getRangeAxisEdge());
  314           
  315           // get the previous point and the next point so we can calculate a 
  316           // "hot spot" for the area (used by the chart entity)...
  317           double x0 = dataset.getXValue(series, Math.max(item - 1, 0));
  318           double y0 = dataset.getYValue(series, Math.max(item - 1, 0));
  319           if (Double.isNaN(y0)) {
  320               y0 = 0.0;
  321           }
  322           double transX0 = domainAxis.valueToJava2D(x0, dataArea, 
  323                   plot.getDomainAxisEdge());
  324           double transY0 = rangeAxis.valueToJava2D(y0, dataArea, 
  325                   plot.getRangeAxisEdge());
  326           
  327           int itemCount = dataset.getItemCount(series);
  328           double x2 = dataset.getXValue(series, Math.min(item + 1, 
  329                   itemCount - 1));
  330           double y2 = dataset.getYValue(series, Math.min(item + 1, 
  331                   itemCount - 1));
  332           if (Double.isNaN(y2)) {
  333               y2 = 0.0;
  334           }
  335           double transX2 = domainAxis.valueToJava2D(x2, dataArea, 
  336                   plot.getDomainAxisEdge());
  337           double transY2 = rangeAxis.valueToJava2D(y2, dataArea, 
  338                   plot.getRangeAxisEdge());
  339           
  340           double transZero = rangeAxis.valueToJava2D(0.0, dataArea, 
  341                   plot.getRangeAxisEdge());
  342           Polygon hotspot = null;
  343           if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
  344               hotspot = new Polygon();
  345               hotspot.addPoint((int) transZero, 
  346                       (int) ((transX0 + transX1) / 2.0));
  347               hotspot.addPoint((int) ((transY0 + transY1) / 2.0), 
  348                       (int) ((transX0 + transX1) / 2.0));
  349               hotspot.addPoint((int) transY1, (int) transX1);
  350               hotspot.addPoint((int) ((transY1 + transY2) / 2.0), 
  351                       (int) ((transX1 + transX2) / 2.0));
  352               hotspot.addPoint((int) transZero, 
  353                       (int) ((transX1 + transX2) / 2.0));
  354           }
  355           else {  // vertical orientation
  356               hotspot = new Polygon();
  357               hotspot.addPoint((int) ((transX0 + transX1) / 2.0), 
  358                       (int) transZero);
  359               hotspot.addPoint((int) ((transX0 + transX1) / 2.0), 
  360                       (int) ((transY0 + transY1) / 2.0));
  361               hotspot.addPoint((int) transX1, (int) transY1);
  362               hotspot.addPoint((int) ((transX1 + transX2) / 2.0), 
  363                       (int) ((transY1 + transY2) / 2.0));
  364               hotspot.addPoint((int) ((transX1 + transX2) / 2.0), 
  365                       (int) transZero);
  366           }
  367                   
  368           PlotOrientation orientation = plot.getOrientation();
  369           Paint paint = getItemPaint(series, item);
  370           Stroke stroke = getItemStroke(series, item);
  371           g2.setPaint(paint);
  372           g2.setStroke(stroke);
  373   
  374           if (getPlotLines()) {
  375               if (item > 0) {
  376                   if (plot.getOrientation() == PlotOrientation.VERTICAL) {
  377                       state.workingLine.setLine(transX0, transY0, transX1, 
  378                               transY1);
  379                   }
  380                   else if (plot.getOrientation() == PlotOrientation.HORIZONTAL) {
  381                       state.workingLine.setLine(transY0, transX0, transY1, 
  382                               transX1);
  383                   }
  384                   g2.draw(state.workingLine);
  385               }
  386           }
  387   
  388           // Check if the item is the last item for the series.
  389           // and number of items > 0.  We can't draw an area for a single point.
  390           g2.fill(hotspot);
  391   
  392           // draw an outline around the Area.
  393           if (isOutline()) {
  394               g2.setStroke(lookupSeriesOutlineStroke(series));
  395               g2.setPaint(lookupSeriesOutlinePaint(series));
  396               g2.draw(hotspot);
  397           }
  398           int domainAxisIndex = plot.getDomainAxisIndex(domainAxis);
  399           int rangeAxisIndex = plot.getRangeAxisIndex(rangeAxis);
  400           updateCrosshairValues(crosshairState, x1, y1, domainAxisIndex, 
  401                   rangeAxisIndex, transX1, transY1, orientation);
  402           
  403           // collect entity and tool tip information...
  404           if (state.getInfo() != null) {
  405               EntityCollection entities = state.getEntityCollection();
  406               if (entities != null && hotspot != null) {
  407                   String tip = null;
  408                   XYToolTipGenerator generator = getToolTipGenerator(
  409                       series, item
  410                   );
  411                   if (generator != null) {
  412                       tip = generator.generateToolTip(dataset, series, item);
  413                   }
  414                   String url = null;
  415                   if (getURLGenerator() != null) {
  416                       url = getURLGenerator().generateURL(dataset, series, item);
  417                   }
  418                   XYItemEntity entity = new XYItemEntity(hotspot, dataset, 
  419                           series, item, tip, url);
  420                   entities.add(entity);
  421               }
  422           }
  423   
  424       }
  425   
  426       /**
  427        * Tests this renderer for equality with an arbitrary object.
  428        * 
  429        * @param obj  the object (<code>null</code> not permitted).
  430        * 
  431        * @return A boolean.
  432        */
  433       public boolean equals(Object obj) {
  434           if (obj == this) {    
  435               return true;
  436           }
  437           if (!(obj instanceof XYAreaRenderer2)) {
  438               return false;
  439           }
  440           XYAreaRenderer2 that = (XYAreaRenderer2) obj;
  441           if (this.showOutline != that.showOutline) {
  442               return false;
  443           }
  444           if (!ShapeUtilities.equal(this.legendArea, that.legendArea)) {
  445               return false;
  446           }
  447           return super.equals(obj);
  448       }
  449       
  450       /**
  451        * Returns a clone of the renderer.
  452        * 
  453        * @return A clone.
  454        * 
  455        * @throws CloneNotSupportedException  if the renderer cannot be cloned.
  456        */
  457       public Object clone() throws CloneNotSupportedException {
  458           XYAreaRenderer2 clone = (XYAreaRenderer2) super.clone();
  459           clone.legendArea = ShapeUtilities.clone(this.legendArea);
  460           return clone;
  461       }
  462       
  463       /**
  464        * Provides serialization support.
  465        *
  466        * @param stream  the input stream.
  467        *
  468        * @throws IOException  if there is an I/O error.
  469        * @throws ClassNotFoundException  if there is a classpath problem.
  470        */
  471       private void readObject(ObjectInputStream stream) 
  472               throws IOException, ClassNotFoundException {
  473           stream.defaultReadObject();
  474           this.legendArea = SerialUtilities.readShape(stream);
  475       }
  476       
  477       /**
  478        * Provides serialization support.
  479        *
  480        * @param stream  the output stream.
  481        *
  482        * @throws IOException  if there is an I/O error.
  483        */
  484       private void writeObject(ObjectOutputStream stream) throws IOException {
  485           stream.defaultWriteObject();
  486           SerialUtilities.writeShape(this.legendArea, stream);
  487       }
  488   
  489   }
  490   

Save This Page
Home » jcommon-1.0.13 » org.jfree » chart » renderer » xy » [javadoc | source]