1. 程式人生 > >圖書管理系統總結——統計圖實現

圖書管理系統總結——統計圖實現

多少 election stat 定義變量 解決 格式 exception als fin

JAVA的JFreeChar提供了繪制各種與統計有關的圖形,比如直方圖,折線圖,餅圖等,而且有各種樣式。這裏只是應用了最簡單的繪制,沒有什麽炫酷的修飾。

一、餅狀圖:

技術分享

實現餅狀圖的類為

public class PieChart {
    ChartPanel frame1;
    
    public PieChart() {
        super();
        // TODO Auto-generated constructor stub
    }
    /**
     * 畫出指定大小餅狀圖
     * @param v 表示圖片大小
     * @param
TypeBuffer 用來記錄圖書種類 * @param number 用來記錄每種圖書對應的數量 */ public PieChart(Dimension v,StringBuffer[] TypeBuffer,int[] number) { DefaultPieDataset data = getDataSet(TypeBuffer,number);//數據集獲得 JFreeChart chart = ChartFactory.createPieChart3D(
"借閱分類分布",//// 圖表標題 data,//數據集 true,// 是否顯示圖例 false,// 是否生成工具 false// 是否生成URL鏈接 );// 創建圖表 //設置百分比 PiePlot pieplot = (PiePlot) chart.getPlot(); DecimalFormat df
= new DecimalFormat("0.00%");//獲得一個DecimalFormat對象,主要是設置小數問題 NumberFormat nf = NumberFormat.getNumberInstance();//獲得一個NumberFormat對象 StandardPieSectionLabelGenerator sp1 = new StandardPieSectionLabelGenerator("{0} {2}", nf, df);//獲得StandardPieSectionLabelGenerator對象 pieplot.setLabelGenerator(sp1);//設置餅圖顯示百分比 //沒有數據的時候顯示的內容 pieplot.setNoDataMessage("無數據顯示"); pieplot.setCircular(false); pieplot.setLabelGap(0.02D); pieplot.setIgnoreNullValues(true);//設置不顯示空值 pieplot.setIgnoreZeroValues(true);//設置不顯示負值 frame1=new ChartPanel (chart,true); frame1.setPreferredSize(new Dimension(v));//設置大小 chart.getTitle().setFont(new Font("宋體",Font.BOLD,35));//設置標題字體 PiePlot piePlot= (PiePlot) chart.getPlot();//獲取圖表區域對象 piePlot.setLabelFont(new Font("宋體",Font.BOLD,30));//解決亂碼,設置標簽的字體 chart.getLegend().setItemFont(new Font("黑體",Font.BOLD,35));//設置下面圖例字體 } /** *生成與外界窗口一樣大小圖 * @param TypeBuffer * @param number */ public PieChart(StringBuffer[] TypeBuffer,int[] number) { DefaultPieDataset data = getDataSet(TypeBuffer,number); JFreeChart chart = ChartFactory.createPieChart3D("借閱分類分布",data,true,false,false); //設置百分比 PiePlot pieplot = (PiePlot) chart.getPlot(); DecimalFormat df = new DecimalFormat("0.00%");//獲得一個DecimalFormat對象,主要是設置小數問題 NumberFormat nf = NumberFormat.getNumberInstance();//獲得一個NumberFormat對象 StandardPieSectionLabelGenerator sp1 = new StandardPieSectionLabelGenerator("{0} {2}", nf, df);//獲得StandardPieSectionLabelGenerator對象 pieplot.setLabelGenerator(sp1);//設置餅圖顯示百分比 //沒有數據的時候顯示的內容 pieplot.setNoDataMessage("無數據顯示"); pieplot.setCircular(false); pieplot.setLabelGap(0.02D); pieplot.setIgnoreNullValues(true);//設置不顯示空值 pieplot.setIgnoreZeroValues(true);//設置不顯示負值 frame1=new ChartPanel (chart,true); chart.getTitle().setFont(new Font("宋體",Font.BOLD,35));//設置標題字體 PiePlot piePlot= (PiePlot) chart.getPlot();//獲取圖表區域對象 piePlot.setLabelFont(new Font("宋體",Font.BOLD,30));//解決亂碼 chart.getLegend().setItemFont(new Font("黑體",Font.BOLD,35)); } /** * 獲得數據集 * @param TypeBuffer * @param number * @return */ private static DefaultPieDataset getDataSet(StringBuffer[] TypeBuffer,int[] number) { DefaultPieDataset dataset = new DefaultPieDataset(); for(int i=0;i<TypeBuffer.length;++i) { if(StringUtil.isEmpty(TypeBuffer[i].toString()))//每個下標對應圖書類別的主鍵,如果那個主鍵下沒有記錄,跳過 { continue; } else { dataset.setValue(TypeBuffer[i].toString(),number[i]);//數據集來自圖書種類名稱和相應種類的借閱本數 } } return dataset; } public ChartPanel getChartPanel(){ return frame1; } }

其中TypeBuffer和number獲得方式就是掃描借閱記錄的表格,將每條記錄圖書類別的主鍵作為這兩個數組的下標,++即可:

/**
 * 借閱分布統計
 */
private void HisBorrowPieChart(StringBuffer[] TypeBuffer,int[] number)
{
    Connection con=null;
    try {
        con=dbUtil.getCon();
        Arrays.fill(number,0);//初始將所有類別本數置0
        for(int i=0;i<TypeBuffer.length;++i)
        {
             TypeBuffer[i]=new StringBuffer();//切記StringBuffer需要分配空間!這是與String最大不同
        }
        if(StringUtil.isEmpty(PresentUser))
        {
            Dialogutil attention=new Dialogutil(null,"Attention!","用戶信息獲取失敗!");
            return;
        }
        else            
        {
            //找到當前書和用戶
            User user=new User(PresentUser);
            ResultSet Hisbo=borrowDao.HisBorrowDistri(con,user);//獲取所有記錄,由用戶ID查找
            while( Hisbo.next()){
                int index=Hisbo.getInt("bt.id");//主鍵作為數組下標
                if(StringUtil.isEmpty(TypeBuffer[index].toString()))
                {                    TypeBuffer[index].append(Hisbo.getString("bt.bookTypeName"));
                }
                number[index]++;                
            }
        }        
    } catch (Exception e) {
        Dialogutil attention=new Dialogutil(null,"Attention!","用戶信息獲取失敗!");
        e.printStackTrace();
    }    
}

調用方式為:

HisBorrowPieChart(TypeBuffer,TypeNum);//更新數據集
PieChartJP.add(new PieChart(PieDi,TypeBuffer,TypeNum).getChartPanel());//添加餅狀圖 ,畫在一個Jpanel容器中

二、折線圖

技術分享

public class TimeSeriesChart 
{
    ChartPanel frame1;
/**
     * 折線圖構造函數
     * @param v 折線圖大小
     * @param BookMonthly 記錄每個月本數,下標與月對應
     * @param CurrentYear  記錄當前年份
     */
    public TimeSeriesChart(Dimension v,int []BookMonthly,int CurrentYear)
{
        XYDataset xydataset = createDataset(BookMonthly,CurrentYear);
        JFreeChart jfreechart = ChartFactory.createTimeSeriesChart("借閱趨勢",//標題
                                                 "月份", //橫坐標
                                                 "數量",//縱坐標
                                                  xydataset,//數據集
                                                   true,//有圖例
                                                  true,//有工具集
                                                    true//統一資源定位圖
                                                     );
        XYPlot xyplot = (XYPlot) jfreechart.getPlot();  // 獲取繪圖區對象
        DateAxis dateaxis = (DateAxis) xyplot.getDomainAxis();
        DecimalFormat df = new DecimalFormat("#0");//整數
        //y軸用整數表示
        ((NumberAxis) ((XYPlot)jfreechart.getPlot()).getRangeAxis()).setNumberFormatOverride(df);
        
        dateaxis.setDateFormatOverride(new SimpleDateFormat("MMM"));//橫軸格式-yyyy
        
        frame1=new ChartPanel(jfreechart,true);
        frame1.setPreferredSize(new Dimension(v));//設置大小
        
        dateaxis.setLabelFont(new Font("黑體",Font.BOLD,30));         //水平底部標題
        dateaxis.setTickLabelFont(new Font("宋體",Font.BOLD,30));  //垂直標題
       // axis0.setLabelFont(new Font("黑體", Font.PLAIN, 12));// y軸字體
        ValueAxis rangeAxis=xyplot.getRangeAxis();//獲取柱狀
        rangeAxis.setLabelFont(new Font("黑體",Font.BOLD,35));
        jfreechart.getLegend().setItemFont(new Font("黑體", Font.BOLD, 30));
        //設定y在軸顯示範圍
       // NumberAxis domainAxis = (NumberAxis)xyplot.getDomainAxis();
        //縱軸從0開始
        //((NumberAxis)rangeAxis).setAutoRangeIncludesZero(true); 
        rangeAxis.setLowerBound(0);
        //找最大值
         int max = BookMonthly[0];//定義變量
            for (int x=1; x<BookMonthly.length; x++ )
            {
                if (BookMonthly[x]>max)
                {
                    max = BookMonthly[x];
                }
            }       
        rangeAxis.setUpperBound(max+1);//顯示最大設為記錄中最大值+1
     // 設置y軸不是使用自動刻度
        ((NumberAxis)rangeAxis).setAutoTickUnitSelection(false);
        // 設置刻度
        NumberTickUnit numberTickUnit = new NumberTickUnit(1);
        ((NumberAxis)rangeAxis).setTickUnit(numberTickUnit);
        jfreechart.getTitle().setFont(new Font("宋體",Font.BOLD,35));//設置標題字體

    } 
     private static XYDataset createDataset(int []BookMonthly,int CurrentYear) 
     {  //這個數據集有點多,但都不難理解
            TimeSeries timeseries = new TimeSeries(Integer.toString(CurrentYear)+"各月借閱數量",
                    org.jfree.data.time.Month.class);//時間軸精確到月
            timeseries.add(new Month(1,CurrentYear), BookMonthly[1]);//設置每個月數量
            timeseries.add(new Month(2,CurrentYear), BookMonthly[2]);
            timeseries.add(new Month(3,CurrentYear), BookMonthly[3]);
            timeseries.add(new Month(4,CurrentYear), BookMonthly[4]);
            timeseries.add(new Month(5,CurrentYear), BookMonthly[5]);
            timeseries.add(new Month(6,CurrentYear), BookMonthly[6]);
            timeseries.add(new Month(7,CurrentYear), BookMonthly[7]);
            timeseries.add(new Month(8,CurrentYear), BookMonthly[8]);
            timeseries.add(new Month(9,CurrentYear), BookMonthly[9]);
            timeseries.add(new Month(10,CurrentYear), BookMonthly[10]);
            timeseries.add(new Month(11,CurrentYear), BookMonthly[11]);
            timeseries.add(new Month(12,CurrentYear), BookMonthly[12]);            
            TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();
            timeseriescollection.addSeries(timeseries);
            return timeseriescollection;
        }
      public ChartPanel getChartPanel()
      {
            return frame1;            
        }
}

數組BookMonthly對應值獲得同樣先連接數據庫,掃描借閱表,取出其中的借閱日期,以月作為數組下標++即可:

//找到當前書和用戶
            User user=new User(PresentUser);
            //獲取當前時間
            java.sql.Date currentDate = new java.sql.Date(System.currentTimeMillis());
            DateInt curdate=new DateInt();
            DateUtil.getdate(currentDate, curdate);
            this.CurrentYear=curdate.getYear();
            ResultSet Hisbo=borrowDao.HisBorrowTrend(con,user);//獲取所有記錄,由用戶ID查找
            while( Hisbo.next())
            {
                DateInt date=new DateInt();                
                DateUtil.getdate(Hisbo.getDate("borTime"), date);                
                if(curdate.getYear()==date.getYear())
                {
                    BookMonthly[date.getMonth()]++;//只統計當前年份
                }
                else
                {
                    continue;
                }
            }

使用折線圖方式:

HisBorrowBrokenLine(BookMonthly);//更新數據集
BrokenLineJP.add(new TimeSeriesChart(Linetrend,BookMonthly,CurrentYear).getChartPanel()); //添加折線圖  

三、柱狀圖:

技術分享

柱狀圖構造類實現方式:

public class BarChart {
      ChartPanel frame1; 
      
      public BarChart() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * 柱狀圖構造函數
     * @param TypeBuffer 圖書種類名稱
     * @param number   圖書種類對應數目
     */
    public  BarChart(StringBuffer[] TypeBuffer,int[] number)
      {  
      CategoryDataset dataset = getDataSet(TypeBuffer,number);  
      JFreeChart chart = ChartFactory.createBarChart3D( "各類圖書借閱統計", // 圖表標題  
                                "圖書種類", // 目錄軸的顯示標簽  
                                "數量", // 數值軸的顯示標簽  
                                dataset, // 數據集  
                                PlotOrientation.VERTICAL, // 圖表方向:水平、垂直  
                                true,           // 是否顯示圖例(對於簡單的柱狀圖必須是false)  
                                false,          // 是否生成工具  
                                false           // 是否生成URL鏈接  
                                );  
              
         CategoryPlot plot=chart.getCategoryPlot();//獲取圖表區域對象  
         CategoryAxis domainAxis=plot.getDomainAxis();         //水平底部列表  
         domainAxis.setLabelFont(new Font("黑體",Font.BOLD,30));         //水平底部標題  
         domainAxis.setTickLabelFont(new Font("宋體",Font.BOLD,30));  //垂直標題  
         
         ValueAxis rangeAxis=plot.getRangeAxis();//獲取柱狀  
         //設置刻度
         NumberTickUnit numberTickUnit = new NumberTickUnit(1);
         ((NumberAxis)rangeAxis).setTickUnit(numberTickUnit);
         //設置柱狀圖頂部數字
         BarRenderer3D renderer = (BarRenderer3D) plot.getRenderer(); //獲得當前數據
         renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); //顯示每個柱的數值  
         
         renderer.setBaseItemLabelsVisible(true);  
         renderer.setBaseItemLabelPaint(Color.BLACK);  
         renderer.setBaseItemLabelFont(new Font("宋書",Font.PLAIN,30));  
       //註意:此句很關鍵,若無此句,那數字的顯示會被覆蓋,給人數字沒有顯示出來的問題 
         renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition
                 (ItemLabelAnchor.OUTSIDE12,TextAnchor.BASELINE_CENTER ));//表示顯示在上方,中間
         //ItemLabelAnchor.OUTSIDE3(顯示在垂直方向中間), TextAnchor.BASELINE_RIGHT(顯示在柱子右邊)
         renderer.setItemLabelAnchorOffset(10D);// 設置柱形圖上的文字偏離值 
         rangeAxis.setLabelFont(new Font("黑體",Font.BOLD,15));  
         chart.getLegend().setItemFont(new Font("黑體", Font.BOLD, 30));  
         chart.getTitle().setFont(new Font("宋體",Font.BOLD,30));//設置標題字體                  
         //到這裏結束,雖然代碼有點多,但只為一個目的,解決漢字亂碼問題              
          frame1=new ChartPanel(chart,true);        //這裏也可以用chartFrame,可以直接生成一個獨立的Frame             
        } 
        
        /**
         * 獲取數據
         * @return
         */
       private static CategoryDataset getDataSet(StringBuffer[] TypeBuffer,int[] number) 
       {  
           DefaultCategoryDataset dataset = new DefaultCategoryDataset();  
           for(int i=0;i<TypeBuffer.length;++i)
            {
               if(StringUtil.isEmpty(TypeBuffer[i].toString()))
                {
                    continue;
                }
               else
               {
                   dataset.addValue(number[i],TypeBuffer[i].toString(),TypeBuffer[i].toString());
               }
            }

           return dataset;  
}  
    public ChartPanel getChartPanel()
    {  
        return frame1;  
        
    }  
}

數據集和餅狀圖一樣。但這裏顯示時候是管理員圖書統計按鈕下單獨開的一個JFrame窗口,與餅狀圖一起上下排列顯示:

public class Statistic extends JFrame {

    private JPanel contentPane;
     //設置跟隨分辨率變化窗口
    Toolkit kit = Toolkit.getDefaultToolkit();
    Dimension screenSize = kit.getScreenSize();
    private int screenHeight = (int) screenSize.getHeight();
    private int screenWidth = (int) screenSize.getWidth();
    private double enlargement_x=screenWidth/1920;
    private double enlargement_y=screenHeight/1080;
    private int windowWidth ; //獲得窗口寬
    private int windowHeight; //獲得窗口高
    /*******************統計變量***************************************/
    final private int typenum=50;//用於存放有多少圖書種類
       int []TypeNum=new int[typenum];
    StringBuffer[] TypeBuffer=new StringBuffer[typenum];//記錄各類書數量
    int []BookMonthly=new int[13];//統計各月借閱數量,下標與月份對齊
    int CurrentYear;//當前年份,用於折線圖數據
    /**************************數據庫操作****************************************/
    DbUtil dbUtil=new DbUtil();//數據庫連接類
    BorrowDao borrowDao=new BorrowDao();//借閱表類
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    Statistic frame = new Statistic();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public Statistic() 
    {
        setResizable(false);
        setTitle("\u6570\u636E\u7EDF\u8BA1\u56FE");
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
        setBounds(screenWidth * 2/7, screenHeight / 3, (int)(1400*enlargement_x),(int)(1600*enlargement_y));
        windowWidth = this.getWidth(); //獲得窗口寬
        windowHeight = this.getHeight(); //獲得窗口高
        this.setLocation(screenWidth / 2 - windowWidth / 2, screenHeight / 2 - windowHeight / 2);//設置窗口居中顯示
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(new GridLayout(2,1,10,10));
         //Dimension PieDi=new Dimension(50,80);
        HisBorrowPieChart(TypeBuffer,TypeNum);//獲得數據
        contentPane.add(new PieChart(TypeBuffer,TypeNum).getChartPanel());           //添加餅狀圖  
        contentPane.add(new BarChart(TypeBuffer,TypeNum).getChartPanel());//添加柱形圖  
        //設置JFrame最大化
        //this.setExtendedState(JFrame.MAXIMIZED_BOTH); 
    }

}

圖書管理系統總結——統計圖實現