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的一些简单应用,调用其接口来设置自己想要的图片,使图片画出来更加清晰美观。