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

📄 vbarchartbean.java

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

package chart;

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

public class VBarChartBean extends HttpServlet
{
  HttpServletResponse response;

  static int width = 500, height = 400;
  static int plotWidth = 400, plotHeight = 300;

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

  String series[] =
  {
    "Python", "JAVA", "C#", "Perl", "PHP"
  };
  String category[] =
  {
    "2005年1月", "2005年2月", "2005年3月"
  };

  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 VBarChartBean()
  {
    // 默认构造器
  }

  public VBarChartBean(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(33, 66, 111),
      0, height, new Color(45, 86, 177), 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(83, 33, plotWidth, plotHeight);
    g2d.setPaint(new Color(27, 60, 105));
    g2d.fill(drawArea);

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

    drawArea = new Rectangle2D.Float(80, 30, 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(245, 213, 164));
    g2d.drawString(chartTitle, (width - titleLength) / 2, 22);
  }

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

    // 创建虚线笔划
    float[] dashes = { 3.f };
    BasicStroke bs = new BasicStroke(1.0f, BasicStroke.CAP_ROUND,
      BasicStroke.JOIN_ROUND, 10, dashes, 0);
    g2d.setStroke(bs);
    g2d.setFont(new Font("宋体", Font.PLAIN, 12));

    int stringLength = 0, stringHeight = 0;

    // 横轴上刻度值的数量
    int xTickCounter = category.length;

    // 图表绘制区和纵轴之间的空白
    int plotMargin = plotWidth / (2 * xTickCounter);

    // 横轴上刻度值之间的长度
    int hSpace;
    if (xTickCounter == 1)
    {
      hSpace = plotWidth;
    }
    else
    {
      hSpace = (plotWidth - 2 * plotMargin) / (xTickCounter - 1);
    }


    // 每组直方图之间的空白
    int barOuterMargin = 20;

    // 每组直方图中,每个直方块之间的空白
    int barInnerMargin = 3;

    // 设定直方块的绘制宽度
    int barLength =
      (hSpace - barOuterMargin - series.length * barInnerMargin) / series.length;

    stringHeight = g2d.getFontMetrics().getAscent();
    for (int i = 0; i < xTickCounter; i++)
    {
      // 设置横轴上刻度绘制的横坐标
      int xTickPosition = plotMargin + i * hSpace;

      // 绘制垂直方向虚线
      g2d.setColor(new Color(103, 115, 133));
      g2d.drawLine(xTickPosition, 0, xTickPosition, plotHeight);

      // 绘制横轴上刻度值的说明文字
      stringLength = g2d.getFontMetrics().stringWidth(category[i]);
      g2d.setColor(new Color(246, 213, 164));


      g2d.drawString(category[i], xTickPosition - stringLength / 2,
        plotHeight + stringHeight + 5);

    }

    String str = "";
    str = "";

    // 纵轴上刻度值的数量
    int vTickCounter = 10;

    // 纵轴上刻度值之间的空白
    int vSpace = plotHeight / vTickCounter;

    for (int i = 0; i < vTickCounter; i++)
    {
      // 绘制水平方向虚线
      g2d.setColor(new Color(103, 115, 133));
      g2d.drawLine(0, i * vSpace, plotWidth, i * vSpace);

      // 绘制纵轴上刻度值的说明文字
      str += plotHeight - i * vSpace;
      stringLength = g2d.getFontMetrics().stringWidth(str);
      g2d.setColor(new Color(246, 213, 164));
      g2d.drawString(str,  - 5-stringLength, i * vSpace + stringHeight / 2);
      str = "";
    }

    double[] sales = new double[series.length];
    double totalBarLength = series.length * (barLength + barInnerMargin);

    g2d.setFont(new Font("Courier New", Font.PLAIN, 12));
    for (int i = 0; i < xTickCounter; i++)
    {
      // 初始化绘制数据
      int bookSales = 0;

      for (int j = 0; j < series.length; j++)
      {

        sales[j] = plotHeight - (65+(int)(Math.random() * 220));

        // 计算直方块的绘制横坐标
        double xVBarPosition = plotMargin + i * hSpace - totalBarLength / 2
          + j * (barLength + barInnerMargin);

        g2d.setColor(paintColor[j % paintColor.length]);

        // 设置每个直方块的绘制参数
        Rectangle2D.Double bar = new Rectangle.Double(xVBarPosition, sales[j],
          barLength, plotHeight - sales[j]);

        g2d.fill(bar);
      }
    }

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

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

  // 绘制图例
  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 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 + -