亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JSP > 正文

在JSP頁面中輕松實現數據餅圖

2024-09-05 00:19:17
字體:
來源:轉載
供稿:網友

  jsp提供了很多簡單實用的工具,其中包括從數據庫中讀出數據,發送數據,并能夠把結果顯示在一個餅狀圖形?,F在讓我們看看這一簡單而實用的方法。

  你所需要的東西

  為了能正確運行這一文章相關的范例,你必須需要jdk 1.2或更高的版本、一個關系數據庫管理系統、一個jsp網絡服務器。我都是在tomcat調試這些例子,同時我也使用了sun java 2 sdk發布的com.sun.image.codec.jpegclasses。

  數據庫設計

  假設你在一家從事銷售新鮮水果的公司上班,公司出售的水果包括:蘋果、桔子、葡萄?,F在你的老板想用一個餅狀圖形顯示每一種水果的總出售量,餅狀圖形能使每一種產品的銷售情況一目了然,老板可以迅速掌握公司的產品成交情況。

  表a使用了本文中的兩種數據庫列表。第一種列表(products)包含所有銷售產品的名稱;第二種列表(sales)包含每一種產品對應的銷售量。

listing a

database design
---------------
p_products table
----------------
productid   int (number)    not null
productname  string (varchar)  not null

p_sales table
-------------
saleid     int (number)   not null
productid   int (number)   not null
amount     float      not null

  產品(products)列表包含productid和productname兩個域。銷售(sales)列表包含saleid, productid,以及總額。銷售列表中的productid提供了這兩個列表之間的關聯。銷售列表中的總額包含了每一次出售的現金數額,這些數額以浮點型數據出現。

  表b中的getproducts()方法連接了兩個數據庫,并把所有的產品名稱保存在數組中:

  listing b

////////////////////////////////////////////////////////////
//get products from the database as a string array
////////////////////////////////////////////////////////////
public string[] getproducts()
{
 string[] arr = new string[0];
 connection con;
 statement stmt;
 resultset rs;
 int count = 0;
 string sql = "select * from p_products order by productid";
 try
 {
  //load driver: class.forname(driver);
  //connect to the database with the url
  con = drivermanager.getconnection(dburl , dbuid , dbpwd);
  stmt = con.createstatement();
  //get resultset
  rs = stmt.executequery(sql);
  //count the records
  while(rs.next())
   {count++;}
  //create an array of the correct size
  arr = new string[count];
  //get resultset (the portable way of using rs a second time)
  rs = stmt.executequery(sql);
  while(rs.next())
  {
   arr[rs.getint("productid")] = rs.getstring("productname");
  }
  stmt.close();
  con.close();
 }
 catch (java.lang.exception ex)
 {
  arr[0] = ex.tostring();
 }
 return arr;
}
 

  我設置以下的數據庫規則:

   1、productid在產品列表中最獨特,也是最關鍵;

   2、productid對于第一個記錄的值為0;

   3、所有之后的連續的記錄都是累加的,所以第二個記錄的productid為1,第三個記錄的productid為2,以此類推。

  這些數據庫規則允許在product數組中存儲數據,如下所示:

arr[rs.getint("productid")] = rs.getstring("productname");


  一些數據庫管理系統在缺省情況下就允許數據的自動累加或者自動排序。當你在設計數據庫時,一定先查明你的數據庫管理系統遵循哪些規則,比如自動累加,自動排序等。

  獲取總銷售量

  在多數情況下,銷售列表中會有很多個記錄,所以訪問數據庫的快捷性和高效性顯得非常重要?,F在我們只需要訪問數據庫中每一種產品的總額銷售量。
  表c中的getsales()方法與數據庫連接并返回一個數組,這個數組包含每一種產品的總額出售量。

  listing c

