|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
你对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[0];
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[count];
//GetResultSet(theportablewayofusingrsasecondtime)
rs=stmt.executeQuery(sql);
while(rs.next())
{
arr[rs.getInt("productID")]=rs.getString("productname");
}
stmt.close();
con.close();
}
catch(java.lang.Exceptionex)
{
arr[0]=ex.toString();
}
returnarr;
}
我设置以下的数据库划定规矩:
1、ProductID在产物列表中最共同,也是最关头;
2、ProductID关于第一个纪录的值为0;
3、一切以后的一连的纪录都是累加的,以是第二个纪录的productID为1,第三个纪录的productID为2,以此类推。
这些数据库划定规矩同意在product数组中存储数据,以下所示:
arr[rs.getInt("productID")]=rs.getString("productname");
一些数据库办理体系在缺省情形下就同意数据的主动累加大概主动排序。当你在计划数据库时,必定先查明你的数据库办理体系遵守哪些划定规矩,好比主动累加,主动排序等。
猎取总发卖量
在多半情形下,发卖列表中会有良多个纪录,以是会见数据库的快速性和高效性显得十分主要。如今我们只必要会见数据库中每种产物的总额发卖量。
表C中的getSales()办法与数据库毗连并前往一个数组,这个数组包括每种产物的总额出卖量。
ListingC
////////////////////////////////////////////////////////////
//Getthesalestotalsfromthedatabase
////////////////////////////////////////////////////////////
publicfloat[]getSales(intproducts)
{
float[]arr=newfloat[products];
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[product]+=rs.getFloat("amount");
count++;
}
}
stmt.close();
con.close();
}
catch(java.lang.Exceptionex)
{
arr[0]=-1.0f;
}
returnarr;
}
当getSales()遍历一切的纪录后,它只存储的是每种产物新的出卖量:
intproduct=rs.getInt("productID");
arr[product]+=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[curPieColor];
}
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[0];
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[count];
//GetResultSet(themostportablewayofusingrsasecondtime)
rs=stmt.executeQuery(sql);
while(rs.next())
{
arr[rs.getInt("productID")]=rs.getString("productname");
}
stmt.close();
con.close();
}
catch(java.lang.Exceptionex)
{arr[0]=ex.toString();}
returnarr;
}
////////////////////////////////////////////////////////////
//Getthesalestotalsfromthedatabase
////////////////////////////////////////////////////////////
publicfloat[]getSales(intproducts)
{
float[]arr=newfloat[products];
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[product]+=rs.getFloat("amount");
}
}
stmt.close();
con.close();
}catch(java.lang.Exceptionex){arr[0]=-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开发主要占据大部分的中小型和中型的的桌面开发,原因是它封装了很多工具 |
|