⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 piechartbean.java

📁 提供 精通Java Web动态图表编程 一书的源代码, 大家赶快下载呀
💻 JAVA
字号:
//	Fig. 9.2_05_01: PieChartBean.java
//	功能: 生成普通饼图的JavaBean

package chart;

import java.util.*;
import java.awt.*;
import java.text.*;
import java.io.*;
import java.awt.image.*;
import java.awt.geom.*;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.imageio.*;

public class PieChartBean extends HttpServlet
{
  HttpServletResponse response;

  static int width = 500, height = 400;
  static int plotBasePointX = 20, plotBasePointY = 40;
  static int plotWidth = width - 2 * plotBasePointX;
  static int plotHeight = height - 2 * plotBasePointY;


  private String domainAxisLabel = "";
  private String rangeAxisLabel = "";
  private String chartTitle = "";

  String series[] =
  {
    // 饼图不需要series变量
    //"Python", "JAVA", "C#", "Perl", "PHP"
  };
  String category[] =
  {
    "Python", "JAVA", "C#", "Perl", "PHP"
  };

  Color paintColor[] =
  {
    new Color(255, 0, 66), new Color(255, 169, 66), new Color(33, 255, 66), 
    new Color(33, 0, 255), new Color(99, 99, 0), new Color(255, 187, 151)
  };

  private Graphics2D g2d = null;
  private BufferedImage image = null;

  public PieChartBean()
  {
    // 默认构造器
  }

  public PieChartBean(HttpServletResponse response)
  {
    this.response = response;
  }

  // 设置横轴标题
  public void setDomainAxisLabel(String domainAxisLabel)
  {
    this.domainAxisLabel = domainAxisLabel;
  }

  // 设置纵轴标题
  public void setRangeAxisLabel(String rangeAxisLabel)
  {
    this.rangeAxisLabel = rangeAxisLabel;
  }

  // 设置图表标题
  public void setChartTitle(String chartTitle)
  {
    this.chartTitle = chartTitle;
  }

  public void initialize()
  {
    image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    g2d = image.createGraphics();
    g2d.setColor(Color.white);
    g2d.fillRect(0, 0, width, height);
  }

  // 绘制整个图表的背景
  public void drawBackground()
  {
    // 阴影和图表之间的偏移量
    int shadowOffset = 5;

    g2d.setColor(Color.white);
    g2d.fillRect(0, 0, width, height);

    // 打开反锯齿功能,用于平滑处理相关背景
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON);

    // 绘制阴影,由灰色渐进圆角矩形组成
    GradientPaint grayGP = new GradientPaint(0, 0, Color.GRAY, width, height, 
      new Color(218, 214, 212), false);
    g2d.setPaint(grayGP);

    RoundRectangle2D.Float bgRR = new RoundRectangle2D.Float(shadowOffset, 
      shadowOffset, width - shadowOffset, height - shadowOffset, 50, 50);
    g2d.fill(bgRR);

    // 绘制圆角矩形背景
    GradientPaint chartGP = new GradientPaint(0, 0, new Color(20, 47, 92), 0, 
      height, new Color(88, 112, 146), false);
    g2d.setPaint(chartGP);
    g2d.fillRoundRect(0, 0, width - shadowOffset, height - shadowOffset, 50, 50);

    // 绘制深蓝色圆角矩形轮廓
    BasicStroke bs = new BasicStroke(2.0f);
    g2d.setStroke(bs);
    g2d.setPaint(new Color(55, 71, 105));
    g2d.drawRoundRect(0, 0, width - shadowOffset, height - shadowOffset, 50, 50);

    // 绘制图表绘图区域背景的阴影效果
    Rectangle2D.Float drawArea = new Rectangle2D.Float(plotBasePointX + 3, 
      plotBasePointY + 3, plotWidth, plotHeight);
    g2d.setPaint(new Color(27, 60, 105));
    g2d.fill(drawArea);