////////////////////////////////////////////////////////////
//get the sales totals from the database
////////////////////////////////////////////////////////////
public float[] getsales(int products)
{
 float[] arr = new float[products];
 connection con;
 statement stmt;
 resultset rs;
 int count = 0;
 string sql = "select productid, amount from p_sales";
 try
 {
  //load driver:
  class.forname(driver);
  //connect to the database with the url
  con = drivermanager.getconnection(dburl , dbuid , dbpwd);
  stmt = con.createstatement();
  //get resultset
  rs = stmt.executequery(sql);
  while(rs.next())
  {
   int product = rs.getint("productid");
   //check that the productid is valid
   if (product >= 0 && product < products)
   {
    //add to product total
    arr[product] += rs.getfloat("amount");
    count++;
   }
     }
  stmt.close();
  con.close();
 }
 catch (java.lang.exception ex)
 {
  arr[0] = -1.0f;
 }
 return arr;
}

  當getsales()遍歷所有的記錄后,它只存儲的是每一種產品新的出售量:

int product = rs.getint("productid");
arr[product] += rs.getfloat("amount");

  piecolor對象

  餅狀圖形上的每一種產品應該以不同的顏色顯示。為了達到這一目的,我們建立一個piecolor對象(如表d)所示,這一對象包含有關顏色的數組:

