天天看點

JFreeChart自定義拆線圖

1.說明

現在市面上的畫圖工具很多,不過對于一個比較老的系統,還是會用到JFreeChart的工具。筆者第一次使用JFreeChart是在大學畢業設計中使用。那時候覺得這個架構還不錯。可以畫出柱狀态圖、折線圖等。不過現在看到,覺得JFreeChart畫出來的圖不是非常好看。但是對于一個系統是面向B端來說,還是可以的。最近筆者又重新使用了一次JFreeChart來畫圖,對于這次的開發過程有幾個點的地方比較好的,就在這個部落格中總結一下。

  1. 1技術實作

2.1定義X軸以時間形式顯示

更多時候,我們需要畫出時時動态的折線圖,而這個時時動态的圖需要的是顯示X軸為時間。是以,我們需要定義X軸的顯示為時間,那麼應該怎麼定義呢?主要是使用DateAxis來實作。代碼如下:

//對domain 軸上日期顯示格式定義  
        DateAxis dateaxis = (DateAxis)xyplot.getDomainAxis();   
        dateaxis.setDateFormatOverride(new SimpleDateFormat("HH:mm"));
           

2.2X軸設定

有時候X軸如果是中文的話,我們要防止其亂碼的出現,同時還要設定自己想要的字型。代碼如下:

private static void setDomainAxis(ValueAxis domainAxis){  
        // 解決x軸坐标上中文亂碼  
        domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));  
        // 解決x軸标題中文亂碼  
        domainAxis.setLabelFont(new Font("宋體", Font.PLAIN, 14));  
        // 用于顯示X軸刻度  
        domainAxis.setTickMarksVisible(true);
	//	domainAxis.setLowerMargin(5);// 左邊距 邊框距離  
	//	domainAxis.setUpperMargin(5);// 右邊距 邊框距離,防止最後邊的一個資料靠近了坐标軸。  

    }  
           

2.3X軸的傾斜顯示

   當X軸的資料量很大時,我們需要傾斜顯示文字,這樣是可以節省空間。當然,有時候傾斜顯示會讓整個圖看起來更加美觀。是以傾斜設定代碼如下:

//設定x軸坐标值斜着顯示  
        DateAxis dateAxis = new DateAxis("  ") {    
             @SuppressWarnings("unchecked")    
             protected List<DateTick> refreshTicksHorizontal(Graphics2D g2,    
                    Rectangle2D dataArea, RectangleEdge edge) {    
                 List ticks = super.refreshTicksHorizontal(g2, dataArea, edge);    
                 List<DateTick> newTicks = new ArrayList<DateTick>();    
                 for (Iterator it = ticks.iterator(); it.hasNext();) {    
                     DateTick tick = (DateTick) it.next();    
                     newTicks.add(new DateTick(tick.getDate(), tick.getText(),    
                             TextAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT,    
                            -Math.PI/3));    
                }    
                return newTicks;    
            }    
         };  
         
         xyplot.setDomainAxis(dateAxis);
           

2.4Y軸設定

   Y軸設定時間間隔、亂碼等問題。代碼如下:

numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());  
        // 是否顯示零點  
        numberaxis.setAutoRangeIncludesZero(true);  
        numberaxis.setAutoTickUnitSelection(false); 
        // 解決Y軸标題中文亂碼  
        numberaxis.setLabelFont(new Font("sans-serif", Font.PLAIN, 14));  
        NumberFormat numformatter = NumberFormat.getInstance();
        numformatter.setMaximumFractionDigits(2);   // 設定數值小數點後最多2位  
        numformatter.setMinimumFractionDigits(2);
        numberaxis.setTickUnit(new NumberTickUnit(comMaxVlue/10,numformatter));
      //   numberaxis.setTickUnit(new NumberTickUnit(comMaxVlue/10));//Y軸資料間隔  
        
       
    }  
           

2.5自定義線條顔色

    當我們的折線圖轵有一條線的時候,且我們需要自己定義線條顔色,可以直接通過JFreeChart的接口來實作。代碼如下:

//線條設定
         XYLineAndShapeRenderer xylinerenderer=(XYLineAndShapeRenderer)xyplot.getRenderer();
         xylinerenderer.setSeriesPaint(0, new Color(0,191,255));
           

2.6其它設定

預設的JFreeChart的架構畫圖是會含有内框的,同時背景也不是很看,為了解決這個問題,可以實作下面的設定:

XYPlot xyplot = (XYPlot)imgChart.getPlot();   
        xyplot.setBackgroundPaint(Color.white);  
        xyplot.setDomainGridlinePaint(new Color(112, 128, 144));  
        xyplot.setRangeGridlinePaint(new Color(112, 128, 144));  
        xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));  
        xyplot.setDomainCrosshairVisible(true);  
        xyplot.setRangeCrosshairVisible(true);
        xyplot.setOutlineVisible(false);
        imgChart.setBorderVisible(false);
           
  1. 全部代碼

3.1X軸設定

/** 
     * 折線圖--設定X軸 
     * @param domainAxis 
     */  
    private static void setDomainAxis(ValueAxis domainAxis){  
        // 解決x軸坐标上中文亂碼  
        domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));  
        // 解決x軸标題中文亂碼  
        domainAxis.setLabelFont(new Font("宋體", Font.PLAIN, 14));  
        // 用于顯示X軸刻度  
        domainAxis.setTickMarksVisible(true);
	//	domainAxis.setLowerMargin(5);// 左邊距 邊框距離  
	//	domainAxis.setUpperMargin(5);// 右邊距 邊框距離,防止最後邊的一個資料靠近了坐标軸。  

    }  
           

3.2Y軸設定

/** 
     * 折線圖--設定Y軸 
     * @param numberAxis 
     */  
    private static void setNumberAxis(NumberAxis numberaxis,Double comMaxVlue){  
        numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());  
        // 是否顯示零點  
        numberaxis.setAutoRangeIncludesZero(true);  
        numberaxis.setAutoTickUnitSelection(false); 
        // 解決Y軸标題中文亂碼  
        numberaxis.setLabelFont(new Font("sans-serif", Font.PLAIN, 14));  
        NumberFormat numformatter = NumberFormat.getInstance();
        numformatter.setMaximumFractionDigits(2);   // 設定數值小數點後最多2位  
        numformatter.setMinimumFractionDigits(2);
        numberaxis.setTickUnit(new NumberTickUnit(comMaxVlue/10,numformatter));
      //   numberaxis.setTickUnit(new NumberTickUnit(comMaxVlue/10));//Y軸資料間隔  
        
       
    }
           

3.3畫圖

/** 
     * 畫折線圖
     *  
     * @return 
     */  
    public static String getJFreeChart(XYDataset dates, String cite,Double comMaxVlue,String imagePth,String resourceName,String key) {  
        JFreeChart imgChart=null;  
        // JFreeChart對象 參數:标題,目錄軸顯示标簽,數值軸顯示标簽,資料集,是否顯示圖例,是否生成工具,是否生成URL連接配接  
        //平面  
        imgChart = ChartFactory.createTimeSeriesChart(
        		"", 
        		"", 
        		"",  
        		dates, false, true, true);  
        imgChart.setBackgroundPaint(Color.white);  
        imgChart.setBorderVisible(true);// 邊框可見  
        TextTitle title = new TextTitle(cite, new Font("宋體", Font.BOLD, 20));  
        // 解決曲線圖檔标題中文亂碼問題  
        imgChart.setTitle(title);  
        //解決圖表底部中文亂碼問題  
     //   imgChart.getLegend().setItemFont(new Font("宋體", Font.PLAIN, 12));  
          
        //獲得 plot : XYPlot!!  
        XYPlot xyplot = (XYPlot)imgChart.getPlot();   
        xyplot.setBackgroundPaint(Color.white);  
        xyplot.setDomainGridlinePaint(new Color(112, 128, 144));  
        xyplot.setRangeGridlinePaint(new Color(112, 128, 144));  
        xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));  
        xyplot.setDomainCrosshairVisible(true);  
        xyplot.setRangeCrosshairVisible(true);
        xyplot.setOutlineVisible(false);
        imgChart.setBorderVisible(false);
        
        //設定x軸坐标值斜着顯示  
        DateAxis dateAxis = new DateAxis("  ") {    
             @SuppressWarnings("unchecked")    
             protected List<DateTick> refreshTicksHorizontal(Graphics2D g2,    
                    Rectangle2D dataArea, RectangleEdge edge) {    
                 List ticks = super.refreshTicksHorizontal(g2, dataArea, edge);    
                 List<DateTick> newTicks = new ArrayList<DateTick>();    
                 for (Iterator it = ticks.iterator(); it.hasNext();) {    
                     DateTick tick = (DateTick) it.next();    
                     newTicks.add(new DateTick(tick.getDate(), tick.getText(),    
                             TextAnchor.TOP_RIGHT, TextAnchor.TOP_RIGHT,    
                            -Math.PI/3));    
                }    
                return newTicks;    
            }    
         };  
         
         xyplot.setDomainAxis(dateAxis);  
         // Y軸  
         NumberAxis numberaxis = (NumberAxis) xyplot.getRangeAxis();  
         numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 
       //  setNumberAxis(numberaxis,comMaxVlue);  
        // x軸  
         ValueAxis domainAxis = xyplot.getDomainAxis();  
         setDomainAxis(domainAxis); 
         
         //線條設定
         XYLineAndShapeRenderer xylinerenderer=(XYLineAndShapeRenderer)xyplot.getRenderer();
         xylinerenderer.setSeriesPaint(0, new Color(0,191,255)); 
        //對domain 軸上日期顯示格式定義  
        DateAxis dateaxis = (DateAxis)xyplot.getDomainAxis();   
        dateaxis.setDateFormatOverride(new SimpleDateFormat("HH:mm"));  

        //儲存圖像的大小  
		int weight = 800;  
		int height = 600; 
		File resourceFile = new File(imagePth + File.separator+ resourceName+File.separator+key);
	    
		if(!resourceFile.exists())
	    {
		 resourceFile.mkdirs();
	    }

		String putImage = resourceFile.getPath() + File.separator+key+".png";
		//存放圖像的目錄   
		saveAsFile(imgChart, putImage, weight, height);
        
        
        return putImage;  
    }  
           

3.4儲存

// 儲存為圖像檔案       
	public static void saveAsFile(JFreeChart chart, String outputPath, int weight, int height) {       
        FileOutputStream out = null;       
        try {       
            File outFile = new File(outputPath);       
            if (!outFile.getParentFile().exists()) {       
                outFile.getParentFile().mkdirs();       
                }       
            out = new FileOutputStream(outputPath);       
            // 儲存為PNG       
            ChartUtilities.writeChartAsPNG(out, chart, weight, height);             
            out.flush();       
            } catch (FileNotFoundException e) {       
                e.printStackTrace();       
            } catch (IOException e) {       
                e.printStackTrace();       
            } finally {       
                if (out != null) {       
                    try {       
                        out.close();       
                        } catch (IOException e) {       
                            // do nothing       
                        }       
                }       
            }       
	    }    
           

4.效果圖

JFreeChart自定義拆線圖

5.總結

   這裡主要是介紹JFreeChart的一些簡單應用,調用其接口來設定自己想要的圖檔,使圖檔畫出來更加清晰美觀。