?? pie3dplot.java
字號:
/* ======================================
* JFreeChart : a free Java chart library
* ======================================
*
* Project Info: http://www.jfree.org/jfreechart/index.html
* Project Lead: David Gilbert (david.gilbert@object-refinery.com);
*
* (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
*
* 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., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* --------------
* PiePlot3D.java
* --------------
* (C) Copyright 2000-2003, by Object Refinery and Contributors.
*
* Original Author: Tomer Peretz;
* Contributor(s): Richard Atkinson;
* David Gilbert (for Object Refinery Limited);
* Xun Kang;
* Christian W. Zuckschwerdt;
* Arnaud Lelievre;
*
* $Id: Pie3DPlot.java,v 1.13 2003/09/09 10:22:40 mungady Exp $
*
* Changes
* -------
* 21-Jun-2002 : Version 1;
* 31-Jul-2002 : Modified to use startAngle and direction, drawing modified so that charts
* render with foreground alpha < 1.0 (DG);
* 05-Aug-2002 : Small modification to draw method to support URLs for HTML image maps (RA);
* 26-Sep-2002 : Fixed errors reported by Checkstyle (DG);
* 18-Oct-2002 : Added drawing bug fix sent in by Xun Kang, and made a couple of other related
* fixes (DG);
* 30-Oct-2002 : Changed the PieDataset interface. Fixed another drawing bug (DG);
* 12-Nov-2002 : Fixed null pointer exception for zero or negative values (DG);
* 07-Mar-2003 : Modified to pass pieIndex on to PieSectionEntity (DG);
* 21-Mar-2003 : Added workaround for bug id 620031 (DG);
* 26-Mar-2003 : Implemented Serializable (DG);
* 30-Jul-2003 : Modified entity constructor (CZ);
* 29-Aug-2003 : Small changes for API updates in PiePlot class (DG);
* 02-Sep-2003 : Fixed bug where the 'no data' message is not displayed (DG);
* 08-Sep-2003 : Added internationalization via use of properties resourceBundle (RFE 690236) (AL);
*
*/
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.Graphics2D;
import java.awt.Insets;
import java.awt.Paint;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.Arc2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.entity.EntityCollection;
import org.jfree.chart.entity.PieSectionEntity;
import org.jfree.chart.labels.StandardPieItemLabelGenerator;
import org.jfree.data.DatasetUtilities;
import org.jfree.data.PieDataset;
/**
* A plot that displays data in the form of a 3D pie chart, using data from
* any class that implements the {@link PieDataset} interface.
* <P>
* Although this class extends {@link PiePlot}, it does not currently support
* exploded sections or the display of multiple pie charts within one plot.
*
* @author Tomer Peretz
*/
public class Pie3DPlot extends PiePlot implements Serializable {
/** The factor of the depth of the pie from the plot height */
private double depthFactor = 0.2;
/**
* Creates a 3D pie chart with default attributes.
*
* @param data the data for the chart.
*/
public Pie3DPlot(PieDataset data) {
super(data);
setCircularAttribute(false);
}
/**
* Sets the factor of the pie depth from the plot height.
*
* @param newDepthFactor the new depth factor.
*/
public void setDepthFactor(double newDepthFactor) {
this.depthFactor = newDepthFactor;
}
/**
* The depth factor for the chart.
*
* @return the current depth factor.
*/
public double getDepthFactor () {
return depthFactor;
}
/**
* Draws the plot on a Java 2D graphics device (such as the screen or a printer).
*
* @param g2 the graphics device.
* @param plotArea the area within which the plot should be drawn.
* @param info collects info about the drawing.
*/
public void draw(Graphics2D g2, Rectangle2D plotArea, ChartRenderingInfo info) {
Shape savedClip = g2.getClip();
Rectangle2D clipArea = savedClip != null
? savedClip.getBounds2D().createIntersection(plotArea)
: plotArea;
// adjust for insets...
Insets insets = getInsets();
if (insets != null) {
plotArea.setRect(plotArea.getX() + insets.left,
plotArea.getY() + insets.top,
plotArea.getWidth() - insets.left - insets.right,
plotArea.getHeight() - insets.top - insets.bottom);
}
if (info != null) {
info.setPlotArea(plotArea);
info.setDataArea(plotArea);
}
// adjust the plot area by the interior spacing value
double gapPercent = getInteriorGap();
double gapHorizontal = plotArea.getWidth() * gapPercent;
double gapVertical = plotArea.getHeight() * gapPercent;
double pieX = plotArea.getX() + gapHorizontal / 2;
double pieY = plotArea.getY() + gapVertical / 2;
double pieW = plotArea.getWidth() - gapHorizontal;
double pieH = plotArea.getHeight() - gapVertical;
if (isCircular()) {
double min = Math.min(pieW, pieH) / 2;
pieX = (pieX + pieX + pieW) / 2 - min;
pieY = (pieY + pieY + pieH) / 2 - min;
pieW = 2 * min;
pieH = 2 * min;
}
Rectangle2D explodedPieArea = new Rectangle2D.Double(pieX, pieY, pieW, pieH);
double radiusPercent = getRadius();
double explodeHorizontal = (1 - radiusPercent) * pieW;
double explodeVertical = (1 - radiusPercent) * pieH;
Rectangle2D pieArea = new Rectangle2D.Double(pieX + explodeHorizontal / 2,
pieY + explodeVertical / 2,
pieW - explodeHorizontal,
pieH - explodeVertical);
drawBackground(g2, plotArea);
// get the data source - return if null;
PieDataset dataset = getPieDataset();
if (DatasetUtilities.isEmptyOrNull(getDataset())) {
drawNoDataMessage(g2, plotArea);
g2.setClip(savedClip);
drawOutline(g2, plotArea);
return;
}
// if too any elements
if (dataset.getKeys().size() > plotArea.getWidth()) {
String text = "Too many elements";
Font sfont = new Font("dialog", Font.BOLD, 10);
g2.setFont(sfont);
int stringWidth
= (int) sfont.getStringBounds(text, g2.getFontRenderContext()).getWidth();
g2.drawString(text,
(int) (plotArea.getX() + (plotArea.getWidth() - stringWidth) / 2),
(int) (plotArea.getY() + (plotArea.getHeight() / 2)));
return;
}
// if we are drawing a perfect circle, we need to readjust the top left
// coordinates of the drawing area for the arcs to arrive at this
// effect.
if (isCircular()) {
double min = Math.min(plotArea.getWidth(), plotArea.getHeight()) / 2;
plotArea = new Rectangle2D.Double(plotArea.getCenterX() - min,
plotArea.getCenterY() - min, 2 * min, 2 * min);
}
// get a list of keys...
List sectionKeys = dataset.getKeys();
if (sectionKeys.size() == 0) {
return;
}
// establish the coordinates of the top left corner of the drawing area
double arcX = pieArea.getX();
double arcY = pieArea.getY();
g2.clip(clipArea);
Composite originalComposite = g2.getComposite();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, getForegroundAlpha()));
double totalValue = DatasetUtilities.getPieDatasetTotal(dataset);
double runningTotal = 0;
int depth = (int) (pieArea.getHeight() * depthFactor);
if (depth < 0) {
return; // if depth is negative don't draw anything
}
ArrayList arcList = new ArrayList();
Arc2D.Double arc;
Paint paint;
Paint outlinePaint;
Iterator iterator = sectionKeys.iterator();
while (iterator.hasNext()) {
Comparable currentKey = (Comparable) iterator.next();
Number dataValue = dataset.getValue(currentKey);
double value = dataValue.doubleValue();
if (value <= 0) {
arcList.add(null);
continue;
}
double startAngle = getStartAngle();
double direction = getDirection().getFactor();
double angle1 = startAngle + (direction * (runningTotal * 360)) / totalValue;
double angle2 = startAngle + (direction * (runningTotal + value) * 360) / totalValue;
if (Math.abs(angle2 - angle1) > getMinimumArcAngleToDraw()) {
arcList.add(new Arc2D.Double(arcX,
arcY + depth,
pieArea.getWidth(),
pieArea.getHeight() - depth,
angle1,
angle2 - angle1,
Arc2D.PIE));
}
else {
arcList.add(null);
}
runningTotal += value;
}
Shape oldClip = g2.getClip();
Ellipse2D top = new Ellipse2D.Double(pieArea.getX(),
pieArea.getY(),
pieArea.getWidth(),
pieArea.getHeight() - depth);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -