From: <mu...@us...> - 2009-04-07 08:15:33
|
Revision: 1938 http://jfreechart.svn.sourceforge.net/jfreechart/?rev=1938&view=rev Author: mungady Date: 2009-04-07 08:15:24 +0000 (Tue, 07 Apr 2009) Log Message: ----------- Synchronised with 1.0.x branch. Modified Paths: -------------- trunk/source/org/jfree/chart/event/RendererChangeEvent.java trunk/source/org/jfree/chart/renderer/AbstractRenderer.java trunk/source/org/jfree/chart/renderer/category/AbstractCategoryItemRenderer.java trunk/source/org/jfree/chart/renderer/xy/AbstractXYItemRenderer.java Modified: trunk/source/org/jfree/chart/event/RendererChangeEvent.java =================================================================== --- trunk/source/org/jfree/chart/event/RendererChangeEvent.java 2009-04-07 07:49:20 UTC (rev 1937) +++ trunk/source/org/jfree/chart/event/RendererChangeEvent.java 2009-04-07 08:15:24 UTC (rev 1938) @@ -2,7 +2,7 @@ * JFreeChart : a free chart library for the Java(tm) platform * =========================================================== * - * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors. + * (C) Copyright 2000-2009, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jfreechart/index.html * @@ -27,7 +27,7 @@ * ------------------------ * RendererChangeEvent.java * ------------------------ - * (C) Copyright 2003-2008, by Object Refinery Limited. + * (C) Copyright 2003-2009, by Object Refinery Limited. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): -; @@ -37,15 +37,15 @@ * 23-Oct-2003 : Version 1 (DG); * ------------- JFREECHART 1.0.x --------------------------------------------- * 04-Apr-2007 : Fixed typo in API docs (DG); + * 26-Mar-2009 : Added flag to signal visible series change (DG); * */ package org.jfree.chart.event; /** - * An event that can be forwarded to any - * {@link org.jfree.chart.event.RendererChangeListener} to signal a change to - * a renderer. + * An event that can be forwarded to any {@link RendererChangeListener} to + * signal a change to a renderer. */ public class RendererChangeEvent extends ChartChangeEvent { @@ -53,13 +53,35 @@ private Object renderer; /** + * A flag that indicates whether this event relates to a change in the + * series visibility. If so, the receiver (if it is a plot) may want to + * update the axis bounds. + * + * @since 1.0.13 + */ + private boolean seriesVisibilityChanged; + + /** * Creates a new event. * * @param renderer the renderer that generated the event. */ public RendererChangeEvent(Object renderer) { + this(renderer, false); + } + + /** + * Creates a new event. + * + * @param renderer the renderer that generated the event. + * @param seriesVisibilityChanged a flag that indicates whether or not + * the event relates to a change in the series visibility flags. + */ + public RendererChangeEvent(Object renderer, + boolean seriesVisibilityChanged) { super(renderer); this.renderer = renderer; + this.seriesVisibilityChanged = seriesVisibilityChanged; } /** @@ -71,4 +93,16 @@ return this.renderer; } + /** + * Returns the flag that indicates whether or not the event relates to + * a change in series visibility. + * + * @return A boolean. + * + * @since 1.0.13 + */ + public boolean getSeriesVisibilityChanged() { + return this.seriesVisibilityChanged; + } + } Modified: trunk/source/org/jfree/chart/renderer/AbstractRenderer.java =================================================================== --- trunk/source/org/jfree/chart/renderer/AbstractRenderer.java 2009-04-07 07:49:20 UTC (rev 1937) +++ trunk/source/org/jfree/chart/renderer/AbstractRenderer.java 2009-04-07 08:15:24 UTC (rev 1938) @@ -27,7 +27,7 @@ * --------------------- * AbstractRenderer.java * --------------------- - * (C) Copyright 2002-2008, by Object Refinery Limited. + * (C) Copyright 2002-2009, by Object Refinery Limited. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): Nicolas Brodu; @@ -86,7 +86,10 @@ * attributes (DG); * 18-Aug-2008 : Added clearSeriesPaints() and clearSeriesStrokes() (DG); * 28-Jan-2009 : Equals method doesn't test Shape equality correctly (DG); - * + * 27-Mar-2009 : Added dataBoundsIncludesVisibleSeriesOnly attribute, and + * updated renderer events for series visibility changes (DG); + * 01-Apr-2009 : Factored up the defaultEntityRadius field from the + * AbstractXYItemRenderer class (DG); */ package org.jfree.chart.renderer; @@ -116,6 +119,7 @@ import org.jfree.chart.plot.DrawingSupplier; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.text.TextAnchor; +import org.jfree.chart.title.LegendTitle; import org.jfree.chart.util.BooleanList; import org.jfree.chart.util.HashUtilities; import org.jfree.chart.util.ObjectList; @@ -353,6 +357,17 @@ */ private transient Paint baseLegendTextPaint; + /** + * A flag that controls whether or not the renderer will include the + * non-visible series when calculating the data bounds. + * + * @since 1.0.13 + */ + private boolean dataBoundsIncludesVisibleSeriesOnly = true; + + /** The default radius for the entity 'hotspot' */ + private int defaultEntityRadius; + /** Storage for registered change listeners. */ private transient EventListenerList listenerList; @@ -414,6 +429,8 @@ this.createEntitiesList = new BooleanList(); this.baseCreateEntities = true; + this.defaultEntityRadius = 3; + this.legendShape = new ShapeList(); this.baseLegendShape = null; @@ -506,7 +523,12 @@ public void setSeriesVisible(int series, Boolean visible, boolean notify) { this.seriesVisibleList.setBoolean(series, visible); if (notify) { - fireChangeEvent(); + // we create an event with a special flag set...the purpose of + // this is to communicate to the plot (the default receiver of + // the event) that series visibility has changed so the axis + // ranges might need updating... + RendererChangeEvent e = new RendererChangeEvent(this, true); + notifyListeners(e); } } @@ -546,7 +568,12 @@ public void setBaseSeriesVisible(boolean visible, boolean notify) { this.baseSeriesVisible = visible; if (notify) { - fireChangeEvent(); + // we create an event with a special flag set...the purpose of + // this is to communicate to the plot (the default receiver of + // the event) that series visibility has changed so the axis + // ranges might need updating... + RendererChangeEvent e = new RendererChangeEvent(this, true); + notifyListeners(e); } } @@ -1080,6 +1107,8 @@ * Returns the base outline paint. * * @return The paint (never <code>null</code>). + * + * @see #setBaseOutlinePaint(Paint) */ public Paint getBaseOutlinePaint() { return this.baseOutlinePaint; @@ -2339,6 +2368,30 @@ } /** + * Returns the radius of the circle used for the default entity area + * when no area is specified. + * + * @return A radius. + * + * @see #setDefaultEntityRadius(int) + */ + public int getDefaultEntityRadius() { + return this.defaultEntityRadius; + } + + /** + * Sets the radius of the circle used for the default entity area + * when no area is specified. + * + * @param radius the radius. + * + * @see #getDefaultEntityRadius() + */ + public void setDefaultEntityRadius(int radius) { + this.defaultEntityRadius = radius; + } + + /** * Performs a lookup for the legend shape. * * @param series the series index. @@ -2554,6 +2607,32 @@ fireChangeEvent(); } + /** + * Returns the flag that controls whether or not the data bounds reported + * by this renderer will exclude non-visible series. + * + * @return A boolean. + * + * @since 1.0.13 + */ + public boolean getDataBoundsIncludesVisibleSeriesOnly() { + return this.dataBoundsIncludesVisibleSeriesOnly; + } + + /** + * Sets the flag that controls whether or not the data bounds reported + * by this renderer will exclude non-visible series and sends a + * {@link RendererChangeEvent} to all registered listeners. + * + * @param visibleOnly include only visible series. + * + * @since 1.0.13 + */ + public void setDataBoundsIncludesVisibleSeriesOnly(boolean visibleOnly) { + this.dataBoundsIncludesVisibleSeriesOnly = visibleOnly; + notifyListeners(new RendererChangeEvent(this, true)); + } + /** The adjacent offset. */ private static final double ADJ = Math.cos(Math.PI / 6.0); @@ -2770,6 +2849,13 @@ return false; } AbstractRenderer that = (AbstractRenderer) obj; + if (this.dataBoundsIncludesVisibleSeriesOnly + != that.dataBoundsIncludesVisibleSeriesOnly) { + return false; + } + if (this.defaultEntityRadius != that.defaultEntityRadius) { + return false; + } if (!this.seriesVisibleList.equals(that.seriesVisibleList)) { return false; } @@ -3055,7 +3141,6 @@ * @throws IOException if there is an I/O error. */ private void writeObject(ObjectOutputStream stream) throws IOException { - stream.defaultWriteObject(); SerialUtilities.writePaint(this.basePaint, stream); SerialUtilities.writePaint(this.baseFillPaint, stream); @@ -3066,7 +3151,6 @@ SerialUtilities.writePaint(this.baseItemLabelPaint, stream); SerialUtilities.writeShape(this.baseLegendShape, stream); SerialUtilities.writePaint(this.baseLegendTextPaint, stream); - } /** @@ -3078,7 +3162,7 @@ * @throws ClassNotFoundException if there is a classpath problem. */ private void readObject(ObjectInputStream stream) - throws IOException, ClassNotFoundException { + throws IOException, ClassNotFoundException { stream.defaultReadObject(); this.basePaint = SerialUtilities.readPaint(stream); Modified: trunk/source/org/jfree/chart/renderer/category/AbstractCategoryItemRenderer.java =================================================================== --- trunk/source/org/jfree/chart/renderer/category/AbstractCategoryItemRenderer.java 2009-04-07 07:49:20 UTC (rev 1937) +++ trunk/source/org/jfree/chart/renderer/category/AbstractCategoryItemRenderer.java 2009-04-07 08:15:24 UTC (rev 1938) @@ -103,8 +103,10 @@ * 25-Nov-2008 : Fixed bug in findRangeBounds() method (DG); * 14-Jan-2009 : Update initialise() to store visible series indices (PK); * 21-Jan-2009 : Added drawRangeLine() method (DG); - * 28-Jan-2009 : Updated for changes to CategoryItemRenderer - * interface (DG); + * 28-Jan-2009 : Updated for changes to CategoryItemRenderer interface (DG); + * 27-Mar-2009 : Added new findRangeBounds() method to account for hidden + * series (DG); + * 01-Apr-2009 : Added new addEntity() method (DG); * */ @@ -118,6 +120,7 @@ import java.awt.Paint; import java.awt.Shape; import java.awt.Stroke; +import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; @@ -787,10 +790,39 @@ * <code>null</code> or empty). */ public Range findRangeBounds(CategoryDataset dataset) { + return findRangeBounds(dataset, false); + } + + /** + * Returns the range of values the renderer requires to display all the + * items from the specified dataset. + * + * @param dataset the dataset (<code>null</code> permitted). + * + * @return The range (<code>null</code> if the dataset is <code>null</code> + * or empty). + * + * @since 1.0.13 + */ + protected Range findRangeBounds(CategoryDataset dataset, + boolean includeInterval) { if (dataset == null) { return null; } - return DatasetUtilities.findRangeBounds(dataset); + if (getDataBoundsIncludesVisibleSeriesOnly()) { + List visibleSeriesKeys = new ArrayList(); + int seriesCount = dataset.getRowCount(); + for (int s = 0; s < seriesCount; s++) { + if (isSeriesVisible(s)) { + visibleSeriesKeys.add(dataset.getRowKey(s)); + } + } + return DatasetUtilities.findRangeBounds(dataset, + visibleSeriesKeys, includeInterval); + } + else { + return DatasetUtilities.findRangeBounds(dataset, includeInterval); + } } /** @@ -904,8 +936,8 @@ * @param dataArea the area for plotting data (not yet adjusted for any 3D * effect). * @param value the value at which the grid line should be drawn. - * @param paint the paint. - * @param stroke the stroke. + * @param paint the paint (<code>null</code> not permitted). + * @param stroke the stroke (<code>null</code> not permitted). * * @see #drawRangeGridline * @@ -1458,12 +1490,9 @@ * @param negative indicates a negative value (which affects the item * label position). */ - protected void drawItemLabel(Graphics2D g2, - PlotOrientation orientation, - CategoryDataset dataset, - int row, int column, - double x, double y, - boolean negative) { + protected void drawItemLabel(Graphics2D g2, PlotOrientation orientation, + CategoryDataset dataset, int row, int column, + double x, double y, boolean negative) { CategoryItemLabelGenerator generator = getItemLabelGenerator(row, column); @@ -1754,12 +1783,17 @@ * @param dataset the dataset. * @param row the row index. * @param column the column index. - * @param hotspot the hotspot. + * @param hotspot the hotspot (<code>null</code> not permitted). */ protected void addItemEntity(EntityCollection entities, CategoryDataset dataset, int row, int column, Shape hotspot) { - + if (hotspot == null) { + throw new IllegalArgumentException("Null 'hotspot' argument."); + } + if (!getItemCreateEntity(row, column)) { + return; + } String tip = null; CategoryToolTipGenerator tipster = getToolTipGenerator(row, column); if (tipster != null) { @@ -1773,7 +1807,54 @@ CategoryItemEntity entity = new CategoryItemEntity(hotspot, tip, url, dataset, dataset.getRowKey(row), dataset.getColumnKey(column)); entities.add(entity); + } + /** + * Adds an entity to the collection. + * + * @param entities the entity collection being populated. + * @param hotspot the entity area (if <code>null</code> a default will be + * used). + * @param dataset the dataset. + * @param row the series. + * @param column the item. + * @param entityX the entity's center x-coordinate in user space (only + * used if <code>area</code> is <code>null</code>). + * @param entityY the entity's center y-coordinate in user space (only + * used if <code>area</code> is <code>null</code>). + * + * @since 1.0.13 + */ + protected void addEntity(EntityCollection entities, Shape hotspot, + CategoryDataset dataset, int row, int column, + double entityX, double entityY) { + if (!getItemCreateEntity(row, column)) { + return; + } + Shape s = hotspot; + if (hotspot == null) { + double r = getDefaultEntityRadius(); + double w = r * 2; + if (getPlot().getOrientation() == PlotOrientation.VERTICAL) { + s = new Ellipse2D.Double(entityX - r, entityY - r, w, w); + } + else { + s = new Ellipse2D.Double(entityY - r, entityX - r, w, w); + } + } + String tip = null; + CategoryToolTipGenerator generator = getToolTipGenerator(row, column); + if (generator != null) { + tip = generator.generateToolTip(dataset, row, column); + } + String url = null; + CategoryURLGenerator urlster = getURLGenerator(row, column); + if (urlster != null) { + url = urlster.generateURL(dataset, row, column); + } + CategoryItemEntity entity = new CategoryItemEntity(s, tip, url, + dataset, row, column); + entities.add(entity); } } Modified: trunk/source/org/jfree/chart/renderer/xy/AbstractXYItemRenderer.java =================================================================== --- trunk/source/org/jfree/chart/renderer/xy/AbstractXYItemRenderer.java 2009-04-07 07:49:20 UTC (rev 1937) +++ trunk/source/org/jfree/chart/renderer/xy/AbstractXYItemRenderer.java 2009-04-07 08:15:24 UTC (rev 1938) @@ -2,7 +2,7 @@ * JFreeChart : a free chart library for the Java(tm) platform * =========================================================== * - * (C) Copyright 2000-2008, by Object Refinery Limited and Contributors. + * (C) Copyright 2000-2009, by Object Refinery Limited and Contributors. * * Project Info: http://www.jfree.org/jfreechart/index.html * @@ -27,7 +27,7 @@ * --------------------------- * AbstractXYItemRenderer.java * --------------------------- - * (C) Copyright 2002-2008, by Object Refinery Limited and Contributors. + * (C) Copyright 2002-2009, by Object Refinery Limited and Contributors. * * Original Author: David Gilbert (for Object Refinery Limited); * Contributor(s): Richard Atkinson; @@ -107,6 +107,10 @@ * minor API doc update (DG); * 02-Jun-2008 : Added isPointInRect() method (DG); * 17-Jun-2008 : Apply legend shape, font and paint attributes (DG); + * 09-Mar-2009 : Added getAnnotations() method (DG); + * 27-Mar-2009 : Added new findDomainBounds() and findRangeBounds() methods to + * take account of hidden series (DG); + * 01-Apr-2009 : Moved defaultEntityRadius up to superclass (DG); * */ @@ -125,6 +129,8 @@ import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; import java.util.Iterator; import java.util.List; @@ -207,9 +213,6 @@ */ private List foregroundAnnotations; - /** The default radius for the entity 'hotspot' */ - private int defaultEntityRadius; - /** The legend item label generator. */ private XYSeriesLabelGenerator legendItemLabelGenerator; @@ -231,7 +234,6 @@ this.baseURLGenerator = null; this.backgroundAnnotations = new java.util.ArrayList(); this.foregroundAnnotations = new java.util.ArrayList(); - this.defaultEntityRadius = 3; this.legendItemLabelGenerator = new StandardXYSeriesLabelGenerator( "{0}"); } @@ -690,30 +692,21 @@ } /** - * Returns the radius of the circle used for the default entity area - * when no area is specified. + * Returns a collection of the annotations that are assigned to the + * renderer. * - * @return A radius. + * @return A collection of annotations (possibly empty but never + * <code>null</code>). * - * @see #setDefaultEntityRadius(int) + * @since 1.0.13 */ - public int getDefaultEntityRadius() { - return this.defaultEntityRadius; + public Collection getAnnotations() { + List result = new java.util.ArrayList(this.foregroundAnnotations); + result.addAll(this.backgroundAnnotations); + return result; } /** - * Sets the radius of the circle used for the default entity area - * when no area is specified. - * - * @param radius the radius. - * - * @see #getDefaultEntityRadius() - */ - public void setDefaultEntityRadius(int radius) { - this.defaultEntityRadius = radius; - } - - /** * Returns the legend item label generator. * * @return The label generator (never <code>null</code>). @@ -801,11 +794,38 @@ * @see #findRangeBounds(XYDataset) */ public Range findDomainBounds(XYDataset dataset) { - if (dataset != null) { - return DatasetUtilities.findDomainBounds(dataset, false); + return findDomainBounds(dataset, false); + } + + /** + * Returns the lower and upper bounds (range) of the x-values in the + * specified dataset. + * + * @param dataset the dataset (<code>null</code> permitted). + * + * @return The range (<code>null</code> if the dataset is <code>null</code> + * or empty). + * + * @since 1.0.13 + */ + protected Range findDomainBounds(XYDataset dataset, + boolean includeInterval) { + if (dataset == null) { + return null; } + if (getDataBoundsIncludesVisibleSeriesOnly()) { + List visibleSeriesKeys = new ArrayList(); + int seriesCount = dataset.getSeriesCount(); + for (int s = 0; s < seriesCount; s++) { + if (isSeriesVisible(s)) { + visibleSeriesKeys.add(dataset.getSeriesKey(s)); + } + } + return DatasetUtilities.findDomainBounds(dataset, + visibleSeriesKeys, includeInterval); + } else { - return null; + return DatasetUtilities.findDomainBounds(dataset, includeInterval); } } @@ -821,11 +841,56 @@ * @see #findDomainBounds(XYDataset) */ public Range findRangeBounds(XYDataset dataset) { - if (dataset != null) { - return DatasetUtilities.findRangeBounds(dataset, false); + return findRangeBounds(dataset, false); + } + + /** + * Returns the range of values the renderer requires to display all the + * items from the specified dataset. + * + * @param dataset the dataset (<code>null</code> permitted). + * + * @return The range (<code>null</code> if the dataset is <code>null</code> + * or empty). + * + * @since 1.0.13 + */ + protected Range findRangeBounds(XYDataset dataset, + boolean includeInterval) { + if (dataset == null) { + return null; } + if (getDataBoundsIncludesVisibleSeriesOnly()) { + List visibleSeriesKeys = new ArrayList(); + int seriesCount = dataset.getSeriesCount(); + for (int s = 0; s < seriesCount; s++) { + if (isSeriesVisible(s)) { + visibleSeriesKeys.add(dataset.getSeriesKey(s)); + } + } + // the bounds should be calculated using just the items within + // the current range of the x-axis...if there is one + Range xRange = null; + XYPlot p = getPlot(); + if (p != null) { + ValueAxis xAxis = null; + int index = p.getIndexOf(this); + if (index >= 0) { + xAxis = plot.getDomainAxisForDataset(index); + } + if (xAxis != null) { + xRange = xAxis.getRange(); + } + } + if (xRange == null) { + xRange = new Range(Double.NEGATIVE_INFINITY, + Double.POSITIVE_INFINITY); + } + return DatasetUtilities.findRangeBounds(dataset, + visibleSeriesKeys, xRange, includeInterval); + } else { - return null; + return DatasetUtilities.findRangeBounds(dataset, includeInterval); } } @@ -1603,9 +1668,6 @@ if (!this.backgroundAnnotations.equals(that.backgroundAnnotations)) { return false; } - if (this.defaultEntityRadius != that.defaultEntityRadius) { - return false; - } if (!ObjectUtilities.equal(this.legendItemLabelGenerator, that.legendItemLabelGenerator)) { return false; @@ -1787,16 +1849,13 @@ } Shape hotspot = area; if (hotspot == null) { - double w = this.defaultEntityRadius * 2; + double r = getDefaultEntityRadius(); + double w = r * 2; if (getPlot().getOrientation() == PlotOrientation.VERTICAL) { - hotspot = new Ellipse2D.Double( - entityX - this.defaultEntityRadius, - entityY - this.defaultEntityRadius, w, w); + hotspot = new Ellipse2D.Double(entityX - r, entityY - r, w, w); } else { - hotspot = new Ellipse2D.Double( - entityY - this.defaultEntityRadius, - entityX - this.defaultEntityRadius, w, w); + hotspot = new Ellipse2D.Double(entityY - r, entityX - r, w, w); } } String tip = null; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |