服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

用java在web页面上输出统计图


河南省焦作水利局 聂春生

  在internet 和intranet 的应用中,数据库和web 技术的结合是传统mis 系统移植到internet(intrant) 环境的关键, 已有不少厂商推出了各自的产品,但这些产品基本上是实现数据的html 格式输出。在实际应用中,我们经常需要把数据以统计图的形式表现出来,例如股票行情曲线图的输出。传统的方法是把统计图作为一个图形文件放到web 服务器的目录中。这种做法虽然简单,但有明显的局限性:一是图形文件要占用较大存储空间;二是难以适应灵活复杂的查询要求;三是图形文件随数据库的变化而更新,加重了服务器的负担,也容易造成图形和数据库的不一致。
  显然,要实现上述要求,需要两个关键环节:一是从数据库中读出数据;二是根据读出的数据在web 页面中绘图。我们采用jdbc 访问数据库,在web 页面中绘图则使用java.awt 包中提供的graphics 类实现。
  为便于表述,建立数据表如下:

项 目
指 标

水 产 养 殖
60

工 程 管 理
89

抗 旱 防 汛
100

财 务
200

办 公 室
350

勘 测 设 计
80

  我们的目标就是把上表用统计图表现出来(本文用水平柱状图)。本文中所指数据库均为如上形式的表,其字段1 为字符形字段,表示项目信息;字段2 为数值形字段(用浮点形读出),表示指标数。实际应用中,对程序稍作修改,就可使其更加灵活通用。
  为了绘制各种形式的图表,先定义一个graph 抽象类(注意不是graphics):
import java.sql. *;
import java.awt. *;
abstract class graph{
 int height,width; // 绘图区域的高和宽
 int maxrow=50,row=0;
 // 可容纳的最大记录数和实有记录数
 color color=new color(50,50,200); // 默认绘图颜色
 float scale;      // 比例尺
 string[] name;   // 项目名缓冲区
 float[] value;    // 指标值缓冲区
 public graph(dimension d,int maxrows,color fcolor){
   height=d.height;
   width=d.width;
   name=new string[maxrows];
   value=new float[maxrows];
   color=fcolor;
 }
 public void setresult(resultset result)
{ // 把查询结果读入缓冲区
  try{
row=0;
   while(result.next() &&row<maxrow){
name[row]=result.getstring(1);
value[row]=result.getfloat(2);
row + +;
}
}
catch(exception ex){
system.out.println(“/n failure!" +ex.getmessage()); }
}

// 绘制统计图的抽象方法, 在子类中实现
}

  在这个类中,定义了图表的一般特性,如颜色、比例尺、记录缓冲区等,并实现了把查询结果置入缓冲区的setresult 方法。因为各种图表的绘制方法完全不同,故把draw 方法定义为抽象方法,有待其子类实现。
  限于篇幅,本文仅介绍实现绘制水平柱状图的子类graphpost, 其主要功能是实现draw 方法。其他子类与其类似。
import java.sql.*;
import java.awt.*;
public class graphpost extends graph{
  float interval=0;
 //柱间空白在柱宽度(含柱间空白)
 中所占比例,0<interval0) interval=ival;
  }
  void draw(graphics g){
fontmetrics fontmetrics=g.getfontmetrics();
try{
  color bgcolor=new color(255,255,255);
  g.setcolor(bgcolor); 
  g.fillrect(0,0,width,height); //填充背景色
  g.setcolor(color);
  int maxlen=0;
  float maxvalue=0;
  for (int i=0;imaxlen)
  maxlen=fontmetrics.stringwidth(name[i]);
     if (value[i]>maxvalue)
   maxvalue=value[i];
   }
   xmargin=maxlen+10;//
   ymargin=fontmetrics.getheight()+10;
   int cheight=fontmetrics.getheight();
   int step=getstep(maxvalue);
   //计算x坐标刻度单位
   scale=(width-xmargin)/maxvalue;
   ehight=(height-ymargin)/row;
   g.drawrect(xmargin-1,0,width-xmargin,height
   -ymargin); //绘出图形外框
   for(int i=1;i*step10){
  mo=mo*10;
  st=(int)(value/10)/mo;
 }
 return (st+1)*mo;
}
}

  对数据库的查询在applet 主类中用creatresultset 方法实现:
private static resultset creatresultset
(string dstr,string sqlstr)
/ * 根据给定的数据源和
sql 查询语句读取数据库*/ {......}

  在applet 主类的paint() 方法中,调用类graphpost 的draw 方法,即可实现统计图的输出。为把查询结果保存在graphpost 的数据缓冲区中供paint() 方法多次使用,需要把一个graphpost 对象定义为applet 主类的成员。在applet 主类的init() 方法中,对graphpost 对象初始化,并完成jdbc 驱动程序注册。在applet 主类的start() 方法中,连接数据库,执行查询,并把查询结果存放到graphpost 对象的数据缓冲区中。这样, 在每次回到包含该applet 的页面时, 都要重新查询数据库, 保证用户阅读到数据库的最新信息。
  下面是applet 主类代码:
import java.applet.applet;
import java.sql. *;
import java.awt. *;
public class webgraph extends applet {
  graphpost graphpost;
public void init() {
   try{
     color color=new color(20,20,230);
     class.forname("sun.jdbc.odbc.jdbcodbcdriver");
// 注册驱动程序
graphpost=new graphpost(size(),30,color,0.3f);
// 初始化graphpost 对象
    }
  catch(exception e){
  system.out.println("/n" +“init error" +e.getmessage());
 }
 }
 public void start(){
  try{
  resultset rs;
  string dsourname="foxpro files";
  string sqlstr="select *from test";
  rs=creatresultset(dsourname,sqlstr);
  // 从数据库中提取数据
  graphpost.setresult(rs);
  // 把查询结果发送给graphpost
  rs.close();
}
catch(exception e){
  system.out.println("/n" +“start error"
  +e.getmessage());
   }
}
public void paint(graphics g){
 graphpost.draw(g);
  // 调用graphpost 的draw 方法绘制柱状统计图
}
private static resultset creatresultset(string dstr,string sqlstr)
  throws sqlexception{
  / *根据给定的数据源和sql
   查询语句读取数据库*/
   string datasr=dstr;
   connection con1=drivermanager.getconnection
("jdbc:odbc:" +datasr); // 连接数据库
   statement stmt1=con1.createstatement();
   return stmt1.executequery(sqlstr);// 执行查询
  }
}

  为了正确使用jdbc,需要安装jdbc 类库(已包含在jdk1.1 中)和jdbc 驱动程序。这方面资料很多,笔者不再赘述。本文为使用odbc 操作foxpro 数据库,采用了jdbc -odbc 桥接方式。在网络环境下,建议使用专门的jdbc 驱动程序。
  本程序在java workshop 2.0 中调试通过

扫描关注微信公众号