1.說明
現在市面上的畫圖工具很多,不過對于一個比較老的系統,還是會用到JFreeChart的工具。筆者第一次使用JFreeChart是在大學畢業設計中使用。那時候覺得這個架構還不錯。可以畫出柱狀态圖、折線圖等。不過現在看到,覺得JFreeChart畫出來的圖不是非常好看。但是對于一個系統是面向B端來說,還是可以的。最近筆者又重新使用了一次JFreeChart來畫圖,對于這次的開發過程有幾個點的地方比較好的,就在這個部落格中總結一下。
- 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);
- 全部代碼
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.效果圖
5.總結
這裡主要是介紹JFreeChart的一些簡單應用,調用其接口來設定自己想要的圖檔,使圖檔畫出來更加清晰美觀。