JFreeChart是一组功能强大、灵活易用的Java绘图API,使用它可以生成多种通用性的报表,包括柱状图、饼图、曲线图、甘特图等。它能够用在Swing和Web等中制作自定义的图表或报表,并且得到广泛的应用。本文将通过引领读者学习在JFreeChart中饼图、柱状图和曲线图的进阶应用,来达到熟练使用JFreeChart的目的。
在使用jfreechart时,一般先通过ChartFactory中的静态方法生成一个JFreeChart对象,然后调用ChartUtilities类中的方法将JFreeChart导出成图片。
JFreeChart的问题估计就在结构的复杂性,每种类型的图表都需要使用对应的DataSet和Plot才能生成出来,开发者必须掌握这些模型和结构之间的关系才能生成出计划中的图表来。
factory模式让JFreeChart不是很容易扩展,多种数据模型和设计模型散乱着放在几个包中,实话说真是太难找了。
JFreeChart还自带一系列的中文乱码问题,必须重新指定所有标签部分的字体才能解决乱码问题。
lib包:jcommon-1.0.16.jar和jfreechart-1.0.13.jar
一:柱状图(bar)
代码一:
package cn.itcast.chart; import java.awt.Font; import java.io.File; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis3D; import org.jfree.chart.axis.NumberAxis3D; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.BarRenderer3D; import org.jfree.data.category.DefaultCategoryDataset; public class BarDemo { public static void main(String[] args) { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); //添加数据 dataset.addValue(13, "所属单位", "北京"); dataset.addValue(6, "所属单位", "深圳"); dataset.addValue(2, "所属单位", "上海"); JFreeChart chart = ChartFactory.createBarChart3D("用户统计报表(所属单位)",//主标题的名称 "所属单位名称", //x轴的标签 "数量", //y轴的标签 dataset, //图标显示的数据集合 PlotOrientation.VERTICAL,//图像的显示形式(水平或者垂直) true, //是否显示自标题 true, //是否生成提示的标签 true);//是否生成URL 链接 //处理图形上的乱码 //处理主标题的乱码 chart.getTitle().setFont(new Font("宋体",Font.BOLD,18)); //处理自标题乱码 chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,18)); //获取图表区域对象 CategoryPlot categoryPlot = (CategoryPlot) chart.getPlot(); //获取X轴的对象 CategoryAxis3D categoryAxis3D = (CategoryAxis3D) categoryPlot.getDomainAxis(); //获取Y轴的对象 NumberAxis3D numberAxis3D = (NumberAxis3D) categoryPlot.getRangeAxis(); //处理X轴上的乱码 categoryAxis3D.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理X轴外的乱码 categoryAxis3D.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上的乱码 numberAxis3D.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴外的乱码 numberAxis3D.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上显示的刻度,以1作为1格 数值是double类型,如果是人的话,只能用int, numberAxis3D.setAutoTickUnitSelection(false); NumberTickUnit unit = new NumberTickUnit(1); numberAxis3D.setTickUnit(unit); //获取绘图区域对象 BarRenderer3D barRenderer3D = (BarRenderer3D) categoryPlot.getRenderer(); //设置柱形图的宽度 barRenderer3D.setMaximumBarWidth(0.07); //在图形上显示数字 barRenderer3D.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); barRenderer3D.setBaseItemLabelsVisible(true); barRenderer3D.setBaseItemLabelFont(new Font("宋体",Font.BOLD,15)); /** * 下面代码可以把生成的图片放在磁盘目录下:比如:<span style="font-family: Arial;">D:/chart.jpeg</span> * 生成图片的格式:jpeg */ //begin File file = new File("D:/chart.jpeg"); try{ ChartUtilities.saveChartAsJPEG(file, chart, 800, 600); }catch(Exception e){ e.printStackTrace(); } //end //使用ChartFrame对象显示图像 ChartFrame frame = new ChartFrame("xyz",chart); frame.setVisible(true); frame.pack(); } }生成的柱形图如下:
代码二:
package cn.itcast.chart; import java.awt.Font; import java.io.File; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis3D; import org.jfree.chart.axis.NumberAxis3D; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.BarRenderer3D; import org.jfree.data.category.DefaultCategoryDataset; public class Bar2Demo { public static void main(String[] args) { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); //添加数据 dataset.addValue(13, "所属单位", "北京"); dataset.addValue(6, "所属单位", "深圳"); dataset.addValue(2, "所属单位", "上海"); <span style="color:#3333ff;">dataset.addValue(8, "美国", "纽约"); dataset.addValue(10, "美国", "旧金山"); dataset.addValue(7, "美国", "华盛顿");</span> JFreeChart chart = ChartFactory.createBarChart3D("用户统计报表(所属单位)",//主标题的名称 "所属单位名称", //x轴的标签 "数量", //y轴的标签 dataset, //图标显示的数据集合 PlotOrientation.VERTICAL,//图像的显示形式(水平或者垂直) true, //是否显示自标题 true, //是否生成提示的标签 true);//是否生成URL 链接 //处理图形上的乱码 //处理主标题的乱码 chart.getTitle().setFont(new Font("宋体",Font.BOLD,18)); //处理自标题乱码 chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,18)); //获取图表区域对象 CategoryPlot categoryPlot = (CategoryPlot) chart.getPlot(); //获取X轴的对象 CategoryAxis3D categoryAxis3D = (CategoryAxis3D) categoryPlot.getDomainAxis(); //获取Y轴的对象 NumberAxis3D numberAxis3D = (NumberAxis3D) categoryPlot.getRangeAxis(); //处理X轴上的乱码 categoryAxis3D.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理X轴外的乱码 categoryAxis3D.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上的乱码 numberAxis3D.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴外的乱码 numberAxis3D.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上显示的刻度,以1作为1格 numberAxis3D.setAutoTickUnitSelection(false); NumberTickUnit unit = new NumberTickUnit(1); numberAxis3D.setTickUnit(unit); //获取绘图区域对象 BarRenderer3D barRenderer3D = (BarRenderer3D) categoryPlot.getRenderer(); //设置柱形图的宽度 barRenderer3D.setMaximumBarWidth(0.07); //在图形上显示数字 barRenderer3D.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); barRenderer3D.setBaseItemLabelsVisible(true); barRenderer3D.setBaseItemLabelFont(new Font("宋体",Font.BOLD,15)); /** * 下面代码可以把生成的图片放在磁盘目录下: * 生成图片的格式:jpeg */ //begin File file = new File("D:/chart.jpeg"); try{ ChartUtilities.saveChartAsJPEG(file, chart, 800, 600); }catch(Exception e){ e.printStackTrace(); } //end //使用ChartFrame对象显示图像 ChartFrame frame = new ChartFrame("xyz",chart); frame.setVisible(true); frame.pack(); } }生成的柱形图如下:
二:折线图(line)
代码一:
package cn.itcast.chart; import java.awt.Font; import java.awt.Rectangle; import java.io.File; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.LineAndShapeRenderer; import org.jfree.data.category.DefaultCategoryDataset; public class LineDemo { public static void main(String[] args) { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); //添加数据 dataset.addValue(13, "所属单位", "北京"); dataset.addValue(6, "所属单位", "深圳"); dataset.addValue(2, "所属单位", "上海"); JFreeChart chart =ChartFactory.createLineChart("用户统计报表(所属单位)", //主标题的名称 "所属单位名称", //X轴的标签 "数量", //Y轴的标签 dataset, //图标显示的数据集合 PlotOrientation.VERTICAL, //图像的显示形式(水平或者垂直) true, //是否显示子标题 true, //是否生成提示的标签 true);//是否生成URL链接 //处理图形上的乱码 //处理主标题的乱码 chart.getTitle().setFont(new Font("宋体",Font.BOLD,18)); //处理子标题乱码 chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,15)); //获取图表区域对象 CategoryPlot categoryPlot = (CategoryPlot) chart.getPlot(); //获取X轴的对象 CategoryAxis categoryAxis = (CategoryAxis)categoryPlot.getDomainAxis(); //获取Y轴的对象 NumberAxis numberAxis = (NumberAxis) categoryPlot.getRangeAxis(); //处理X轴上的乱码 categoryAxis.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理X轴外的乱码 categoryAxis.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上的乱码 numberAxis.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴外的乱码 numberAxis.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上显示的刻度,以1作为1格 numberAxis.setAutoTickUnitSelection(false); NumberTickUnit unit = new NumberTickUnit(1); numberAxis.setTickUnit(unit); //获取绘图区域对象 LineAndShapeRenderer lineAndShapeRenderer = (LineAndShapeRenderer) categoryPlot.getRenderer(); //在图形上显示数字 lineAndShapeRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); lineAndShapeRenderer.setBaseItemLabelsVisible(true); lineAndShapeRenderer.setBaseItemLabelFont(new Font("宋体",Font.BOLD,15)); //在图形上添加转折点(使用小矩形显示) Rectangle shape = new Rectangle(10,10); lineAndShapeRenderer.setSeriesShape(0, shape); lineAndShapeRenderer.setSeriesShapesVisible(0, true); /** * 下面代码可以把生成的图片放在磁盘目录下: * 生成图片的格式:jpeg */ //begin File file = new File("D:/chart.jpeg"); try{ ChartUtilities.saveChartAsJPEG(file, chart, 800, 600); }catch(Exception e){ e.printStackTrace(); } //end //使用chartFrame对象显示图像 ChartFrame frame = new ChartFrame("xyz",chart); frame.setVisible(true); frame.pack(); } }
代码二:
<span style="background-color: rgb(255, 255, 255);">package cn.itcast.chart; import java.awt.Font; import java.awt.Rectangle; import java.io.File; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.CategoryAxis; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.axis.NumberTickUnit; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.LineAndShapeRenderer; import org.jfree.data.category.DefaultCategoryDataset; public class LineDemo { public static void main(String[] args) { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); //添加数据 dataset.addValue(13, "中国", "北京"); dataset.addValue(6, "中国", "深圳"); dataset.addValue(2, "中国", "上海"); dataset.addValue(8, "美国", "纽约"); dataset.addValue(10, "美国", "旧金山"); dataset.addValue(7, "美国", "华盛顿"); JFreeChart chart =ChartFactory.createLineChart("用户统计报表(所属单位)", //主标题的名称 "所属单位名称", //X轴的标签 "数量", //Y轴的标签 dataset, //图标显示的数据集合 PlotOrientation.VERTICAL, //图像的显示形式(水平或者垂直) true, //是否显示子标题 true, //是否生成提示的标签 true);//是否生成URL链接 //处理图形上的乱码 //处理主标题的乱码 chart.getTitle().setFont(new Font("宋体",Font.BOLD,18)); //处理子标题乱码 chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,15)); //获取图表区域对象 CategoryPlot categoryPlot = (CategoryPlot) chart.getPlot(); //获取X轴的对象 CategoryAxis categoryAxis = (CategoryAxis)categoryPlot.getDomainAxis(); //获取Y轴的对象 NumberAxis numberAxis = (NumberAxis) categoryPlot.getRangeAxis(); //处理X轴上的乱码 categoryAxis.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理X轴外的乱码 categoryAxis.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上的乱码 numberAxis.setTickLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴外的乱码 numberAxis.setLabelFont(new Font("宋体",Font.BOLD,15)); //处理Y轴上显示的刻度,以1作为1格 numberAxis.setAutoTickUnitSelection(false); NumberTickUnit unit = new NumberTickUnit(1); numberAxis.setTickUnit(unit); //获取绘图区域对象 LineAndShapeRenderer lineAndShapeRenderer = (LineAndShapeRenderer) categoryPlot.getRenderer(); System.out.println(lineAndShapeRenderer); //在图形上显示数字 lineAndShapeRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); lineAndShapeRenderer.setBaseItemLabelsVisible(true); lineAndShapeRenderer.setBaseItemLabelFont(new Font("宋体",Font.BOLD,15)); //在图形上添加转折点(使用小矩形显示) Rectangle shape = new Rectangle(10,10); <span style="color:#3366ff;">/** * 如果是一条折线图 */</span> lineAndShapeRenderer.setSeriesShape(0, shape); lineAndShapeRenderer.setSeriesShapesVisible(0, true); <span style="color:#3366ff;">/** * 如果是二条折线图,如果更多依次类推 */</span> lineAndShapeRenderer.setSeriesShape(1, shape); lineAndShapeRenderer.setSeriesShapesVisible(1, true); /** * 下面代码可以把生成的图片放在磁盘目录下: * 生成图片的格式:jpeg */ //begin File file = new File("D:/chart.jpeg"); try{ ChartUtilities.saveChartAsJPEG(file, chart, 800, 600); }catch(Exception e){ e.printStackTrace(); } //end //使用chartFrame对象显示图像 ChartFrame frame = new ChartFrame("xyz",chart); frame.setVisible(true); frame.pack(); } } </span>生成的折线图如下:
三:饼图(pie)
代码一:
package cn.itcast.chart; import java.awt.Font; import java.io.File; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.labels.StandardPieSectionLabelGenerator; import org.jfree.chart.plot.PiePlot3D; import org.jfree.data.general.DefaultPieDataset; public class PieDemo { public static void main(String[] args) { DefaultPieDataset dataset = new DefaultPieDataset(); //添加数据 dataset.setValue("北京 ", 13); dataset.setValue("深圳 ", 6); dataset.setValue("上海 ", 2); JFreeChart chart = ChartFactory.createPieChart3D("用户统计报表(所属单位)",//主标题的名称 dataset, //图标显示的数据集合 true, //是否显示子标题 true, //是否生成提示的标签 true);//是否生成URL链接 //处理图形上的乱码 //处理主标题的乱码 chart.getTitle().setFont(new Font("宋体",Font.BOLD,18)); //处理子标题乱码 chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,15)); //获取图表区域对象 PiePlot3D categoryPlot = (PiePlot3D) chart.getPlot(); //处理图像上的乱码 categoryPlot.setLabelFont(new Font("宋体",Font.BOLD,15)); //设置图形的生成格式为(上海 2 (10%)) String format = "{0} {1} ({2})"; categoryPlot.setLabelGenerator(new StandardPieSectionLabelGenerator(format)); /** * 下面代码可以把生成的图片放在磁盘目录下: * 生成图片的格式:jpeg */ //begin File file = new File("D:/chart.jpeg"); try{ ChartUtilities.saveChartAsJPEG(file, chart, 800, 600); }catch(Exception e){ e.printStackTrace(); } //end //使用ChartFrame对象显示图像 ChartFrame frame = new ChartFrame("xyz",chart); frame.setVisible(true); frame.pack(); } }生成的饼图如下:
代码二:
package cn.itcast.chart; import java.awt.Font; import java.io.File; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartFrame; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.labels.StandardPieSectionLabelGenerator; import org.jfree.chart.plot.PiePlot3D; import org.jfree.data.general.DefaultPieDataset; public class PieDemo { public static void main(String[] args) { DefaultPieDataset dataset = new DefaultPieDataset(); //添加数据 dataset.setValue("北京 ", 13); dataset.setValue("深圳 ", 6); dataset.setValue("上海 ", 2); dataset.setValue("郑州 ", 20); dataset.setValue("武汉 ", 17); dataset.setValue("天津 ", 10); JFreeChart chart = ChartFactory.createPieChart3D("用户统计报表(所属单位)",//主标题的名称 dataset, //图标显示的数据集合 true, //是否显示子标题 true, //是否生成提示的标签 true);//是否生成URL链接 //处理图形上的乱码 //处理主标题的乱码 chart.getTitle().setFont(new Font("宋体",Font.BOLD,18)); //处理子标题乱码 chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,15)); //获取图表区域对象 PiePlot3D categoryPlot = (PiePlot3D) chart.getPlot(); //处理图像上的乱码 categoryPlot.setLabelFont(new Font("宋体",Font.BOLD,15)); //设置图形的生成格式为(上海 2 (10%)) String format = "{0} {1} ({2})"; categoryPlot.setLabelGenerator(new StandardPieSectionLabelGenerator(format)); /** * 下面代码可以把生成的图片放在磁盘目录下: * 生成图片的格式:jpeg */ //begin File file = new File("D:/chart.jpeg"); try{ ChartUtilities.saveChartAsJPEG(file, chart, 800, 600); }catch(Exception e){ e.printStackTrace(); } //end //使用ChartFrame对象显示图像 ChartFrame frame = new ChartFrame("xyz",chart); frame.setVisible(true); frame.pack(); } }生成的饼图如下: