📄 polarplot.java
字号:
/* ===========================================================
* 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.]
*
* --------------
* PolarPlot.java
* --------------
* (C) Copyright 2004-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);
* 07-Apr-2004 : Changed text bounds calculation (DG);
* 05-May-2005 : Updated draw() method parameters (DG);
* 09-Jun-2005 : Fixed getDataRange() and equals() methods (DG);
* 25-Oct-2005 : Implemented Zoomable (DG);
* ------------- JFREECHART 1.0.x ---------------------------------------------
* 07-Feb-2007 : Fixed bug 1599761, data value less than axis minimum (DG);
* 21-Mar-2007 : Fixed serialization bug (DG);
* 24-Sep-2007 : Implemented new zooming methods (DG);
*
*/
package org.jfree.chart.plot;
import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import org.jfree.chart.LegendItem;
import org.jfree.chart.LegendItemCollection;
import org.jfree.chart.axis.AxisState;
import org.jfree.chart.axis.NumberTick;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.event.PlotChangeEvent;
import org.jfree.chart.event.RendererChangeEvent;
import org.jfree.chart.event.RendererChangeListener;
import org.jfree.chart.renderer.PolarItemRenderer;
import org.jfree.data.Range;
import org.jfree.data.general.DatasetChangeEvent;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.xy.XYDataset;
import org.jfree.io.SerialUtilities;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;
import org.jfree.util.ObjectUtilities;
import org.jfree.util.PaintUtilities;
/**
* Plots data that is in (theta, radius) pairs where
* theta equal to zero is due north and increases clockwise.
*/
public class PolarPlot extends Plot implements ValueAxisPlot, Zoomable,
RendererChangeListener, Cloneable, Serializable {
/** For serialization. */
private static final long serialVersionUID = 3794383185924179525L;
/** The default margin. */
private static final int MARGIN = 20;
/** The annotation margin. */
private static final double ANNOTATION_MARGIN = 7.0;
/** The default grid line stroke. */
public static final Stroke DEFAULT_GRIDLINE_STROKE = new BasicStroke(
0.5f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL,
0.0f, new float[]{2.0f, 2.0f}, 0.0f);
/** The default grid line paint. */
public static final Paint DEFAULT_GRIDLINE_PAINT = Color.gray;
/** The resourceBundle for the localization. */
protected static ResourceBundle localizationResources
= ResourceBundle.getBundle("org.jfree.chart.plot.LocalizationBundle");
/** The angles that are marked with gridlines. */
private List angleTicks;
/** The axis (used for the y-values). */
private ValueAxis axis;
/** The dataset. */
private XYDataset dataset;
/**
* Object responsible for drawing the visual representation of each point
* on the plot.
*/
private PolarItemRenderer renderer;
/** A flag that controls whether or not the angle labels are visible. */
private boolean angleLabelsVisible = true;
/** The font used to display the angle labels - never null. */
private Font angleLabelFont = new Font("SansSerif", Font.PLAIN, 12);
/** The paint used to display the angle labels. */
private transient Paint angleLabelPaint = Color.black;
/** A flag that controls whether the angular grid-lines are visible. */
private boolean angleGridlinesVisible;
/** The stroke used to draw the angular grid-lines. */
private transient Stroke angleGridlineStroke;
/** The paint used to draw the angular grid-lines. */
private transient Paint angleGridlinePaint;
/** A flag that controls whether the radius grid-lines are visible. */
private boolean radiusGridlinesVisible;
/** The stroke used to draw the radius grid-lines. */
private transient Stroke radiusGridlineStroke;
/** The paint used to draw the radius grid-lines. */
private transient Paint radiusGridlinePaint;
/** The annotations for the plot. */
private List cornerTextItems = new ArrayList();
/**
* Default constructor.
*/
public PolarPlot() {
this(null, null, null);
}
/**
* Creates a new plot.
*
* @param dataset the dataset (<code>null</code> permitted).
* @param radiusAxis the radius axis (<code>null</code> permitted).
* @param renderer the renderer (<code>null</code> permitted).
*/
public PolarPlot(XYDataset dataset,
ValueAxis radiusAxis,
PolarItemRenderer renderer) {
super();
this.dataset = dataset;
if (this.dataset != null) {
this.dataset.addChangeListener(this);
}
this.angleTicks = new java.util.ArrayList();
this.angleTicks.add(new NumberTick(new Double(0.0), "0",
TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
this.angleTicks.add(new NumberTick(new Double(45.0), "45",
TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
this.angleTicks.add(new NumberTick(new Double(90.0), "90",
TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
this.angleTicks.add(new NumberTick(new Double(135.0), "135",
TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
this.angleTicks.add(new NumberTick(new Double(180.0), "180",
TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
this.angleTicks.add(new NumberTick(new Double(225.0), "225",
TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
this.angleTicks.add(new NumberTick(new Double(270.0), "270",
TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
this.angleTicks.add(new NumberTick(new Double(315.0), "315",
TextAnchor.CENTER, TextAnchor.CENTER, 0.0));
this.axis = radiusAxis;
if (this.axis != null) {
this.axis.setPlot(this);
this.axis.addChangeListener(this);
}
this.renderer = renderer;
if (this.renderer != null) {
this.renderer.setPlot(this);
this.renderer.addChangeListener(this);
}
this.angleGridlinesVisible = true;
this.angleGridlineStroke = DEFAULT_GRIDLINE_STROKE;
this.angleGridlinePaint = DEFAULT_GRIDLINE_PAINT;
this.radiusGridlinesVisible = true;
this.radiusGridlineStroke = DEFAULT_GRIDLINE_STROKE;
this.radiusGridlinePaint = DEFAULT_GRIDLINE_PAINT;
}
/**
* Add text to be displayed in the lower right hand corner and sends a
* {@link PlotChangeEvent} to all registered listeners.
*
* @param text the text to display (<code>null</code> not permitted).
*
* @see #removeCornerTextItem(String)
*/
public void addCornerTextItem(String text) {
if (text == null) {
throw new IllegalArgumentException("Null 'text' argument.");
}
this.cornerTextItems.add(text);
this.notifyListeners(new PlotChangeEvent(this));
}
/**
* Remove the given text from the list of corner text items and
* sends a {@link PlotChangeEvent} to all registered listeners.
*
* @param text the text to remove (<code>null</code> ignored).
*
* @see #addCornerTextItem(String)
*/
public void removeCornerTextItem(String text) {
boolean removed = this.cornerTextItems.remove(text);
if (removed) {
this.notifyListeners(new PlotChangeEvent(this));
}
}
/**
* Clear the list of corner text items and sends a {@link PlotChangeEvent}
* to all registered listeners.
*
* @see #addCornerTextItem(String)
* @see #removeCornerTextItem(String)
*/
public void clearCornerTextItems() {
if (this.cornerTextItems.size() > 0) {
this.cornerTextItems.clear();
this.notifyListeners(new PlotChangeEvent(this));
}
}
/**
* Returns the plot type as a string.
*
* @return A short string describing the type of plot.
*/
public String getPlotType() {
return PolarPlot.localizationResources.getString("Polar_Plot");
}
/**
* Returns the axis for the plot.
*
* @return The radius axis (possibly <code>null</code>).
*
* @see #setAxis(ValueAxis)
*/
public ValueAxis getAxis() {
return this.axis;
}
/**
* Sets the axis for the plot and sends a {@link PlotChangeEvent} to all
* registered listeners.
*
* @param axis the new axis (<code>null</code> permitted).
*/
public void setAxis(ValueAxis axis) {
if (axis != null) {
axis.setPlot(this);
}
// plot is likely registered as a listener with the existing axis...
if (this.axis != null) {
this.axis.removeChangeListener(this);
}
this.axis = axis;
if (this.axis != null) {
this.axis.configure();
this.axis.addChangeListener(this);
}
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns the primary dataset for the plot.
*
* @return The primary dataset (possibly <code>null</code>).
*
* @see #setDataset(XYDataset)
*/
public XYDataset getDataset() {
return this.dataset;
}
/**
* Sets the dataset for the plot, replacing the existing dataset if there
* is one.
*
* @param dataset the dataset (<code>null</code> permitted).
*
* @see #getDataset()
*/
public void setDataset(XYDataset dataset) {
// if there is an existing dataset, remove the plot from the list of
// change listeners...
XYDataset existing = this.dataset;
if (existing != null) {
existing.removeChangeListener(this);
}
// set the new m_Dataset, and register the chart as a change listener...
this.dataset = dataset;
if (this.dataset != null) {
setDatasetGroup(this.dataset.getGroup());
this.dataset.addChangeListener(this);
}
// send a m_Dataset change event to self...
DatasetChangeEvent event = new DatasetChangeEvent(this, this.dataset);
datasetChanged(event);
}
/**
* Returns the item renderer.
*
* @return The renderer (possibly <code>null</code>).
*
* @see #setRenderer(PolarItemRenderer)
*/
public PolarItemRenderer getRenderer() {
return this.renderer;
}
/**
* Sets the item renderer, and notifies all listeners of a change to the
* plot.
* <P>
* If the renderer is set to <code>null</code>, no chart will be drawn.
*
* @param renderer the new renderer (<code>null</code> permitted).
*
* @see #getRenderer()
*/
public void setRenderer(PolarItemRenderer renderer) {
if (this.renderer != null) {
this.renderer.removeChangeListener(this);
}
this.renderer = renderer;
if (this.renderer != null) {
this.renderer.setPlot(this);
}
notifyListeners(new PlotChangeEvent(this));
}
/**
* Returns a flag that controls whether or not the angle labels are visible.
*
* @return A boolean.
*
* @see #setAngleLabelsVisible(boolean)
*/
public boolean isAngleLabelsVisible() {
return this.angleLabelsVisible;
}
/**
* Sets the flag that controls whether or not the angle labels are visible,
* and sends a {@link PlotChangeEvent} to all registered listeners.
*
* @param visible the flag.
*
* @see #isAngleLabelsVisible()
*/
public void setAngleLabelsVisible(boolean visible) {
if (this.angleLabelsVisible != visible) {
this.angleLabelsVisible = visible;
notifyListeners(new PlotChangeEvent(this));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -