分享
 
 
 

用Java在Web页面上输出统计图 统计报表

王朝java/jsp·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

用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;

publicvoid 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 中调试通过,程序运行结果如下图所示:

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有