JAVA教程之在JSP页面中轻松完成数据饼图
你对java乐观有点盲目。java的关键就是在服务器上表现优异,而且它提供了整个开发所需要的工具。应该是说,看哪天。net有没有机会赶上java。js|饼图|数据|页面 JSP供应了良多复杂有用的工具,个中包含从数据库中读出数据,发送数据,并可以把了局显现在一个饼状图形。如今让我们看看这一复杂而有用的办法。你所必要的工具
为了能准确运转这一文章相干的典范,你必需必要JDK1.2或更高的版本、一个干系数据库办理体系、一个JSP收集服务器。我都是在Tomcat调试这些例子,同时我也利用了SunJava2SDK公布的com.sun.image.codec.jpegclasses。
数据库计划
假定你在一家处置发卖奇怪生果的公司下班,公司出卖的生果包含:苹果、桔子、葡萄。如今你的老板想用一个饼状图形显现每种生果的总出卖量,饼状图形能使每种产物的发卖情形一览无余,老板能够敏捷把握公司的产物成友爱况。
表A利用了本文中的两种数据库列表。第一种列表(Products)包括一切发卖产物的称号;第二种列表(Sales)包括每种产物对应的发卖量。
ListingA
DatabaseDesign
---------------
p_productstable
----------------
productID int(number) notnull
productname String(varchar) notnull
p_salestable
-------------
saleID int(number) notnull
productID int(number) notnull
amount float notnull
产物(Products)列表包括productID和productname两个域。发卖(Sales)列表包括saleID,productID,和总额。发卖列表中的productID供应了这两个列表之间的联系关系。发卖列表中的总额包括了每次出卖的现金数额,这些数额以浮点型数据呈现。
表B中的getProducts()办法毗连了两个数据库,并把一切的产物称号保留在数组中:
ListingB
////////////////////////////////////////////////////////////
//GetproductsfromthedatabaseasaStringarray
////////////////////////////////////////////////////////////
publicString[]getProducts()
{
String[]arr=newString;
Connectioncon;
Statementstmt;
ResultSetrs;
intcount=0;
Stringsql="select*fromp_productsorderbyproductID";
try
{
//LoadDriver:Class.forName(driver);
//Connecttothedatabasewiththeurl
con=DriverManager.getConnection(dburl,dbuid,dbpwd);
stmt=con.createStatement();
//GetResultSet
rs=stmt.executeQuery(sql);
//Counttherecords
while(rs.next())
{count++;}
//Createanarrayofthecorrectsize
arr=newString;
//GetResultSet(theportablewayofusingrsasecondtime)
rs=stmt.executeQuery(sql);
while(rs.next())
{
arr=rs.getString("productname");
}
stmt.close();
con.close();
}
catch(java.lang.Exceptionex)
{
arr=ex.toString();
}
returnarr;
}
我设置以下的数据库划定规矩:
1、ProductID在产物列表中最共同,也是最关头;
2、ProductID关于第一个纪录的值为0;
3、一切以后的一连的纪录都是累加的,以是第二个纪录的productID为1,第三个纪录的productID为2,以此类推。
这些数据库划定规矩同意在product数组中存储数据,以下所示:
arr=rs.getString("productname");
一些数据库办理体系在缺省情形下就同意数据的主动累加大概主动排序。当你在计划数据库时,必定先查明你的数据库办理体系遵守哪些划定规矩,好比主动累加,主动排序等。
猎取总发卖量
在多半情形下,发卖列表中会有良多个纪录,以是会见数据库的快速性和高效性显得十分主要。如今我们只必要会见数据库中每种产物的总额发卖量。
表C中的getSales()办法与数据库毗连并前往一个数组,这个数组包括每种产物的总额出卖量。
ListingC
////////////////////////////////////////////////////////////
//Getthesalestotalsfromthedatabase
////////////////////////////////////////////////////////////
publicfloat[]getSales(intproducts)
{
float[]arr=newfloat;
Connectioncon;
Statementstmt;
ResultSetrs;
intcount=0;
Stringsql="selectproductID,amountfromp_sales";
try
{
//LoadDriver:
Class.forName(driver);
//Connecttothedatabasewiththeurl
con=DriverManager.getConnection(dburl,dbuid,dbpwd);
stmt=con.createStatement();
//GetResultSet
rs=stmt.executeQuery(sql);
while(rs.next())
{
intproduct=rs.getInt("productID");
//CheckthattheproductIDisvalid
if(product>=0&&product<products)
{
//Addtoproducttotal
arr+=rs.getFloat("amount");
count++;
}
}
stmt.close();
con.close();
}
catch(java.lang.Exceptionex)
{
arr=-1.0f;
}
returnarr;
}
当getSales()遍历一切的纪录后,它只存储的是每种产物新的出卖量:
intproduct=rs.getInt("productID");
arr+=rs.getFloat("amount");
pieColor对象
饼状图形上的每种产物应当以分歧的色彩显现。为了到达这一目标,我们创建一个pieColor对象(如表D)所示,这一对象包括有关色彩的数组:
ColorpieColorArray[]={newColor(210,60,60),newColor(60,210,60)…}
pieColor类界说了一个setNewColor()的办法,这一办法可以使curPieColor和索引递增,同时它能够反省索引不要凌驾界限局限,即接纳的办法是:假如curPieColor过年夜即赋0值。
更无效的是,setNewColor()轮回每种色彩后,并在第一种色彩下实行以下的代码:
curPieColor++;
if(curPieColor>=pieColorArray.length)
{curPieColor=0;}
RenderingHints和antialiasing类
java.awt.RenderingHints类界说了良多办法以显现二维图形,包含alpha_interpolation,发抖,和antialiasing办法。RenderingHints有助于决意图形怎样显现和图形怎样到达最好处置。
为了能以光滑显现,可使用antialiasing办法来处置饼状图形。Antialiasing是一种图形的光滑处置办法。其算法是选择一个特别象素的色彩值并代替交织处的象素,从而可以使线条交织处失掉光滑化。
图A申明了antialiasing办法的效果。能够看出利用antialiasing办法的饼状图形的线条交织处变得很光滑。
图A
同时,还能够创建一个RenderingHints对象,并传送到Graphics2DsetRenderingHints()办法,以下所示:
RenderingHintsrenderHints=newRenderingHints(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHints(renderHints);
制做可调剂的界限
图A中的饼状图形有一界限,怎样能改动界限的巨细呢?能够先界说intborder=10,然后盘算界限内面积的巨细而完成:
Ellipse2D.Doubleelb=newEllipse2D.Double(x_pie-border/2,y_pie-border/2,pieWidth+border,pieHeight+border);
x_pie和y_pie的值代表着包抄在饼状图形的正方形的左上角。我们经由过程界限面积取一半(border/2)而失掉饼状图形的中央。
圆弧(Arc)实际
从java.awt.Graphics类承继而来的fillArc()办法供应了绘制饼状图形各个部分(或圆弧)的复杂办法:
g2d.fillArc(x_position,y_position,width,height,startAngle,sweepAngle);
x_position,和y_position整数代表着要添补的圆弧的左上角的x,y的坐标,width和heigh整数代表其详细的尺寸。假如width和height的值相称,饼状图形将是一个圆。假如width和height不相称,那末饼状图形将是一个椭圆。
fillArc()办法决意基于sweepAngle整数值的圆弧的巨细。假如sweepAngle值是正的,则圆弧是以反时针偏向绘制,反之以顺时针绘制。
绘制圆弧
第一步,利用pieColor对象的getPieColor()办法猎取比来饼状圆弧的色彩,并把它付与以后的圆弧::
g2d.setColor(pc.getPieColor());
接着,经由过程不休轮回sales[]数组并使其累加而取得统共的发卖量:
salesTotal+=sales;
利用统共发卖量,能够盘算出每种产物发卖情形占统共发卖量的百份量:
floatperc=(sales/salesTotal);
我们盘算sweepAngle便可给圆弧的每部分分派度数:
intsweepAngle=(int)(perc*360);
每部分圆弧画完以后,startAngle便可依据以后的sweepAngle递增。这就确保以后的圆弧部分都是以上一圆弧为入手下手,从而创建一个完全的饼状图形。
显现图标
图标供应了显现饼状图形中各个部分最简便的体例。一个图标的巨细应当与饼状图形中的占据量绝对应。
图B显现了一个完全饼状图形及其对应各个部分的图标,包含产物称号、发卖总量、和各个部分的占据量。
图B
总结
本文报告了怎样使用JSP绘制饼状图形的办法及算法,这些办法及算法复杂而有用,开辟职员能够充实天时用这些办法。
附:本文全体源代码
ListingE
<%@pagelanguage="java"%>
<%@pageimport="java.io.OutputStream"%>
<%@pageimport="java.sql.*"%>
<%@pageimport="java.awt.*"%>
<%@pageimport="java.awt.geom.*"%>
<%@pageimport="java.awt.image.BufferedImage"%>
<%@pageimport="com.sun.image.codec.jpeg.*"%>
<%!
////////////////////////////////////////////////////////////
//PieColorsclassmanagesthecolorsusedinthepiechart
////////////////////////////////////////////////////////////
classPieColors
{
ColorpieColorArray[]={
newColor(210,60,60),newColor(60,210,60),newColor(60,60,210),
newColor(120,60,120),newColor(60,120,210),newColor(210,120,60)
};
intcurPieColor=0;
publicColorgetPieColor()
{
returnpieColorArray;
}
publicvoidsetNewColor()
{
curPieColor++;
if(curPieColor>=pieColorArray.length)
{curPieColor=0;}
}
}
%>
<%!Stringdriver="com.mysql.jdbc.Driver";Stringdburl="jdbc:mysql://localhost/articles";Stringdbuid="myuid";Stringdbpwd="mypwd";
////////////////////////////////////////////////////////////
//GettheproductsfromthedatabaseasaStringarray
////////////////////////////////////////////////////////////
publicString[]getProducts()
{
String[]arr=newString;
Connectioncon;
Statementstmt;
ResultSetrs;
intcount=0;
Stringsql="select*fromp_productsorderbyproductID";
try
{
//LoadDriver:
Class.forName(driver);
//Connecttothedatabasewiththeurl
con=DriverManager.getConnection(dburl,dbuid,dbpwd);
stmt=con.createStatement();
//GetResultSet
rs=stmt.executeQuery(sql);
//Counttherecords
while(rs.next()){count++;
}
//Createanarrayofthecorrectsize
arr=newString;
//GetResultSet(themostportablewayofusingrsasecondtime)
rs=stmt.executeQuery(sql);
while(rs.next())
{
arr=rs.getString("productname");
}
stmt.close();
con.close();
}
catch(java.lang.Exceptionex)
{arr=ex.toString();}
returnarr;
}
////////////////////////////////////////////////////////////
//Getthesalestotalsfromthedatabase
////////////////////////////////////////////////////////////
publicfloat[]getSales(intproducts)
{
float[]arr=newfloat;
Connectioncon;
Statementstmt;
ResultSetrs;
Stringsql="selectproductID,amountfromp_sales";
try{
//LoadDriver:
Class.forName(driver);
//Connecttothedatabasewiththeurl
con=DriverManager.getConnection(dburl,dbuid,dbpwd);
stmt=con.createStatement();
//GetResultSet
rs=stmt.executeQuery(sql);
while(rs.next()){intproduct=rs.getInt("productID");
//CheckthattheproductIDisvalid
if(product>=0&&product<products)
{
//Addtoproducttotal
arr+=rs.getFloat("amount");
}
}
stmt.close();
con.close();
}catch(java.lang.Exceptionex){arr=-1.0f;}
returnarr;}%>
<%
//getanarraythatcontainstheproductnames
Stringproducts[]=getProducts();
//readthedataandstorethetotalsinanarray
floatsales[]=getSales(products.length);
//DeclarePieColorsPieColors
pc=newPieColors();
//ColorsColor
dropShadow=newColor(240,240,240);
//innerpaddingtomakesurebarsnevertouchtheouterborder
intinnerOffset=20;
//Setthegraphsouterwidth&height
intWIDTH=400;
intHEIGHT=200;
intpieHeight=HEIGHT-(innerOffset*2);
intpieWidth=pieHeight;
//Tomakeasquare(circular)pie
inthalfWidth=WIDTH/2;
//Widthoftheinnergraphablearea
intinnerWIDTH=WIDTH-(innerOffset*2);
//graphdimensionsDimension
graphDim=newDimension(WIDTH,HEIGHT);
RectanglegraphRect=newRectangle(graphDim);
//borderdimensions
DimensionborderDim=newDimension(halfWidth-2,HEIGHT-2);
RectangleborderRect=newRectangle(borderDim);
/////////////////////////////////////////////////////////////
//Setupthegraph
////////////////////////////////////////////////////////////
//Setcontenttype
response.setContentType("image/jpeg");
//CreateBufferedImage&Graphics2D
BufferedImagebi=newBufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
Graphics2Dg2d=bi.createGraphics();
//SetAntialiasingRenderingHints
renderHints=newRenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHints(renderHints);
//Setgraphbackgroundcolortowhite:
g2d.setColor(Color.white);
g2d.fill(graphRect);
//Drawblackborder
g2d.setColor(Color.black);
borderRect.setLocation(1,1);
g2d.draw(borderRect);
//Nowdrawborderforlegend
borderRect.setLocation((WIDTH/2)+1,1);
g2d.draw(borderRect);
////////////////////////////////////////////////////////////////////
//Drawdataontothegraph:
////////////////////////////////////////////////////////////////////
intx_pie=innerOffset;
inty_pie=innerOffset;intborder=20;
//MainchartEllipse
//Ellipse2D.Doubleel=newEllipse2D.Double(x_pie,y_pie,pieWidth,pieHeight); Ellipse2D.Doubleelb=newEllipse2D.Double(x_pie-border/2,y_pie-border/2,pieWidth+border,pieHeight+border);
//Shadow
g2d.setColor(dropShadow);
g2d.fill(elb);
//Border
g2d.setColor(Color.black);
g2d.draw(elb);
/////////////////////////////////////////////////////////////////
//Calculatethetotalsales
/////////////////////////////////////////////////////////////////
floatsalesTotal=0.0f;
intlastElement=0;
for(inti=0;i<products.length;i++)
{
if(sales>0.0f)
{
salesTotal+=sales;
lastElement=i;
}
}
//////////////////////////////////////////////////////////////
//Drawthepiechart
/////////////////////////////////////////////////////////////
//Chartvariables
intstartAngle=0;
//Legendvariables
intlegendWidth=20;
intx_legendText=halfWidth+innerOffset/2+legendWidth+5;
intx_legendBar=halfWidth+innerOffset/2;
inttextHeight=20;
intcurElement=0;
inty_legend=0;
//Dimensionsofthelegendbar
DimensionlegendDim=newDimension(legendWidth,textHeight/2);
RectanglelegendRect=newRectangle(legendDim);
for(inti=0;i<products.length;i++)
{
if(sales>0.0f)
{
//Calculatepercentagesalesfloat
perc=(sales/salesTotal);
//Calculatenewangle
intsweepAngle=(int)(perc*360);
//Checkthatthelastelementgoesbackto0position
if(i==lastElement)
{
sweepAngle=360-startAngle;
}
//DrawArc
g2d.setColor(pc.getPieColor());
g2d.fillArc(x_pie,y_pie,pieWidth,pieHeight,startAngle,sweepAngle);
//IncrementstartAnglewiththesweepAngle
startAngle+=sweepAngle;
/////////////
//DrawLegend
/////////////
//Setypositionforbar
y_legend=curElement*textHeight+innerOffset;
//Displaythecurrentproduct
Stringdisplay=products;
g2d.setColor(Color.black);
g2d.drawString(display,x_legendText,y_legend);
//Displaythetotalsales
display=""+(int)sales;
g2d.setColor(Color.black);
g2d.drawString(display,x_legendText+80,y_legend);
//Displaythesalespercentage
display="("+(int)(perc*100)+"%)";
g2d.setColor(Color.red);
g2d.drawString(display,x_legendText+110,y_legend);
//Drawthebar
g2d.setColor(pc.getPieColor());
legendRect.setLocation(x_legendBar,y_legend-textHeight/2);
g2d.fill(legendRect);
//Setnewpiecolor
pc.setNewColor();
//Increment
curElement++;
}
}
////////////////////////////////////////////////
//Encodethegraph
/////////////////////////////////////////
OutputStreamoutput=response.getOutputStream();
JPEGImageEncoderencoder=JPEGCodec.createJPEGEncoder(output);
encoder.encode(bi);
output.close();%>
唉!都是钱闹的1.Swing和.net开发比较------从市场份额看.net开发主要占据大部分的中小型和中型的的桌面开发,原因是它封装了很多工具 你快去找一份Java的编程工作来做吧(如果是在校学生可以去做兼职啊),在实践中提高自己,那才是最快的。不过你得祈祷在公司里碰到一个高手,而且他 还愿意不厌其烦地教你,这样好象有点难哦!还有一个办法就是读开放源码的程序了。我们知道开放源码大都出自高手,他们设计合理,考虑周到,再加上有广大的程序员参与,代码的价值自然是字字珠叽,铿锵有力(对不起,偶最近《金装四大才子》看多了)。 《JAVA语言程序设计》或《JAVA从入门到精通》这两本书开始学,等你编程有感觉的时候也可以回看一下。《JAVA读书笔记》这本书,因为讲的代码很多,也很容易看懂,涉及到面也到位。是你学习技术巩固的好书,学完后就看看《JAVA编程思想》这本书,找找一个自己写的代码跟书上的代码有什么不一样。 所以现在应用最广泛又最好学的就是J2EE了。 J2EE又包括许多组件,如Jsp,Servlet,JavaBean,EJB,JDBC,JavaMail等。要学习起来可不是一两天的事。那么又该如何学习J2EE呢?当然Java语法得先看一看的,I/O包,Util包,Lang包你都熟悉了吗?然后再从JSP学起。 当然你也可以参加一些开源项目,一方面可以提高自己,另一方面也是为中国软件事业做贡献嘛!开发者在互联网上用CVS合作开发,用QQ,MSN,E-mail讨论联系,天南海北的程序员分散在各地却同时开发同一个软件,是不是很有意思呢? http://www.jdon.com/去下载,或到同济技术论坛的服务器ftp://nro.shtdu.edu.cn去下,安装上有什么问题,可以到论坛上去提问。 接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。 科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。 学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。 你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。 接着就是EJB了,EJB就是Enterprise JavaBean, 看名字好象它是Javabean,可是它和Javabean还是有区别的。它是一个体系结构,你可以搭建更安全、更稳定的企业应用。它的大量代码已由中间件(也就是我们常听到的 Weblogic,Websphere这些J2EE服务器)完成了,所以我们要做的程序代码量很少,大部分工作都在设计和配置中间件上。 是一种将安全性(Security)列为第一优先考虑的语言 你快去找一份Java的编程工作来做吧(如果是在校学生可以去做兼职啊),在实践中提高自己,那才是最快的。不过你得祈祷在公司里碰到一个高手,而且他 还愿意不厌其烦地教你,这样好象有点难哦!还有一个办法就是读开放源码的程序了。我们知道开放源码大都出自高手,他们设计合理,考虑周到,再加上有广大的程序员参与,代码的价值自然是字字珠叽,铿锵有力(对不起,偶最近《金装四大才子》看多了)。
页:
[1]