    // 填充图表绘图区域背景
    GradientPaint plotGP = new GradientPaint(120, 60, new Color(151, 205, 235), 
      120, 300, Color.WHITE, false);
    g2d.setPaint(plotGP);

    drawArea = 
      new Rectangle2D.Float(plotBasePointX, plotBasePointY, plotWidth, plotHeight);
    g2d.fill(drawArea);

    // 描绘图表绘图区域的轮廓
    bs = new BasicStroke(1.2f);
    g2d.setStroke(bs);
    g2d.setPaint(Color.BLACK);
    g2d.draw(drawArea);

    // 重新关闭反锯齿功能
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_OFF);
  }

  // 绘制图表标题
  public void drawTitle()
  {
    g2d.setFont(new Font("华文隶书", Font.PLAIN, 25));
    int titleLength = g2d.getFontMetrics().stringWidth(chartTitle);

    g2d.setColor(new Color(252, 171, 54));
    g2d.drawString(chartTitle, (width - titleLength) / 2, 25);
  }

  // 绘制图表主体部分
  public void drawChart()
  {
    // 获得当前的AffineTransform对象
    AffineTransform old = g2d.getTransform();
    g2d.translate(plotBasePointX, plotBasePointY);

    // 定义圆弧
    Arc2D.Double arc2d = new Arc2D.Double();

    double startAngle = 30.0, arcAngle = 0.0;
    double rectWidth = 6 * plotWidth / 10, rectHeight = 3 * plotHeight / 4;
    Point2D.Double p2d = 
      new Point2D.Double((width - rectWidth) / 2-plotBasePointX, plotBasePointY);
    int arcType = Arc2D.PIE;

    double data[] = new double[category.length];
    double sum = 0.0;
    double proportion = 0.0;

    // 生成饼图所需的随机数据
    for (int i = 0; i < category.length; i++)
    {
      data[i] = 50+Math.random() * 150;
      sum += data[i];
    }

    for (int i = 0; i < category.length; i++)
    {
      // 打开反锯齿功能,绘制圆弧
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON);
      arcAngle = data[i] * 360 / sum;
      proportion = data[i] / sum * 100;

      g2d.setColor(paintColor[i % category.length]);
      arc2d = new Arc2D.Double(p2d.x, p2d.y, rectWidth, rectHeight,
        startAngle, arcAngle, arcType);

      // 填充圆弧
      g2d.fill(arc2d);

      // 描绘圆弧轮廓
      g2d.setStroke(new BasicStroke(1.2f));
      g2d.setPaint(Color.GRAY);
      g2d.draw(arc2d);

      // 更新圆弧的起始角度
      startAngle += arcAngle;

      // 格式化浮点数的输出格式
      DecimalFormat twoDigits = new DecimalFormat("0.00");
      g2d.setFont(new Font("Courier New", Font.PLAIN, 12));

      // 关闭反锯齿功能,绘制说明文字
      g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_OFF);

      // 绘制说明文字
      drawTips(twoDigits.format(proportion) + "%", Color.BLACK, arc2d, g2d);
    }

    // 恢复以前的AffineTransform对象
    g2d.setTransform(old);

    // 绘制坐标轴图例
    drawLegend(category);
  }

  // 绘制图例
  public void drawLegend(String[]legendItems)
  {
    g2d.setStroke(new BasicStroke());
    g2d.setFont(new Font("宋体", Font.PLAIN, 12));
    g2d.setPaint(Color.WHITE);

    int itemHeight = g2d.getFontMetrics().getAscent();
    int itemWidth[] = new int[legendItems.length];

    // 图例的长度
    int legendWidth = 20;

    for (int i = 0; i < legendItems.length; i++)
    {
      itemWidth[i] = g2d.getFontMetrics().stringWidth(legendItems[i]);

      if (i != legendItems.length - 1)
      {
        legendWidth += itemWidth[i] + 20;
      }
      else
      {
        legendWidth += itemWidth[i] + 15;
      }
    }

    g2d.fillRect((width - legendWidth) / 2, height - 25, legendWidth, itemHeight + 5);
    g2d.setColor(Color.BLACK);
    g2d.drawRect((width - legendWidth) / 2, height - 25, legendWidth, itemHeight + 5);
    int itemAnchor = (width - legendWidth) / 2+10;
    g2d.setColor(Color.BLACK);
    for (int i = 0; i < legendItems.length; i++)
    {
      g2d.setColor(paintColor[i % paintColor.length]);
      g2d.fillRect(itemAnchor, height - 20, 10, 10);
      g2d.setColor(Color.BLACK);
      g2d.drawString(legendItems[i], itemAnchor + 15, height - 12);
      itemAnchor += itemWidth[i] + 20;
    }
  }

  // 绘制坐标轴标题
  public void drawAxisLabel()
  {
    g2d.setFont(new Font("楷体_GB2312", Font.BOLD, 18));
    g2d.setPaint(new Color(242, 159, 25));
    int labelHeight = g2d.getFontMetrics().getAscent();

    int labelLength = g2d.getFontMetrics().stringWidth(rangeAxisLabel);

    // 获得当前的AffineTransform对象
    AffineTransform old = g2d.getTransform();

    g2d.translate(40, (height + labelLength) / 2);
    g2d.rotate( - Math.PI / 2);
    g2d.drawString(rangeAxisLabel, 0, 0);

    // 恢复以前的AffineTransform对象
    g2d.setTransform(old);

    labelLength = g2d.getFontMetrics().stringWidth(domainAxisLabel);
    g2d.drawString(domainAxisLabel, (width - labelLength) / 2, 370);
  }

  // 绘制饼图的说明
  public void drawTips(String tips, Color color, Arc2D.Double arc2d, Graphics2D g2d)
  {
    Arc2D.Double position = arc2d;

    position.setAngleExtent(arc2d.getAngleExtent() / 2);
    position.x = arc2d.x - 15;
    position.y = arc2d.y - 15;
    position.width = arc2d.getWidth() + 50;
    position.height = arc2d.getHeight() + 50;
    Point2D.Double startPoint = (Point2D.Double)position.getStartPoint();
    Point2D.Double endPoint = (Point2D.Double)position.getEndPoint();

    g2d.setPaint(color);

    int stringLength = g2d.getFontMetrics().stringWidth(tips);

    if (endPoint.x <= arc2d.getCenterX())
    {
      g2d.drawString(tips, (float)endPoint.x - stringLength, (float)endPoint.y);
    }
    else
    {
      g2d.drawString(tips, (float)endPoint.x, (float)endPoint.y);
    }
  }

  public void getChart()
  {
    this.initialize();
    this.drawBackground();
    this.drawTitle();
    this.drawChart();
    this.drawAxisLabel();

    // 部署图形环境
    g2d.dispose();

    // 输出图像到WEB页面
    try
    {
      this.response.reset();
      this.response.setContentType("image/png");
      OutputStream sos = response.getOutputStream();
      ImageIO.write(image, "PNG", sos);

      sos.close();
    }
    catch (Exception e)
    {
      System.out.println("图表输出错误!");
    }
  }

}

/**************************************************************************
 * (C) Copyright 2004-2005 by Jingkui Zhong(钟京馗) and Huan Tang(唐桓).  *
 * All Rights Reserved.                                                   *
 *                                                                        *
 * DISCLAIMER: The authors of this code have used their                   *
 * best efforts in preparing the code. These efforts include the          *
 * development, research, and testing of the theories and programs        *
 * to determine their effectiveness. The authors and publisher make       *
 * no warranty of any kind, expressed or implied, with regard to these    *
 * programs or to the documentation contained in these codes. The authors *
 * shall not be liable in any event for incidental or consequential       *
 * damages in connection with, or arising out of, the furnishing,         *
 * performance, or use of these programs.                                 *
 **************************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -