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

📄 linechart3dbean.java

📁 提供 精通Java Web动态图表编程 一书的源代码, 大家赶快下载呀
💻 JAVA
字号:
//	Fig. 9.2_02_01: LineChart3DBean.java
//	功能: 生成3D线段图的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 LineChart3DBean extends HttpServlet
{
  HttpServletResponse response;

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

  private String xAxisLabel = "销售时间";
  private String yAxisLabel = "销售量";
  private String chartTitle = "线段图表Bean: 书籍月销售量统计图";

  // 设定阴影的厚度
  int thickness = 25;

  // 设定夹角
  int alpha = 45;

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

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

  public LineChart3DBean(HttpServletResponse response)
  {
    this.response = response;
    this.initialize();
    this.drawBackground();
    this.drawTitle();
    this.drawChart();
    this.drawAxisLabel();
  }

  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 blueGP = new GradientPaint(0, 0, new Color(93, 117, 151), 0,
      height, new Color(90, 114, 150), false);

    g2d.setPaint(blueGP);
    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(215, 230, 252),
      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(Color.WHITE);
    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("Courier New", Font.PLAIN, 12));
    String str = "2004-";
    int stringLength = 0, stringHeight = 0;

    // 横轴上刻度值的数量
    int xTickCounter = 12;

    // 图表绘制区和纵轴之间的空白
    int plotMargin = 10;

    // 横轴上刻度值的长度
    int hSpace = (plotWidth - 2 * plotMargin) / (xTickCounter - 1);

    stringHeight = g2d.getFontMetrics().getAscent();
    for (int i = 0; i < xTickCounter; i++)
    {
      // 绘制垂直方向虚线
      g2d.setColor(new Color(103, 115, 133));
      g2d.drawLine(plotMargin + i * hSpace, 0, plotMargin + i * hSpace,
        plotHeight);

      // 绘制横轴上刻度值的说明文字
      str += i + 1;
      stringLength = g2d.getFontMetrics().stringWidth(str);
      g2d.setColor(Color.YELLOW);
      if (i % 2 == 0)
      {
        g2d.drawString(str, plotMargin + i * hSpace - stringLength / 2,
          plotHeight + stringHeight + 5);
      }
      str = "2004-";
    }

    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(Color.YELLOW);
      g2d.drawString(str,  - 5-stringLength, i * vSpace + stringHeight / 2);
      str = "";
    }

    String[] bookTitle =
    {
      "Java类书籍", "C#类书籍"
    };
    Color[] bookColor =
    {
      Color.RED, Color.ORANGE
    };
    int[] sales = new int[xTickCounter];
    int[] month = new int[xTickCounter];

    g2d.setFont(new Font("Courier New", Font.PLAIN, 12));
    for (int i = 0; i < bookTitle.length; i++)
    {
      // 初始化绘制数据
      int bookSales = 0;
      for (int j = 0; j < sales.length; j++)
      {
        sales[j] = plotHeight - (65+(int)(Math.random() * 220));
        month[j] = plotMargin + j * hSpace;
      }

      // 重新设置笔划
      g2d.setStroke(new BasicStroke(5.0f));
      g2d.setColor(bookColor[i]);

      // 绘制阴影
      drawLineShadow(month, sales, thickness, alpha, bookColor[i], g2d);

      // 绘制月销售量折线
      g2d.drawPolyline(month, sales, sales.length);
    }

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

    // 绘制坐标轴图例
    drawLegend(bookTitle, bookColor);
  }
 
  // 绘制图例
  public void drawLegend(String[]legendItems, Color[]color)
  {
    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(color[i]);
      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(255, 224, 193));
    int labelHeight = g2d.getFontMetrics().getAscent();

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

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

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

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

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

  // 绘制阴影
  public void drawLineShadow(int xPoint[], int yPoint[], int thickness, int
    alpha, Color color, Graphics2D g2d)
  {
    int shadowX[] = new int[xPoint.length];
    int shadowY[] = new int[yPoint.length];

    for (int i = thickness; i >= 0; i--)
    {
      if (i == thickness || i == 0)
      {
        g2d.setStroke(new BasicStroke(2.0f));
        g2d.setColor(color.darker());
      }
      else
      {
        g2d.setStroke(new BasicStroke(4.0f));
        g2d.setColor(color);
      }

      for (int j = 0; j < xPoint.length; j++)
      {
        shadowX[j] = xPoint[j] + getOffsetX(alpha, i);
        shadowY[j] = yPoint[j] - getOffsetY(alpha, i);
      }
      g2d.drawPolyline(shadowX, shadowY, shadowX.length);
    }
  }

  // 计算offsetX的值
  public int getOffsetX(int alpha, int thickness)
  {
    return (int)(Math.cos(alpha * Math.PI / 180) * thickness + 0.5);
  }

  // 计算offsetY的值
  public int getOffsetY(int alpha, int thickness)
  {
    return (int)(Math.sin(alpha * Math.PI / 180) * thickness + 0.5);
  }

  public void getChart()
  {
    // 部署图形环境
    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 + -