【www.bbyears.com--js教程】
1 preparation
1.1 sample introduction
JFreeChart是JAVA平台上的一个开放的图表绘制类库。I完全使用JAVA语言编写,是为applications, applets, servlets 以及JSP等使用所设计。JFreeChart可生成饼图(pie charts)、柱状图(bar charts)、散点图(scatter plots)、时序图(time series)、甘特图(Gantt charts)等等多种图表,并且可以产生PNG和JPEG格式的输出,还可以与PDF和EXCEL关联。JFreeChart截止2011年2月22日为止的相当不错的java图形解决方案,基本能够解决目前的图形方面的需求。
1.2 download
下载地址:http://sourceforge.net/project/showfiles.php?group_id=15494
说明:下载后介绍请注意以下三个:1)source目录-存放jfreechart的源码 2) lib目录-存放jar文件 3)jfreechart-1.0.14-demo.jar 例子程序
1.3 notes
开发环境:
System:xp JDK:1.5 Tomcat:5.X Myeclipse:6.5
项目环境:
web工程的目录结构如下:
没有去细分每个jar是做什么的,就把所有的jfreechart的lib目录下所有的jar都导入了工程中,本次用的jfreechart的版本是jfreechart-1.0.14)
bar是条形图存放的文件夹,line是曲线文件存放的文件夹,pie是饼图文件存放的文件夹,曲线和饼图文件在后面介绍,在本项目中,条形图我用java代码来书写,曲线图我用GUI来书写,饼图我用jsp来书写。
2 start
web.xml
这里只贴出公共部分,后面的介绍需要修改此配置文件的,我会另外的说明给出
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
org.jfree.chart.servlet.DisplayChart
下面来介绍用java文件书写的条形图(我用的是servlet实现,为了演示效果,我条形图放了四个实现不同效果条形图的方法)
2.1 在配置文件中加servlet文件的配置
2.2 BarServlet.java
代码如下 package bar;import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.ui.TextAnchor;
import org.jfree.chart.ChartUtilities;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.io.IOException;
import java.io.PrintWriter;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.axis.AxisLocation;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.plot.CategoryPlot;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
*
* Module: BarServlet.java
* Description: 条形图用java代码来书写
* Company:
* Asiainfo Author: pantaipeng
* Date: Dec 15, 2011
*/
public class BarServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
// 访问此servlet的url为:http://localhost:8080/JFreeChart/BarServlet?num=2
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
//获得回话的session对象,ServletUtilities类的saveChartAsPNG方法需要用时把session放进去
//HttpSession session = request.getSession();
/**解决servlet输出的中文乱码问题,这里的乱码和条形图中的乱码可是两种不同的乱码
* 如果使用response.getWriter()方法获得对象,则setContentType方法必须放在获得out对象之前
* 如果使用response.getOutputStream()方法获得对象,则setContentType方法放在获得out对象之前或之后都可以
* */
response.setContentType("text/html; charset=GBK");
PrintWriter out = response.getWriter();
//ServletOutputStream out = response.getOutputStream();
//response.setCharacterEncoding("GBK");
String num = request.getParameter("num");//获得请求url的参数,用来判断是显示第几个条形图示例
/*
* 为了少新建文件,也为了少配置web.xml文件,把条形图的介绍都放在一个servlet中了,
* 每个if分支都是独立的,调用四个不同的方法,实现四个不同效果的条形图,从1到4,功能依次增强
*/
String filename ="";//定义一个公共变量,保存生成的名称
if (num.equals("1")) {
out.print("第一种情况,一个简单的条形图
");
filename = bar1();
} else if (num.equals("2")) {
out.print("第二种情况,各种不同颜色的条形图
");
filename = bar2();
} else if (num.equals("3")) {
out.print("第三种情况,多个条形图对比
");
filename = bar3();
} else if (num.equals("4")) {
out.print("第四种情况,多个条形图对比并且每个条形图上面加上数字
");
filename = bar4();
} else {
out.println("输入的url不对,请输入1、2、3、4 来查看不同的条形图
");
}
String graphURL = request.getContextPath() + "/DisplayChart?filename="
+ filename;// 调用jfreechart的处理类
// 条形图的输出
//---------------start---------------
out.println("");
out.println("");
out
.println(" + graphURL
+ "" width=600 height=400 border=0 usemap="#"
+ filename + ""/>");
out.println("");
out.println("");
//---------------end---------------
out.flush();//刷新该流的缓冲
out.close();//关闭该流并释放与之关联的所有系统资源
}
//加上接受post请求的处理方法,实质也还是调用doGet方法来处理
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException {
this.doGet(request, response);
}
//条形图示例1 一个简单的条形图
public String bar1() throws IOException{
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// 设置填充数据
dataset.addValue(25, "襄阳", "襄城");
dataset.addValue(20, "襄阳", "樊城");
dataset.addValue(15, "襄阳", "襄州");
dataset.addValue(10, "襄阳", "东津");
dataset.addValue(5, "襄阳", "鱼梁州");
/**
* ChartFactory类的createBarChart3D方法参数介绍:
* createBarChart3D
* (
* String title, 图表标题
* String categoryAxisLabel, 统计种类轴标题,可以理解为X轴标题
* String valueAxisLabel,统计值轴标题,可以理解为y轴标题
* CategoryDataset dataset, 绘图数据集
* PlotOrientation orientation, 用于设置柱形图的绘制方向,PlotOrientation.VERTICAL(垂直),PlotOrientation.HORIZONTAL(水平)
* boolean legend, 用于设定是否显示图例
* boolean tooltips, 用于设定是否采用标准生成器
* boolean urls 用于设置定否包生成链接
* )
*/
JFreeChart chart = ChartFactory.createBarChart3D("襄阳城区人口统计", "地区",
"人口数(单位:万)", dataset, PlotOrientation.VERTICAL, true,
false, false);
// 设置主标题指定字体,解决中文乱码
Font font = new Font("宋体", Font.BOLD, 20);
TextTitle title = new TextTitle("襄阳城区人口统计(主标题)", font);
chart.setTitle(title);
/* 以上三句和下面的一句效果是一样的 */
// chart.setTitle(new TextTitle("襄阳城区人口统计(主标题)",new
// Font("宋体",Font.BOLD,20)));
CategoryPlot plot = chart.getCategoryPlot();
//获得横轴对象,并设置相关的绘图属性
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setAxisLineStroke(new BasicStroke(1.6f)); // 设置轴线粗细
domainAxis.setAxisLinePaint(Color.BLACK); //设置轴线颜色
domainAxis.setCategoryLabelPositionOffset(5); //设置统计种类与轴线的颜色
domainAxis.setLabelPaint(Color.BLACK); //设置坐标轴标题颜色
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.STANDARD);// 设置坐标轴标题旋转角度
/*------设置X轴坐标上的文字,解决中文乱码-----------*/
/* 本例指的是襄城、樊城、襄州、东津、鱼梁州这些字 */
domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 15));
/*------设置X轴的标题文字,解决中文乱码------------*/
/* 本例指的是"地区"两个字 */
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 15));
//获得纵轴对象,并设置相关的绘图属性
ValueAxis rangeAxis = plot.getRangeAxis();
rangeAxis.setAxisLineStroke(new BasicStroke(1.6f)); //设置轴线粗细
rangeAxis.setAxisLinePaint(Color.RED); // 设置轴线颜色
rangeAxis.setUpperBound(30.0f); // 设置坐标最大值
rangeAxis.setTickMarkStroke(new BasicStroke(1.6f)); //设置坐标标记大小
rangeAxis.setTickMarkPaint(Color.BLACK); // 设置坐标标记颜色
rangeAxis.setLabelPaint(Color.BLACK); //设置坐标轴标题颜色
rangeAxis.setLabelAngle(Math.PI / 2); //设置坐标轴标题旋转角度
rangeAxis.setLabelFont(new Font("黑体", Font.PLAIN, 15)); //设置Y轴的标题文字,解决中文乱码
rangeAxis.setUpperMargin(0.15); //设置最高一个柱与图片顶端的距离
rangeAxis.setLowerMargin(0.15); //设置最低的一个柱与图片底端的距离
//也可以通过NumberAxis的方法解决y轴中文乱码问题
/*------设置Y轴的标题文字,解决中文乱码------------*/
// 本例中指的是"销量"两个字
//NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();
//numberaxis.setLabelFont(new Font("黑体", Font.PLAIN, 15));
/*------设置Y轴坐标上的文字,解决中文乱码------------*/
/* 本例中指的是"0,25,50..."这些值,因为本来这些就是数值,所以有没有此句都可以 */
// numberaxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN,
// 15));
/*------解决底部汉字乱码的问题,如过程序没有底部,下面的一行代码如果释放的话会报空指针的错误-----------*/
chart.getLegend().setItemFont(new Font("宋体", Font.PLAIN, 15));//显示的是dataset.addValue中的值"襄阳"
/**
* ServletUtilities类的saveChartAsPNG方法参数介绍:
* saveChartAsPNG(
* JFreeChart chart, chart对象
* int width, 图片的宽度
* int height, 图片的高度
* ChartRenderingInfo info,info对象,可以为null
* HttpSession session session对象,可以为null
* )
*/
String filename = ServletUtilities
.saveChartAsPNG(chart, 600, 400, null);
/**
* 使用writeImageMap方法输出图片
ChartRenderingInfo info=new ChartRenderingInfo(new StandardEntityCollection());
ChartUtilities.writeImageMap(out, filename, info, true);
*/
return filename;
}
//条形图示例2 一个不同颜色的条形图
public String bar2() throws IOException {
double[][] data = new double[][] { {25},{ 20 }, { 15 }, { 10 },
{ 5 } };
String[] rowKeys = { "襄城", "樊城", "襄州", "东津","鱼梁州" };
String[] columnKeys = { "" };
CategoryDataset dataset = DatasetUtilities.createCategoryDataset(
rowKeys, columnKeys, data);
JFreeChart chart = ChartFactory
.createBarChart3D("襄阳城区人口统计", "地区", "人口", dataset,
PlotOrientation.VERTICAL, true, false, false);
//设置主标题指定字体,解决中文乱码
Font font = new Font("宋体", Font.BOLD, 16);
TextTitle title = new TextTitle("襄阳城区人口统计(主标题)", font);
chart.setTitle(title);
CategoryPlot plot = chart.getCategoryPlot();
NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();
CategoryAxis domainAxis = plot.getDomainAxis();
/*------设置X轴坐标上的文字-----------*/
//domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));
/*------设置X轴的标题文字------------*/
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
/*------设置Y轴坐标上的文字-----------*/
//numberaxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));
/*------设置Y轴的标题文字------------*/
numberaxis.setLabelFont(new Font("黑体", Font.PLAIN, 12));
/*------解决底部汉字乱码的问题-----------*/
chart.getLegend().setItemFont(new Font("宋体", Font.PLAIN, 12));
String filename = ServletUtilities.saveChartAsPNG(chart, 500, 300,
null);
return filename;
}
//条形图示例3 多个条形图对比
public String bar3() throws IOException {
double[][] data = new double[][] { { 1310, 1220, 1110, 1000 ,666},
{ 720, 700, 680, 640 ,777}, { 1130, 1020, 980, 800 ,888},
{ 440, 400, 360, 300 ,999} ,{400,400,400,400,555}};
String[] rowKeys = { "猪肉", "牛肉", "鸡肉", "鱼肉","羊肉" };
String[] columnKeys = { "襄城", "樊城", "襄州", "东津","鱼梁州" };
CategoryDataset dataset = DatasetUtilities.createCategoryDataset(
rowKeys, columnKeys, data);
JFreeChart chart = ChartFactory
.createBarChart3D("襄阳各区肉类销量统计图", "地区", "销量", dataset,
PlotOrientation.VERTICAL, true, false, false);
//设置主标题指定字体,解决中文乱码
Font font = new Font("宋体", Font.BOLD, 16);
TextTitle title = new TextTitle("肉类销量统计图(主标题)", font);
chart.setTitle(title);
CategoryPlot plot = chart.getCategoryPlot();
NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();
CategoryAxis domainAxis = plot.getDomainAxis();
/*------设置X轴坐标上的文字-----------*/
domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));
/*------设置X轴的标题文字------------*/
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
/*------设置Y轴坐标上的文字-----------*/
//numberaxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));
/*------设置Y轴的标题文字------------*/
numberaxis.setLabelFont(new Font("黑体", Font.PLAIN, 12));
/*------解决底部汉字乱码的问题-----------*/
chart.getLegend().setItemFont(new Font("宋体", Font.PLAIN, 12));
String filename = ServletUtilities
.saveChartAsPNG(chart, 500, 300, null);
return filename;
}
//条形图示例4 多个条形图对比并且每个条形图上面加上数字
public String bar4() throws IOException {
double[][] data = new double[][] { { 1310, 1220, 1110, 1000 ,666},
{ 720, 700, 680, 640 ,777}, { 1130, 1020, 980, 800,888 },
{ 440, 400, 360, 300 ,999} ,{400,400,400,400,555}};
String[] rowKeys = { "猪肉", "牛肉", "鸡肉", "鱼肉" ,"羊肉"};
String[] columnKeys = { "襄城", "樊城", "襄州", "东津","鱼梁州" };
CategoryDataset dataset = DatasetUtilities.createCategoryDataset(
rowKeys, columnKeys, data);
JFreeChart chart = ChartFactory.createBarChart3D("襄阳各区肉类销量统计图", "地区",
"销量", dataset, PlotOrientation.VERTICAL, true, true, false);
CategoryPlot plot = chart.getCategoryPlot();
//设置网格背景颜色
plot.setBackgroundPaint(Color.white);
//设置网络竖线颜色
plot.setDomainGridlinePaint(Color.pink);
//显示每个柱的数值,并修改该数字的字体属性
BarRenderer3D renderer = new BarRenderer3D();
renderer
.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
//默认的数字显示在柱子中,通过以下两句调整数字的显示
//注意,此句很关键,若无此句,那数字的显示会覆盖,给人数字没有显示出来的问题
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_LEFT));
renderer.setItemLabelAnchorOffset(10D);
//设置每个地区所包含的平行柱的之间的距离
//renderer.setItemMargin(0.3);
plot.setRenderer(renderer);
//设置地区、销量的显示位置
//将下方的“肉类”放到上方
plot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);
//将默认的左边的“销量”放到右方
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();
CategoryAxis domainAxis = plot.getDomainAxis();
//图表标题以及副标题乱码
Font font = new Font("宋体", Font.BOLD, 16);
TextTitle title = new TextTitle("襄阳", font);//副标题
TextTitle subtitle = new TextTitle("肉类销量统计图", new Font("黑体", Font.BOLD,
12));
chart.addSubtitle(subtitle);//子标题
chart.setTitle(title); //标题
//X轴乱码
//X轴坐标上的文字:
domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));
//X轴坐标标题(肉类)
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
//Y轴坐标上的文字
numberaxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));
//Y轴坐标标题(销量):
numberaxis.setLabelFont(new Font("黑体", Font.PLAIN, 12));
//图表底部乱码(猪肉等文字)
chart.getLegend().setItemFont(new Font("黑体", Font.PLAIN, 12));
String filename = ServletUtilities
.saveChartAsPNG(chart, 700, 400, null);
return filename;
}
}
bar1的运行截图:
访问的URL为:http://localhost:8080/JFreeChart/BarServlet?num=1
bar2的运行截图:
访问的URL为:http://localhost:8080/JFreeChart/BarServlet?num=2
bar3的运行截图:
访问的URL为:http://localhost:8080/JFreeChart/BarServlet?num=3
bar4的运行截图:
访问的URL为:http://localhost:8080/JFreeChart/BarServlet?num=4