color piecolorarray[] = {new color(210,60,60), new color(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方法的效果??梢钥闯鍪褂胊ntialiasing方法的餅狀圖形的線條交叉處變得很平滑。


圖a

  同時,還可以建立一個renderinghints對象,并傳遞到graphics2d setrenderinghints()方法,如下所示:

renderinghints renderhints = new renderinghints(renderinghints.key_antialiasing,
renderinghints.value_antialias_on);
g2d.setrenderinghints(renderhints);

 

  制做可調整的邊界

  圖a中的餅狀圖形有一邊界,如何能改變邊界的大小呢?可以先定義int border = 10,然后計算邊界內面積的大小而實現:
ellipse2d.double elb = new ellipse2d.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[i];


  使用總共銷售量,可以計算出每一種產品銷售情況占總共銷售量的百分量:

float perc = (sales[i]/salestotal);


  我們計算sweepangle即可給圓弧的每一部分分配度數:

int sweepangle = (int)(perc * 360);


  每一部分圓弧畫完之后,startangle即可根據當前的sweepangle遞增。這就確保當前的圓弧部分都是以上一圓弧為開始,從而建立一個完整的餅狀圖形。

  顯示圖標

  圖標提供了顯示餅狀圖形中各個部分最簡潔的方式。一個圖標的大小應該與餅狀圖形中的占有量相對應。

  圖b顯示了一個完整餅狀圖形及其對應各個部分的圖標,包括產品名稱、銷售總量、以及各個部分的占有量。


圖b

  總結

  本文講述了如何利用jsp繪制餅狀圖形的方法及算法,這些方法及算法簡單而實用,開發人員可以充分地利用這些方法。

  附:本文全部源代碼

listing e

<%@ page language="java" %>
<%@ page import="java.io.outputstream" %>
<%@ page import="java.sql.*" %>
<%@ page import="java.awt.*" %>
<%@ page import="java.awt.geom.*" %>
<%@ page import="java.awt.image.bufferedimage" %>
<%@ page import="com.sun.image.codec.jpeg.*" %>
<%!
////////////////////////////////////////////////////////////
// piecolors class manages the colors used in the pie chart
////////////////////////////////////////////////////////////
class piecolors
{
 color piecolorarray[] = {
  new color(210,60,60), new color(60,210,60), new color(60,60,210),
  new color(120,60,120), new color(60,120,210), new color(210,120,60)
  };
 int curpiecolor = 0;
 public color getpiecolor()
 {
  return piecolorarray[curpiecolor];
 }
 public void setnewcolor()
 {
  curpiecolor++;
  if(curpiecolor >= piecolorarray.length)
  {curpiecolor = 0;}
 }
}
%>
<%! string driver = "com.mysql.jdbc.driver"; string dburl = "jdbc:mysql://localhost/articles"; string dbuid = "myuid"; string dbpwd = "mypwd";

////////////////////////////////////////////////////////////
// get the products from the database as a string array
////////////////////////////////////////////////////////////
public string[] getproducts()
{
 string[] arr = new string[0];
 connection con;
 statement stmt;
 resultset rs;
 int count = 0;
 string sql = "select * from p_products order by productid";
 try
 {
  //load driver:
  class.forname(driver);
  //connect to the database with the url
  con = drivermanager.getconnection(dburl , dbuid , dbpwd);
  stmt = con.createstatement();
  //get resultset
  rs = stmt.executequery(sql);
  //count the records
  while(rs.next()){count++;
 }
 //create an array of the correct size
 arr = new string[count];
 //get resultset (the most portable way of using rs a second time)
 rs = stmt.executequery(sql);
 while(rs.next())
 {
  arr[rs.getint("productid")] = rs.getstring("productname");
 }
 stmt.close();
 con.close();
}
 catch (java.lang.exception ex)
 {arr[0] = ex.tostring();}
 return arr;
}
////////////////////////////////////////////////////////////
//get the sales totals from the database
////////////////////////////////////////////////////////////
public float[] getsales(int products)
{
 float[] arr = new float[products];
 connection con;
 statement stmt;
 resultset rs;
 string sql = "select productid, amount from p_sales";
 try {
  //load driver:
  class.forname(driver);
  //connect to the database with the url
  con = drivermanager.getconnection(dburl , dbuid , dbpwd);
  stmt = con.createstatement();
  //get resultset
  rs = stmt.executequery(sql);
  while (rs.next()) { int product = rs.getint("productid");
  //check that the productid is valid
  if (product >= 0 && product < products)
  {
   //add to product total
   arr[product] += rs.getfloat("amount");
  }
 }
 stmt.close();
 con.close();
} catch (java.lang.exception ex) {arr[0] = -1.0f; }
 return arr; } %>
<%
 //get an array that contains the product names
 string products[] = getproducts();
 //read the data and store the totals in an array
 float sales[] = getsales(products.length);
 //declare piecolors piecolors
 pc = new piecolors();
 //colors color
 dropshadow = new color(240,240,240);
 //inner padding to make sure bars never touch the outer border
 int inneroffset = 20;
 //set the graph's outer width & height
 int width = 400;
 int height = 200;
 int pieheight = height - (inneroffset * 2);
 int piewidth = pieheight;
 //to make a square (circular) pie
 int halfwidth = width/2;
 //width of the inner graphable area
 int innerwidth = width - (inneroffset * 2);
 //graph dimensions dimension
 graphdim = new dimension(width,height);
 rectangle graphrect = new rectangle(graphdim);
 //border dimensions
 dimension borderdim = new dimension(halfwidth-2,height-2);
 rectangle borderrect = new rectangle(borderdim);

 /////////////////////////////////////////////////////////////
  //set up the graph
 ////////////////////////////////////////////////////////////
 //set content type
  response.setcontenttype("image/jpeg");
 //create bufferedimage & graphics2d
 bufferedimage bi = new bufferedimage(width, height, bufferedimage.type_int_rgb);
 graphics2d g2d = bi.creategraphics();
 // set antialiasing renderinghints
 renderhints = new renderinghints( renderinghints.key_antialiasing,renderinghints.value_antialias_on);
 g2d.setrenderinghints(renderhints);
 //set graph background color to white:
 g2d.setcolor(color.white);
 g2d.fill(graphrect);
 //draw black border
 g2d.setcolor(color.black);
 borderrect.setlocation(1,1);
 g2d.draw(borderrect);
 //now draw border for legend
 borderrect.setlocation((width/2) + 1,1);
 g2d.draw(borderrect);  
 ////////////////////////////////////////////////////////////////////
 //draw data onto the graph:    
 ////////////////////////////////////////////////////////////////////
 int x_pie = inneroffset;
 int y_pie = inneroffset; int border = 20;
 //main chart ellipse
 //ellipse2d.double el = new ellipse2d.double(x_pie, y_pie, piewidth, pieheight);  ellipse2d.double elb = new ellipse2d.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);

 /////////////////////////////////////////////////////////////////
 //calculate the total sales       
 /////////////////////////////////////////////////////////////////
 float salestotal = 0.0f;
 int lastelement = 0;
 for(int i=0; i<products.length; i++)
 {
  if(sales[i] > 0.0f)
  {
   salestotal += sales[i];
   lastelement = i;
   }
 }
 //////////////////////////////////////////////////////////////
  //draw the pie chart   
 /////////////////////////////////////////////////////////////
 //chart variables
 int startangle = 0;
 //legend variables
 int legendwidth = 20;
 int x_legendtext = halfwidth + inneroffset/2 + legendwidth + 5;
 int x_legendbar = halfwidth + inneroffset/2;
 int textheight = 20;
 int curelement = 0;
 int y_legend = 0;
 //dimensions of the legend bar
 dimension legenddim = new dimension(legendwidth , textheight/2);
 rectangle legendrect = new rectangle(legenddim);
 for(int i=0; i<products.length; i++)
 {
  if(sales[i] > 0.0f)
  {
   //calculate percentage sales float
   perc = (sales[i]/salestotal);
   //calculate new angle
   int sweepangle = (int)(perc * 360);
   //check that the last element goes back to 0 position
   if (i == lastelement)
   {
    sweepangle = 360-startangle;
   }
   // draw arc
   g2d.setcolor(pc.getpiecolor());
   g2d.fillarc(x_pie, y_pie, piewidth, pieheight, startangle, sweepangle);
   //increment startangle with the sweepangle
   startangle += sweepangle;
   /////////////
   //draw legend
   /////////////
   //set y position for bar
   y_legend = curelement * textheight + inneroffset;
   //display the current product
   string display = products[i];
   g2d.setcolor(color.black);
   g2d.drawstring(display, x_legendtext, y_legend);
   //display the total sales
   display = "" + (int)sales[i];
   g2d.setcolor(color.black);
   g2d.drawstring(display, x_legendtext + 80, y_legend);
   //display the sales percentage
   display = " (" + (int)(perc*100) + "%)";
   g2d.setcolor(color.red);
   g2d.drawstring(display, x_legendtext + 110, y_legend);
   //draw the bar
   g2d.setcolor(pc.getpiecolor());
   legendrect.setlocation(x_legendbar,y_legend - textheight/2);
   g2d.fill(legendrect);
   //set new pie color
   pc.setnewcolor();
   //increment
   curelement++;
  }
 }
 ////////////////////////////////////////////////
 // encode the graph   
 /////////////////////////////////////////
 outputstream output = response.getoutputstream();
 jpegimageencoder encoder = jpegcodec.createjpegencoder(output);
 encoder.encode(bi);
 output.close(); %>



發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲黄页视频免费观看| 久久精品国产99国产精品澳门| 精品久久香蕉国产线看观看gif| 91中文精品字幕在线视频| 精品中文字幕在线| 午夜精品久久久久久久99热浪潮| 午夜精品久久久久久99热软件| 国产精品视频自拍| 国产精品高潮在线| 日韩成人中文字幕在线观看| 亚洲第一区中文99精品| 日韩精品免费电影| 国产精品免费小视频| 亚洲福利在线看| 911国产网站尤物在线观看| 国产69久久精品成人| 51ⅴ精品国产91久久久久久| 亚洲www永久成人夜色| 国产视频在线观看一区二区| 欧美午夜丰满在线18影院| 亚洲国产高潮在线观看| 久久亚洲成人精品| 亚洲一区二区三区在线视频| 国产伦精品一区二区三区精品视频| 亚洲电影在线看| 国产做受69高潮| 亚洲第一精品夜夜躁人人爽| 91视频国产一区| 久久国产精品免费视频| 国产欧美精品va在线观看| 日韩av影片在线观看| 精品国偷自产在线| 国产精品亚洲аv天堂网| 欧洲亚洲在线视频| 欧美裸体xxxxx| 亚洲亚裔videos黑人hd| 国产精品国语对白| 国产精品久久久久久av福利软件| 黑人巨大精品欧美一区免费视频| 久久精品99久久久久久久久| 国产色婷婷国产综合在线理论片a| 国产精品视频中文字幕91| 国产ts人妖一区二区三区| 欧洲成人免费aa| 久久频这里精品99香蕉| 亚洲国产成人爱av在线播放| 亚洲精品电影网| 国产91色在线|免| 久久天天躁狠狠躁夜夜躁| 亚洲欧美日韩爽爽影院| 欧美日韩美女在线| 欧美亚洲日本网站| 成人福利视频在线观看| 欧美日韩激情网| 欧美亚洲另类制服自拍| 亚洲国模精品私拍| 国产成人精品日本亚洲| 色妞一区二区三区| 夜夜狂射影院欧美极品| 久久久久久久999精品视频| 欧美日韩精品在线播放| 国产啪精品视频| 久久高清视频免费| 亚洲欧洲中文天堂| 性色av一区二区三区| 欧美午夜激情视频| 国产日韩欧美夫妻视频在线观看| 欧美综合国产精品久久丁香| 国产精品免费一区| 色妞一区二区三区| 高清在线视频日韩欧美| 国产精品com| 午夜精品视频在线| 国产三级精品网站| 午夜精品一区二区三区在线视| 国产精品27p| 国产日韩欧美日韩大片| 国产精品久久久久久久久借妻| 日韩成人在线观看| 日韩欧美国产成人| 在线精品高清中文字幕| 国产精品网址在线| 亚洲精品www久久久| 亚洲福利视频专区| 91免费的视频在线播放| 91国内免费在线视频| 高清一区二区三区四区五区| 精品亚洲国产成av人片传媒| 国产精品一区二区三区久久| 欧美在线一级va免费观看| 在线电影欧美日韩一区二区私密| 九九热99久久久国产盗摄| 日韩欧美福利视频| 亚洲人成电影网站色…| 精品国偷自产在线视频99| 久久久在线观看| 狠狠色噜噜狠狠狠狠97| 在线色欧美三级视频| 亚洲黄色av女优在线观看| 亚洲人成自拍网站| 欧美中在线观看| 日韩国产精品一区| 亚洲高清色综合| 精品在线欧美视频| 久久人人爽人人爽人人片av高清| 国产欧美一区二区三区在线| 欧美人成在线视频| 欧美精品亚州精品| 欧美裸身视频免费观看| 精品国产依人香蕉在线精品| 亚洲视频电影图片偷拍一区| 最近的2019中文字幕免费一页| 亚洲美女自拍视频| 精品免费在线观看| 欧美激情久久久| 日韩精品亚洲视频| 国产z一区二区三区| 欧美xxxx做受欧美| 欧美成人激情在线| 国产91色在线|| 久久亚洲一区二区三区四区五区高| 国产不卡在线观看| 欧美日在线观看| 欧美在线国产精品| 欧美电影在线观看高清| 日韩欧美在线观看视频| 亚洲国产精品国自产拍av秋霞| 欧美日韩国产精品一区二区三区四区| 国产亚洲美女精品久久久| 成人欧美一区二区三区在线| 国产美女精彩久久| 欧美成人精品一区| 国模视频一区二区三区| 欧美日韩国产中文字幕| 最近2019好看的中文字幕免费| 国产激情久久久| 中文字幕一区二区精品| 日本国产一区二区三区| 国产成人精品国内自产拍免费看| 欧美丰满老妇厨房牲生活| 亚洲欧洲美洲在线综合| 国产精品老牛影院在线观看| 成人欧美一区二区三区在线湿哒哒| 国产成人在线一区二区| 亚洲电影免费观看高清完整版在线观看| 欧美二区在线播放| 精品日韩中文字幕| 久久久999精品| 国产亚洲欧洲在线| 国产精品久久在线观看| 色综合久综合久久综合久鬼88| 国产精品美女久久久久av超清| 国产综合在线视频| 久久精品国产成人| 国产亚洲成av人片在线观看桃| 亚洲精品第一页| 日本亚洲欧美成人| 欧美大尺度在线观看| 最近2019年日本中文免费字幕| 超碰97人人做人人爱少妇| 亚洲第一福利在线观看| y97精品国产97久久久久久| 国产精品69av| 欧美日韩免费区域视频在线观看|