/* ===========================================================
* JFreeChart : a free chart library for the Java(tm) platform
* ===========================================================
*
* (C) Copyright 2000-2007, by Object Refinery Limited and Contributors.
*
* Project Info: http://www.jfree.org/jfreechart/index.html
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
* USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* -----------------------------
* DefaultPolarItemRenderer.java
* -----------------------------
* (C) Copyright 2004, 2006, 2007, by Solution Engineering, Inc. and
* Contributors.
*
* Original Author: Daniel Bridenbecker, Solution Engineering, Inc.;
* Contributor(s): David Gilbert (for Object Refinery Limited);
*
* Changes
* -------
* 19-Jan-2004 : Version 1, contributed by DB with minor changes by DG (DG);
* 15-Jul-2004 : Switched getX() with getXValue() and getY() with
* getYValue() (DG);
* 04-Oct-2004 : Renamed BooleanUtils --> BooleanUtilities (DG);
* 20-Apr-2005 : Update for change to LegendItem class (DG);
* ------------- JFREECHART 1.0.x ---------------------------------------------
* 04-Aug-2006 : Implemented equals() and clone() (DG);
* 02-Feb-2007 : Removed author tags from all over JFreeChart sources (DG);
* 14-Mar-2007 : Fixed clone() method (DG);
* 04-May-2007 : Fixed lookup for series paint and stroke (DG);
* 18-May-2007 : Set dataset for LegendItem (DG);
*
*/
package org.jfree.chart.renderer;
import java.awt.AlphaComposite;
import java.awt.Composite;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.LegendItem;
import org.jfree.chart.axis.NumberTick;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.DrawingSupplier;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.PolarPlot;
import org.jfree.data.xy.XYDataset;
import org.jfree.text.TextUtilities;
import org.jfree.ui.TextAnchor;
import org.jfree.util.BooleanList;
import org.jfree.util.BooleanUtilities;
/**
* A renderer that can be used with the {@link PolarPlot} class.
*/
public class DefaultPolarItemRenderer extends AbstractRenderer
implements PolarItemRenderer {
/** The plot that the renderer is assigned to. */
private PolarPlot plot;
/** Flags that control whether the renderer fills each series or not. */
private BooleanList seriesFilled;
/**
* Creates a new instance of DefaultPolarItemRenderer
*/
public DefaultPolarItemRenderer() {
this.seriesFilled = new BooleanList();
}
/**
* Set the plot associated with this renderer.
*
* @param plot the plot.
*
* @see #getPlot()
*/
public void setPlot(PolarPlot plot) {
this.plot = plot;
}
/**
* Return the plot associated with this renderer.
*
* @return The plot.
*
* @see #setPlot(PolarPlot)
*/
public PolarPlot getPlot() {
return this.plot;
}
/**
* Returns the drawing supplier from the plot.
*
* @return The drawing supplier.
*/
public DrawingSupplier getDrawingSupplier() {
DrawingSupplier result = null;
PolarPlot p = getPlot();
if (p != null) {
result = p.getDrawingSupplier();
}
return result;
}
/**
* Returns <code>true</code> if the renderer should fill the specified
* series, and <code>false</code> otherwise.
*
* @param series the series index (zero-based).
*
* @return A boolean.
*/
public boolean isSeriesFilled(int series) {
boolean result = false;
Boolean b = this.seriesFilled.getBoolean(series);
if (b != null) {
result = b.booleanValue();
}
return result;
}
/**
* Sets a flag that controls whether or not a series is filled.
*
* @param series the series index.
* @param filled the flag.
*/
public void setSeriesFilled(int series, boolean filled) {
this.seriesFilled.setBoolean(series, BooleanUtilities.valueOf(filled));
}
/**
* Plots the data for a given series.
*
* @param g2 the drawing surface.
* @param dataArea the data area.
* @param info collects plot rendering info.
* @param plot the plot.
* @param dataset the dataset.
* @param seriesIndex the series index.
*/
public void drawSeries(Graphics2D g2,
Rectangle2D dataArea,
PlotRenderingInfo info,
PolarPlot plot,
XYDataset dataset,
int seriesIndex) {
Polygon poly = new Polygon();
int numPoints = dataset.getItemCount(seriesIndex);
for (int i = 0; i < numPoints; i++) {
double theta = dataset.getXValue(seriesIndex, i);
double radius = dataset.getYValue(seriesIndex, i);
Point p = plot.translateValueThetaRadiusToJava2D(theta, radius,
dataArea);
poly.addPoint(p.x, p.y);
}
g2.setPaint(lookupSeriesPaint(seriesIndex));
g2.setStroke(lookupSeriesStroke(seriesIndex));
if (isSeriesFilled(seriesIndex)) {
Composite savedComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.5f));
g2.fill(poly);
g2.setComposite(savedComposite);
}
else {
g2.draw(poly);
}
}
/**
* Draw the angular gridlines - the spokes.
*
* @param g2 the drawing surface.
* @param plot the plot.
* @param ticks the ticks.
* @param dataArea the data area.
*/
public void drawAngularGridLines(Graphics2D g2,
PolarPlot plot,
List ticks,
Rectangle2D dataArea) {
g2.setFont(plot.getAngleLabelFont());
g2.setStroke(plot.getAngleGridlineStroke());
g2.setPaint(plot.getAngleGridlinePaint());
double axisMin = plot.getAxis().getLowerBound();
double maxRadius = plot.getMaxRadius();
Point center = plot.translateValueThetaRadiusToJava2D(axisMin, axisMin,
dataArea);
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
NumberTick tick = (NumberTick) iterator.next();
Point p = plot.translateValueThetaRadiusToJava2D(
tick.getNumber().doubleValue(), maxRadius, dataArea);
g2.setPaint(plot.getAngleGridlinePaint());
g2.drawLine(center.x, center.y, p.x, p.y);
if (plot.isAngleLabelsVisible()) {
int x = p.x;
int y = p.y;
g2.setPaint(plot.getAngleLabelPaint());
TextUtilities.drawAlignedString(tick.getText(), g2, x, y,
TextAnchor.CENTER);
}
}
}
/**
* Draw the radial gridlines - the rings.
*
* @param g2 the drawing surface.
* @param plot the plot.
* @param radialAxis the radial axis.
* @param ticks the ticks.
* @param dataArea the data area.
*/
public void drawRadialGridLines(Graphics2D g2,
PolarPlot plot,
ValueAxis radialAxis,
List ticks,
Rectangle2D dataArea) {
g2.setFont(radialAxis.getTickLabelFont());
g2.setPaint(plot.getRadiusGridlinePaint());
g2.setStroke(plot.getRadiusGridlineStroke());
double axisMin = radialAxis.getLowerBound();
Point center = plot.translateValueThetaRadiusToJava2D(axisMin, axisMin,
dataArea);
Iterator iterator = ticks.iterator();
while (iterator.hasNext()) {
NumberTick tick = (NumberTick) iterator.next();
Point p = plot.translateValueThetaRadiusToJava2D(90.0,
tick.getNumber().doubleValue(), dataArea);
int r = p.x - center.x;
int upperLeftX = center.x - r;
int upperLeftY = center.y - r;
int d = 2 * r;
Ellipse2D ring = new Ellipse2D.Double(upperLeftX, upperLeftY, d, d);
g2.setPaint(plot.getRadiusGridlinePaint());
g2.draw(ring);
}
}
/**
* Return the legend for the given series.
*
* @param series the series index.
*
* @return The legend item.
*/
public LegendItem getLegendItem(int series) {
LegendItem result = null;
PolarPlot polarPlot = getPlot();
if (polarPlot != null) {
XYDataset dataset = polarPlot.getDataset();
if (dataset != null) {
String label = dataset.getSeriesKey(series).toString();
String description = label;
Shape shape = lookupSeriesShape(series);
Paint paint = lookupSeriesPaint(series);
Paint outlinePaint = lookupSeriesOutlinePaint(series);
Stroke outlineStroke = lookupSeriesOutlineStroke(series);
result = new LegendItem(label, description, null, null,
shape, paint, outlineStroke, outlinePaint);
result.setDataset(dataset);
}
}
return result;
}
/**
* Tests this renderer for equality with an arbitrary object.
*
* @param obj the object (<code>null</code> not permitted).
*
* @return <code>true</code> if this renderer is equal to <code>obj</code>,
* and <code>false</code> otherwise.
*/
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof DefaultPolarItemRenderer)) {
return false;
}
DefaultPolarItemRenderer that = (DefaultPolarItemRenderer) obj;
if (!this.seriesFilled.equals(that.seriesFilled)) {
return false;
}
return super.equals(obj);
}
/**
* Returns a clone of the renderer.
*
* @return A clone.
*
* @throws CloneNotSupportedException if the renderer cannot be cloned.
*/
public Object clone() throws CloneNotSupportedException {
DefaultPolarItemRenderer clone
= (DefaultPolarItemRenderer) super.clone();
clone.seriesFilled = (BooleanList) this.seriesFilled.clone();
return clone;
}
}
|