最近公司有项目需要jfreechart出数据图,刚开始接手有点懵,后来查了一些资料,总算把活干完了,然后那总结一下,防止自己以后忘记了可以快速的捡起来。
没想到阅读量这么大,现在更新一下,百度有一个团队开发了一款更牛X的图表插件 Echarts(http://echarts.baidu.com/),各位有空可以看看~ update by wwj 2014-11-17 09:23:57
1.JFreeChart的使用 转自雷霆山崖
前提:导入需要的2个jar文件,jcommon-版本号.jar,jfreechart-版本号.jar。可以去官网下载:http://sourceforge.net/projects/jfreechart/files/
注意:下载的Jfreechart版本不要太高,新版本对中文的显示会出问题,我自己后来下的是1.0.10的版本。
实例一:比较简单的application版本的饼图
package com.test.jfreechart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;
public class JFreeChartTest
{
public static void main(String[] args)
{
DefaultPieDataset dpd=new DefaultPieDataset(); //建立一个默认的饼图
dpd.setValue("管理人员", 25); //输入数据
dpd.setValue("市场人员", 25);
dpd.setValue("开发人员", 45);
dpd.setValue("其他人员", 10);
JFreeChart chart=ChartFactory.createPieChart("某公司人员组织数据图",dpd,true,true,false);
//可以查具体的API文档,第一个参数是标题,第二个参数是一个数据集,第三个参数表示是否显示Legend,第四个参数表示是否显示提示,第五个参数表示图中是否存在URL
ChartFrame chartFrame=new ChartFrame("某公司人员组织数据图",chart);
//chart要放在Java容器组件中,ChartFrame继承自java的Jframe类。该第一个参数的数据是放在窗口左上角的,不是正中间的标题。
chartFrame.pack(); //以合适的大小展现图形
chartFrame.setVisible(true);//图形是否可见
}
}
运行结果如下:
注:一个图表由以下3个部分组成:
实例二:一个结构更加明晰的application版本的柱状图,将逻辑分装到各个函数中去。
package com.test.jfreechart;
import java.awt.Font;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;
public class JFreeChartTest2 extends ApplicationFrame
{
public JFreeChartTest2(String title)
{
super(title);
this.setContentPane(createPanel()); //构造函数中自动创建Java的panel面板
}
public static CategoryDataset createDataset() //创建柱状图数据集
{
DefaultCategoryDataset dataset=new DefaultCategoryDataset();
dataset.setValue(10,"a","管理人员");
dataset.setValue(20,"b","市场人员");
dataset.setValue(40,"c","开发人员");
dataset.setValue(15,"d","其他人员");
return dataset;
}
public static JFreeChart createChart(CategoryDataset dataset) //用数据集创建一个图表
{
JFreeChart chart=ChartFactory.createBarChart("hi", "人员分布",
"人员数量", dataset, PlotOrientation.VERTICAL, true, true, false); //创建一个JFreeChart
chart.setTitle(new TextTitle("某公司组织结构图",new Font("宋体",Font.BOLD+Font.ITALIC,20)));//可以重新设置标题,替换“hi”标题
CategoryPlot plot=(CategoryPlot)chart.getPlot();//获得图标中间部分,即plot
CategoryAxis categoryAxis=plot.getDomainAxis();//获得横坐标
categoryAxis.setLabelFont(new Font("微软雅黑",Font.BOLD,12));//设置横坐标字体
return chart;
}
public static JPanel createPanel()
{
JFreeChart chart =createChart(createDataset());
return new ChartPanel(chart); //将chart对象放入Panel面板中去,ChartPanel类已继承Jpanel
}
public static void main(String[] args)
{
JFreeChartTest2 chart=new JFreeChartTest2("某公司组织结构图");
chart.pack();//以合适的大小显示
chart.setVisible(true);
}
}
运行结果如下:
package com.test.jfreechart;
import java.awt.Font;
import java.io.FileOutputStream;
import java.io.OutputStream;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.general.DefaultPieDataset;
public class JFreeChartTest3
{
public static void main(String[] args) throws Exception
{
JFreeChart chart=ChartFactory.createPieChart("某公司人员组织数据图",getDataset(),true,true,false);
chart.setTitle(new TextTitle("某公司组织结构图",new Font("宋体",Font.BOLD+Font.ITALIC,20)));
LegendTitle legend=chart.getLegend(0);//设置Legend
legend.setItemFont(new Font("宋体",Font.BOLD,14));
PiePlot plot=(PiePlot) chart.getPlot();//设置Plot
plot.setLabelFont(new Font("隶书",Font.BOLD,16));
OutputStream os = new FileOutputStream("company.jpeg");//图片是文件格式的,故要用到FileOutputStream用来输出。
ChartUtilities.writeChartAsJPEG(os, chart, 1000, 800);
//使用一个面向application的工具类,将chart转换成JPEG格式的图片。第3个参数是宽度,第4个参数是高度。
os.close();//关闭输出流
}
private static DefaultPieDataset getDataset()
{
DefaultPieDataset dpd=new DefaultPieDataset(); //建立一个默认的饼图
dpd.setValue("管理人员", 25); //输入数据
dpd.setValue("市场人员", 25);
dpd.setValue("开发人员", 45);
dpd.setValue("其他人员", 10);
return dpd;
}
}
运行结果如下,在该项目的根目录下生成了JPEG格式的图片,注意不是在webroot目录下。
实例四:将类似实例三生成的图片嵌入到JSP页面中去。
1.web.xml中加入以下配置信息.
<servlet>
<servlet-name>DisplayChart</servlet-name>
<servlet-class>
org.jfree.chart.servlet.DisplayChart <!--这个固定不变-->
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayChart</servlet-name>
<url-pattern>/DisplayChart</url-pattern>
</servlet-mapping>
2.jfreeChart.jsp
<%@ page language="java" contentType="text/html; charset=GB18030"
pageEncoding="GB18030"%>
<%@ page import="org.jfree.data.general.DefaultPieDataset,org.jfree.chart.ChartFactory
,org.jfree.chart.JFreeChart,org.jfree.chart.servlet.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=GB18030">
<title>Insert title here</title>
</head>
<body>
<%
DefaultPieDataset dpd = new DefaultPieDataset();
dpd.setValue("管理人员", 25);
dpd.setValue("市场人员", 25);
dpd.setValue("开发人员", 45);
dpd.setValue("其他人员", 10);
JFreeChart chart = ChartFactory.createPieChart("某公司组织结构图",dpd, true, false, false);
String fileName = ServletUtilities.saveChartAsPNG(chart,800,600,session);
//ServletUtilities是面向web开发的工具类,返回一个字符串文件名,文件名自动生成,生成好的图片会自动放在服务器(tomcat)的临时文件下(temp)
String url = request.getContextPath() + "/DisplayChart?filename=" + fileName;
//根据文件名去临时目录下寻找该图片,这里的/DisplayChart路径要与配置文件里用户自定义的<url-pattern>一致
%>
<img src="<%= url %>" width="800" height="600">
</body>
</html>
显示结果为:
实例五:模拟对运动项目投票然后查看投票JFreeChart图表
原理:服务器不重启时,session结果依然保存模拟投票功能,使用struts2-jfreechart-plugin-版本号.jar插件将图表对象在action中自动渲染。
注意:不要忘记添加struts2-jfreechart-plugin-版本号.jar到工程中。
1.Action类:
package com.test.action;
import java.awt.Font;
import java.util.List;
import java.util.Map;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.title.TextTitle;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class ViewResultAction extends ActionSupport
{
private JFreeChart chart;//这里变量名必须是chart,不能是其他变量名
private List<String> interest; //struts会自动类型转换,将页面传递过来的值存到List中去
public JFreeChart getChart()//getChart()方法是必须的,setChart()可以不写.
{ //在action中的chart属性的get方法中,创建chart对象,然后进行设置plot主体和颜色;以及legend颜色和字体
chart = ChartFactory.createBarChart("兴趣统计结果", "项目", "结果", this
.getDataset(), PlotOrientation.VERTICAL, false, false, false);
chart.setTitle(new TextTitle("兴趣统计结果",new Font("黑体",Font.BOLD,22)));
CategoryPlot plot = (CategoryPlot)chart.getPlot();
CategoryAxis categoryAxis = plot.getDomainAxis();
categoryAxis.setLabelFont(new Font("宋体",Font.BOLD,22));
categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);//设置角度
NumberAxis numberAxis = (NumberAxis)plot.getRangeAxis();
numberAxis.setLabelFont(new Font("宋体",Font.BOLD,22));
return chart;
}
public List<String> getInterest()
{
return interest;
}
public void setInterest(List<String> interest)
{
this.interest = interest;
}
@Override
public String execute() throws Exception
{
return SUCCESS;
}
@SuppressWarnings("unchecked")
private void increaseResult(List<String> list)//真正在开发中是不会写在action里的,应该写在model中
{ //模拟一个临时数据库
ActionContext context = ActionContext.getContext();//struts与servlet的耦合方式一
Map map = context.getApplication();
for (String str : list)
{
if (null == map.get(str))//表示用户第一次投票
{
map.put(str, 1);
}
else
{
map.put(str, (Integer) map.get(str) + 1);
}
}
}
@SuppressWarnings("unchecked")
private CategoryDataset getDataset() //得到数据集。
{
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
this.increaseResult(this.getInterest());
ActionContext context = ActionContext.getContext();
Map map = context.getApplication();
dataset.setValue((Integer) map.get("football"), "", "足球");//更新成最新值
dataset.setValue((Integer) map.get("basketball"), "", "篮球");
dataset.setValue((Integer) map.get("volleyball"), "", "排球");
dataset.setValue((Integer) map.get("badminton"), "", "羽毛球");
return dataset;
}
}
2.Jsp页面
<%@ page language="java" import="java.util.*" pageEncoding="gbk"%>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<h1><font color="blue">请选择喜欢的运动项目</font></h1>
<s:form action="viewResult">
<s:checkbox name="interest" label="足球" fieldValue="football"></s:checkbox>
<s:checkbox name="interest" label="篮球" fieldValue="basketball"></s:checkbox>
<s:checkbox name="interest" label="排球" fieldValue="volleyball"></s:checkbox>
<s:checkbox name="interest" label="羽毛球" fieldValue="badminton"></s:checkbox>
<!--
<s:checkboxlist list="#{'computer':'计算机','math':'数学'}" name="interest" label="课程" labelposition="top"></s:checkboxlist>
-->
<s:submit value="提交"></s:submit>
</s:form>
</body>
</html>
3.struts.xml的配置
<package name="struts2" extends="struts-default,jfreechart-default">
注意:这里的包要继承2个。网上常用的方法是将struts2-jfreechart-plugin-版本号.jar插件解压,然后修改struts-plugin-xml中package,让它继承于struts-default包然后重新打包,再配置action中的package包,使其extends= jfreechart-default,感觉这种做法比较麻烦。还是直接继承2个包比较方便。
<action name="viewResult" class="com.test.action.ViewResultAction">
<result name="success" type="chart">
<param name="height">600</param>
<param name="width">800</param>
</result>
</action>
这里<result/>标签中不需要再加入JSP页面用来跳转,会直接跳转到由chart所指定的ChartResult类来处理。
附struts-plugin-xml文件内容:
<struts>
<package name="jfreechart-default">
<result-types>
<result-type name="chart" class="org.apache.struts2.dispatcher.ChartResult">
<param name="height">150</param>
<param name="width">200</param>
</result-type>
</result-types>
</package>
</struts>
最后页面显示结果:
2.linux解决jfreechart中文乱码问题
做项目中用到了jfreechart用来显示统计课程排行的结果,但是在xp下显示正常,但是在linux下显
示中文乱码 类似 口口口之类的
在网上搜了些,一开始由于对linux不太熟悉,也就没有解决问题,现在学习了一段fedora后,重新
解决了这个问题
首先 将xp下的 simsun.ttc字体拷贝到 linux下,放在 linux的 %JAVA_HOME%/jre/lib/fonts目录下
然后修改目录下的 fonts.dir文件 将首行的数字 +1 比如 122变为123 ,然后在最后一行加上:
simsun.ttc -SungtiL GB-medium-r-normal--0-0-0-0-c-0-gb2312.1988-0
然后保存 ,如果是只读文件 的话 要强制保存 :w!
最后 在 含有 jfreechat的程序中 设置如下:
CategoryPlot plot = this.chart.getCategoryPlot()
plot.setForegroundAlpha(0.6F);
chart.setTitle(new TextTitle(chart.getTitle().getText(),new Font("宋体", 1, 13)));
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setLabelFont(new Font("宋体", 1, 12));
domainAxis.setTickLabelFont(new Font("宋体", 0, 10));
NumberAxis numberaxis = (NumberAxis)plot.getRangeAxis();
numberaxis.setTickLabelFont(new Font("宋体", 0, 12));
numberaxis.setLabelFont(new Font("宋体", 0, 12));
domainAxis.setLowerMargin(0.01D);
domainAxis.setUpperMargin(0.01D);
3.JFreeChart生成折线图(生成图片本地保存,有解决中文乱码的通用方法)
import java.awt.Color;
import java.awt.Font;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.RectangleInsets;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.labels.*;
import org.jfree.ui.*;
/**
* 创建JFreeChart Line Chart(折线图)
*/
public class CopyOfCreateJFreeChartLine {
public static void main(String[] args) {
// 步骤1:创建CategoryDataset对象(准备数据)
TimeSeriesCollection dataset = createDataset();
// 步骤2:根据Dataset 生成JFreeChart对象,以及做相应的设置
JFreeChart freeChart = createChart(dataset);
// 步骤3:将JFreeChart对象输出到文件,Servlet输出流等
saveAsFile(freeChart, "c://jfreechart//testline.png", 500, 300);
}
// 创建TimeSeriesCollection对象
public static TimeSeriesCollection createDataset() {
TimeSeriesCollection lineDataset = new TimeSeriesCollection();
TimeSeries timeSeries = new TimeSeries("统计", Month.class);
timeSeries.add(new Month(1, 2007), 11200);
timeSeries.add(new Month(2, 2007), 9000);
timeSeries.add(new Month(3, 2007), 6200);
timeSeries.add(new Month(4, 2007), 8200);
timeSeries.add(new Month(5, 2007), 8200);
timeSeries.add(new Month(6, 2007), 12200);
timeSeries.add(new Month(7, 2007), 13200);
timeSeries.add(new Month(8, 2007), 8300);
timeSeries.add(new Month(9, 2007), 12400);
timeSeries.add(new Month(10, 2007), 12500);
timeSeries.add(new Month(11, 2007), 13600);
timeSeries.add(new Month(12, 2007), 12500);
lineDataset.addSeries(timeSeries);
return lineDataset;
}
// 根据CategoryDataset生成JFreeChart对象
public static JFreeChart createChart(TimeSeriesCollection lineDataset) {
JFreeChart jfreechart = ChartFactory.createTimeSeriesChart(
"统计", // 标题
"月份", // categoryAxisLabel (category
轴,横轴,X轴的标签)
"访问量", // valueAxisLabel(value轴,纵轴,Y轴的
标签)
lineDataset,// dataset
true, // legend
true, // tooltips
true); // URLs
// 配置字体(解决中文乱码的通用方法)
Font xfont = new Font("宋体", Font.PLAIN, 16); // X轴
Font yfont = new Font("宋体", Font.PLAIN, 16); // Y轴
Font kfont = new Font("宋体", Font.PLAIN, 14); // 底部
Font titleFont = new Font("隶书", Font.BOLD, 20); // 图片标题
jfreechart.setBackgroundPaint(Color.white);
XYPlot xyplot = (XYPlot) jfreechart.getPlot(); // 获得 plot:XYPlot!
xyplot.getDomainAxis().setLabelFont(xfont);
xyplot.getRangeAxis().setLabelFont(yfont);
jfreechart.getLegend().setItemFont(kfont);
jfreechart.getTitle().setFont(titleFont);
//设置时间格式,同时也解决了乱码问题
DateAxis dateaxis = (DateAxis)xyplot.getDomainAxis();
SimpleDateFormat sfd = new SimpleDateFormat("yy-MM");
dateaxis.setDateFormatOverride(sfd);
xyplot.setDomainAxis(dateaxis);
// 以下的设置可以由用户定制,也可以省略
XYPlot plot = (XYPlot) jfreechart.getPlot();
XYLineAndShapeRenderer xylineandshaperenderer = (XYLineAndShapeRenderer)
plot.getRenderer();
// 设置网格背景颜色
plot.setBackgroundPaint(Color.white);
// 设置网格竖线颜色
plot.setDomainGridlinePaint(Color.pink);
// 设置网格横线颜色
plot.setRangeGridlinePaint(Color.pink);
// 设置曲线图与xy轴的距离
plot.setAxisOffset(new RectangleInsets(0D, 0D, 0D, 10D));
// 设置曲线是否显示数据点
xylineandshaperenderer.setBaseShapesVisible(true);
// 设置曲线显示各数据点的值
XYItemRenderer xyitem = plot.getRenderer();
xyitem.setBaseItemLabelsVisible(true);
xyitem.setBasePositiveItemLabelPosition(new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_LEFT));
xyitem.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator());
xyitem.setBaseItemLabelFont(new Font("Dialog", 1, 14));
plot.setRenderer(xyitem);
return jfreechart;
}
// 保存为文件
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, 600, 350);
// 保存为JPEG文件
//ChartUtilities.writeChartAsJPEG(out, chart, 500, 400);
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.JFreeChart3d柱形图 关于负值不显示问题的解决总结
JFreeChart生成柱状图时,当数值为负的不能显示在顶端
解决要点:
renderer.setNegativeItemLabelPosition(new ItemLabelPosition(
ItemLabelAnchor.INSIDE12,TextAnchor.CENTER_RIGHT,
TextAnchor.CENTER_RIGHT,-1.57D));
引用解答者的原文
<%@ page contentType="text/html;charset=GBK"%>
<%@ page import="java.awt.Color,
org.jfree.chart.ChartFactory,
org.jfree.chart.JFreeChart,
org.jfree.chart.plot.PlotOrientation,
org.jfree.chart.servlet.ServletUtilities,
org.jfree.data.category.CategoryDataset,
org.jfree.data.general.*,
org.jfree.chart.plot.CategoryPlot,
org.jfree.chart.axis.CategoryAxis,
org.jfree.chart.axis.ValueAxis,
org.jfree.chart.renderer.category.BarRenderer3D,
org.jfree.chart.urls.StandardCategoryURLGenerator,
org.jfree.chart.*,
org.jfree.chart.entity.*,
org.jfree.chart.labels.*,
org.jfree.chart.axis.CategoryLabelPositions,
java.awt.Font,
java.awt.GradientPaint,
org.jfree.ui.TextAnchor,
org.jfree.chart.axis.NumberAxis,
org.jfree.chart.axis.NumberTickUnit
"%>
<%
java.io.PrintWriter pw=new java.io.PrintWriter(out);
double[][] data = new double[][] {{500}, {200}, {100}, {400}, {600}, {300}};
String[] rowKeys = {"苹果", "梨子", "葡萄", "桔子", "西瓜", "香蕉"};
String[] columnKeys = {""};
CategoryDataset dataset = DatasetUtilities.createCategoryDataset(
rowKeys,
columnKeys,
data);
JFreeChart chart = ChartFactory.createBarChart3D("水果销量图统计",
"水果", //横坐标名称
"销量", //纵坐标名称
dataset,//数据集合
PlotOrientation.VERTICAL,//图形位置,水平还是垂直
true,
false,
false);
chart.setBackgroundPaint(Color.WHITE);
//设定背景色为白色
CategoryPlot categoryPlot = chart.getCategoryPlot();
//获得 plot:3dBar为CategoryPlot
categoryPlot.setBackgroundPaint(Color.lightGray);
//设定图表数据显示部分背景色
categoryPlot.setDomainGridlinePaint(Color.white);
//横坐标网格线白色
categoryPlot.setDomainGridlinesVisible(true);
//设置网格线可见
categoryPlot.setRangeGridlinePaint(Color.white);
//纵坐标网格线白色
//获取横坐标
CategoryAxis domainAxis = categoryPlot.getDomainAxis();
//设置 横坐标 垂直显示
//domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(0.4));
//获取纵坐标
NumberAxis numberaxis = (NumberAxis)categoryPlot.getRangeAxis();
//将纵坐标间距设置为50
numberaxis.setTickUnit(new NumberTickUnit(50));
//设置横坐标的标题字体和大小,此处是“宋体13号”
domainAxis.setLabelFont(new Font("宋体",Font.PLAIN,13));
//设置距离图片左端距离,参数为图片的百分比
domainAxis.setLowerMargin(0.05);
//设置距离图片右端距离
domainAxis.setUpperMargin(0.05);
//设置横坐标的坐标值的字体
domainAxis.setTickLabelFont(new Font("宋体",Font.PLAIN,12));
//使横坐标设置生效
categoryPlot.setDomainAxis(domainAxis);
ValueAxis rangeAxis = categoryPlot.getRangeAxis();
//设置最高的一个柱与图片顶端的距离
rangeAxis.setUpperMargin(0.05);
//设置最低的一个柱与图片底端的距离
rangeAxis.setLowerMargin(0.05);
categoryPlot.setRangeAxis(rangeAxis);
//设置竖坐标标签的旋转角度
rangeAxis.setLabelAngle(0.05);
//重要的类,负责生成各种效果
BarRenderer3D renderer=(BarRenderer3D) categoryPlot.getRenderer();
//设置 Wall 的颜色
renderer.setWallPaint(Color.PINK);
//设置每个柱的颜色
GradientPaint gradientpaint = new GradientPaint(0.0F, 0.0F, Color.blue,
0.0F, 0.0F, new Color(0, 0, 64)); //设定特定颜色
GradientPaint gradientpaint1 = new GradientPaint(0.0F, 0.0F, Color.green,
0.0F, 0.0F, new Color(0, 64, 0));
renderer.setSeriesPaint(0, gradientpaint);
renderer.setSeriesPaint(1, gradientpaint1);
//设置柱的 Outline 颜色
renderer.setSeriesOutlinePaint(0, Color.BLACK);
renderer.setSeriesOutlinePaint(1, Color.BLACK);
//设置每个category所包含的平行柱的之间距离
renderer.setItemMargin(0.1);
//显示每个柱的数值,并修改该数值的字体属性
renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
//以下设置,将按照指定格式,制定内容显示每个柱的数值。可以显示柱名称,所占百分比
//renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}",new DecimalFormat("0.0%")));
//设置柱子上数值的字体
renderer.setItemLabelFont(new Font("宋体",Font.PLAIN,13));
renderer.setItemLabelsVisible(true);
//设置柱子上数据的颜色
renderer.setItemLabelPaint(Color.RED);
//设置bar的最小宽度,以保证能显示数值
renderer.setMinimumBarLength(0.02);
//最大宽度
//renderer.setMaximumBarWidth(0.07);
//设置柱子上比例数值的显示,如果按照默认方式显示,数值为方向正常显示
//设置柱子上显示的数据旋转90度,最后一个参数为旋转的角度值/3.14
ItemLabelPosition itemLabelPosition= new ItemLabelPosition(
ItemLabelAnchor.INSIDE12,TextAnchor.CENTER_RIGHT,
TextAnchor.CENTER_RIGHT,-1.57D);
//下面的设置是为了解决,当柱子的比例过小,而导致表示该柱子比例的数值无法显示的问题
//设置不能在柱子上正常显示的那些数值的显示方式,将这些数值显示在柱子外面
ItemLabelPosition itemLabelPositionFallback=new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE12,TextAnchor.BASELINE_LEFT,
TextAnchor.HALF_ASCENT_LEFT,-1.57D);
//设置正常显示的柱子label的position
renderer.setPositiveItemLabelPosition(itemLabelPosition);
renderer.setNegativeItemLabelPosition(itemLabelPosition);
//设置不能正常显示的柱子label的position
renderer.setPositiveItemLabelPositionFallback(itemLabelPositionFallback);
renderer.setNegativeItemLabelPositionFallback(itemLabelPositionFallback);
categoryPlot.setRenderer(renderer);
//设置柱子的透明度
categoryPlot.setForegroundAlpha(0.8f);
//为柱图设置“数据挖陷”
//第一个参数是跳转的连接地址
renderer.setBaseItemURLGenerator(new StandardCategoryURLGenerator(
"detail.jsp", "fruit", ""));
//使设置生效
renderer.setBaseItemLabelsVisible(true);
//设置柱的透明度
categoryPlot.setForegroundAlpha(0.5f);
//设置地区、销量的显示位置
//plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
ChartRenderingInfo info = new ChartRenderingInfo(new StandardEntityCollection());
//生成图形的名称
//可以改变ServletUtilities源代码,设置图形统一前缀名称和默认存放路径
//注意:图形的大小往往都是通过配置文件设置的,不可能所有图形一个大小
String filename = ServletUtilities.saveChartAsPNG(chart, 800, 600, info, session);
//调用DisplayChart(配置在webxml中),生成图形
String graphURL = request.getContextPath() + "/DisplayChart?filename=" + filename;
//将MAP信息,写入图形
ChartUtilities.writeImageMap(pw, filename, info, true);
pw.flush();
%>
<table width="100%">
<tr>
<td align="center">
<!-- 生成图形 -->
<img src="<%= graphURL %>" width=800 height=600 border=0 usemap="#<%= filename %>" alt="">
</td>
</tr>
</table>
解释的很详细,关键地方还有文字,备注,下面我附上我最后的负值解决的两个图片
上面很明显,负值由于有负号所以显示不开,只好旋转90度(0D--> -1.57D)
5.Jfreechart柱形图详细设置!
一. 下载与环境配置
此最新版本为 1.0.13
解压jfreechart-1.0.13.zip 将lib目录下的jfreechart-1.0.13.jar 、jcommon-1.0.16.jar 复制到工程 WEB-INF/lib 文件夹中
二. 配置
我是用Struts1.2开发的。
在工程的web.xml 文件中添加
<servlet>
<servlet-name>DisplayChart</servlet-name>
<servlet-class>org.jfree.chart.servlet.DisplayChart</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayChart</servlet-name>
<url-pattern>/DisplayChart</url-pattern>
</servlet-mapping>
三. 生成柱形图
新建个Action 最好是继承DispatchAction
public ActionForward toBarPic(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) {
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
//添加数据
dataset.addValue(440, "数据", "类型1");
dataset.addValue(360, "数据", "类型2");
dataset.addValue(510, "数据", "类型3");
dataset.addValue(390, "数据", "类型4");
//
JFreeChart chart = ChartFactory.createBarChart3D("XXX统计图", "类型","数据额", dataset, PlotOrientation.VERTICAL, true, false, false);
HttpSession session=request.getSession();
String filename="";
try{
//生成宽600,高420 png格式的图,并将图片保存到session中,好像只能保存到session中,要不就设置为null
filename = ServletUtilities.saveChartAsPNG(chart,600,420, null, session);
}catch(Exception ex){
ex.printStackTrace();
}
String graphURL = request.getContextPath() + "/DisplayChart?filename=" + filename;
request.setAttribute("graphURL", graphURL);
request.setAttribute("filename", filename);
return mapping.findForward("success");
}
页面中 图片链接方式
<img src="${graphURL}" width=630 height=450 border=0 usemap="#${filename}">
生成的图如下:

可见生成柱形图很简单,只需要以下几步
1、 DefaultCategoryDataset dataset = new DefaultCategoryDataset();
2、 dataset.addValue(440, "数据", "类型1"); //封数据
3、 JFreeChart chart = ChartFactory.createBarChart3D("XXX统计图", "类型","数据额", dataset, PlotOrientation.VERTICAL, true, false, false);
4、 String filename = ServletUtilities.saveChartAsPNG(chart,600,420, null, session);//返回图片名称
//为图片生成url访问地址
5、 String graphURL = request.getContextPath() + "/DisplayChart?filename=" + filename;
6、 将 图片名称filename 和图片地址 graphURL 保存到作用域中,最后返回。
以上是生成柱形图最基本的步骤,但是生成的图往往是不合人意的,因为太粗糙了,好比刚盖好的房子还没有装修,下面就对图形进行美化,装修这个柱形房子。
要设置图片高级属性先获得 CategoryPlot 和 BarRenderer3D 大部分修改都是在这上面
CategoryPlot plot = chart.getCategoryPlot();//设置图的高级属性
BarRenderer3D renderer = new BarRenderer3D();//3D属性修改
最后还得将renderer 放到plot 中
plot.setRenderer(renderer);//将修改后的属性值保存到图中
在JFreeChart chart = ChartFactory.createBarChart3D()下面添加
CategoryPlot plot = chart.getCategoryPlot();//设置图的高级属性
BarRenderer3D renderer = new BarRenderer3D();//3D属性修改
plot.setRenderer(renderer);//将修改后的属性值保存到图中
然后做的修改都是在
BarRenderer3D renderer = new BarRenderer3D();//3D属性修改
plot.setRenderer(renderer);//将修改后的属性值保存到图中
这两行中间,也就是以下添加的任何代码都是在上面这两行中间添加。
首先修改颜色
//设置网格竖线颜色
plot.setDomainGridlinePaint(Color.blue);
plot.setDomainGridlinesVisible(true);
//设置网格横线颜色
plot.setRangeGridlinePaint(Color.blue);
plot.setRangeGridlinesVisible(true);
//图片背景色
plot.setBackgroundPaint(Color.LIGHT_GRAY);
plot.setOutlineVisible(true);
//图边框颜色
plot.setOutlinePaint(Color.magenta);
//边框颜色
renderer.setBaseOutlinePaint(Color.ORANGE);
renderer.setDrawBarOutline(true);
//设置墙体颜色
renderer.setWallPaint(Color.gray);
效果图如下

接下来修改字体,看上图还是乱码,下面就对字体做调整
//对X轴做操作
CategoryAxis domainAxis = plot.getDomainAxis();
//对Y轴做操作
ValueAxis rAxis = plot.getRangeAxis();
/*----------设置消除字体的锯齿渲染(解决中文问题)--------------*/
chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
//设置标题字体
TextTitle textTitle = chart.getTitle();
textTitle.setFont(new Font("黑体", Font.PLAIN, 20));
//设置X轴坐标上的文字
domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));
//设置X轴的标题文字
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
//设置Y轴坐标上的文字
rAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));
//设置Y轴的标题文字
rAxis.setLabelFont(new Font("黑体", Font.PLAIN, 12));
//底部汉字乱码的问题
chart.getLegend().setItemFont(new Font("宋体",Font.PLAIN,12));
效果图如下

在上面基础上在做一下高级设计,设计字体颜色和节段
//对X轴做操作
CategoryAxis domainAxis = plot.getDomainAxis();
//对Y轴做操作
ValueAxis rAxis = plot.getRangeAxis();
/*--------设置消除字体的锯齿渲染(解决中文问题)---------*/
chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
//设置标题字体
TextTitle textTitle = chart.getTitle();
textTitle.setFont(new Font("黑体", Font.PLAIN, 20));
textTitle.setBackgroundPaint(Color.LIGHT_GRAY);//标题背景色
textTitle.setPaint(Color.cyan);//标题字体颜色
textTitle.setText("类型统计图");//标题内容
//设置X轴坐标上的文字
domainAxis.setTickLabelFont(new Font("宋体", Font.PLAIN, 11));
//设置X轴的标题文字
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
domainAxis.setTickLabelPaint(Color.red);//X轴的标题文字颜色
domainAxis.setTickLabelsVisible(true);//X轴的标题文字是否显示
domainAxis.setAxisLinePaint(Color.red);//X轴横线颜色
domainAxis.setTickMarksVisible(true);//标记线是否显示
domainAxis.setTickMarkOutsideLength(3);//标记线向外长度
domainAxis.setTickMarkInsideLength(3);//标记线向内长度
domainAxis.setTickMarkPaint(Color.red);//标记线颜色
/** Y轴设计同X轴相类似 **/
//设置Y轴坐标上的文字
rAxis.setTickLabelFont(new Font("宋体", Font.PLAIN, 12));
rAxis.setMinorTickCount(7);//显示有多少标记段
rAxis.setMinorTickMarksVisible(true);
rAxis.setRange(100, 600); //Y轴取值范围(或者如下设置)
// rAxis.setLowerBound(100); //Y轴以开始的最小值
// rAxis.setUpperBound(600);Y轴的最大值
//设置Y轴的标题文字
rAxis.setLabelFont(new Font("黑体", Font.PLAIN, 12));
//底部汉字乱码的问题
chart.getLegend().setItemFont(new Font("宋体",Font.PLAIN,12));

大多数情况下都需要在柱子上显示对应的数值,设置如下:
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
renderer.setBaseItemLabelPaint(Color.BLUE);//设置数值颜色,默认黑色
用下面设置也能达到同样效果
renderer.setItemLabelGenerator( new StandardCategoryItemLabelGenerator());
renderer.setItemLabelsVisible( true );
renderer.setItemLabelPaint(Color.BLUE);
效果图如下:

默认的数值如上图所示,但是大多数情况下我们要应对不同的需求对数值显示的位置等进行调整。具体调整如下:
//搭配ItemLabelAnchor TextAnchor 这两项能达到不同的效果,但是
ItemLabelAnchor最好选OUTSIDE,因为INSIDE显示不出来
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.CENTER_LEFT));
//下面可以进一步调整数值的位置,但是得根据ItemLabelAnchor选择情况,例
如我选的是OUTSIDE12,那么下面设置为正数时,数值就会向上调整,负数则向下
renderer.setItemLabelAnchorOffset(10);
效果图如图六:

有时候柱子过多,而且图大小有限,就得将柱子类型倾斜显示,或者将其放到上面等。看如下配置:
//将类型放到上面
plot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);
//横轴上的 Lable 45度倾斜
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
//将默认放到左边的数值放到右边
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
效果图如下:

看上面的柱子太粗,实在不好看,下面就是调整柱子的宽度和透明度等:
//设置距离图片左端距离
domainAxis.setUpperMargin(0.2);
//设置距离图片右端距离
domainAxis.setLowerMargin(0.2);
//数据轴精度
NumberAxis na = (NumberAxis) plot.getRangeAxis();
na.setAutoRangeIncludesZero(true);
DecimalFormat df = new DecimalFormat("#0.000");
//数据轴数据标签的显示格式
na.setNumberFormatOverride(df);
//设置柱的透明度
plot.setForegroundAlpha(1.0f);

详细设置如下:
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
//添加数据
dataset.addValue(440, "数据", "类型1");
dataset.addValue(360, "数据", "类型2");
dataset.addValue(510, "数据", "类型3");
dataset.addValue(390, "数据", "类型4");
/**参数分别为:图表标题 ,目录轴的显示标签 ,数值轴的显示标签 ,数据集 ,是否生成URL链接
图表方向:水平、垂直, 是否显示图例(对于简单的柱状图必须是false) ,是否生成工具 */
JFreeChart chart = ChartFactory.createBarChart3D("XXX统计图", "类型","数据额", dataset, PlotOrientation.VERTICAL, true, false, true);
/*----------设置消除字体的锯齿渲染(解决中文问题)--------------*/
chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
//底部汉字乱码的问题
chart.getLegend().setItemFont(new Font("宋体",Font.PLAIN,12));
//设置标题字体
TextTitle textTitle = chart.getTitle();
textTitle.setFont(new Font("黑体", Font.PLAIN, 20));
textTitle.setBackgroundPaint(Color.LIGHT_GRAY);//标题背景色
textTitle.setPaint(Color.cyan);//标题字体颜色
textTitle.setText("类型统计图");//标题内容
CategoryPlot plot = chart.getCategoryPlot();//设置图的高级属性
BarRenderer3D renderer = new BarRenderer3D();//3D属性修改
CategoryAxis domainAxis = plot.getDomainAxis();//对X轴做操作
ValueAxis rAxis = plot.getRangeAxis();//对Y轴做操作
/***
* domainAxis设置(x轴一些设置)
**/
//设置X轴坐标上的文字
domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 11));
//设置X轴的标题文字
domainAxis.setLabelFont(new Font("宋体", Font.PLAIN, 12));
domainAxis.setLabel("");//X轴的标题内容
domainAxis.setTickLabelPaint(Color.red);//X轴的标题文字颜色
domainAxis.setTickLabelsVisible(true);//X轴的标题文字是否显示
domainAxis.setAxisLinePaint(Color.red);//X轴横线颜色
domainAxis.setTickMarksVisible(true);//标记线是否显示
domainAxis.setTickMarkOutsideLength(3);//标记线向外长度
domainAxis.setTickMarkInsideLength(3);//标记线向内长度
domainAxis.setTickMarkPaint(Color.red);//标记线颜色
domainAxis.setUpperMargin(0.2);//设置距离图片左端距离
domainAxis.setLowerMargin(0.2); //设置距离图片右端距离
//横轴上的 Lable 是否完整显示
domainAxis.setMaximumCategoryLabelWidthRatio(0.6f);
//横轴上的 Lable 45度倾斜
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_45);
/**
* rAxis设置 Y轴设置
*
**/
//设置Y轴坐标上的文字
rAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));
//设置Y轴的标题文字
rAxis.setLabelFont(new Font("黑体", Font.PLAIN, 12));
//Y轴取值范围(下面不能出现 rAxis.setAutoRange(true) 否则不起作用)
rAxis.setRange(100, 600);
// rAxis.setLowerBound(100); //Y轴以开始的最小值
// rAxis.setUpperBound(600);//Y轴的最大值
rAxis.setLabel("content");//Y轴内容
rAxis.setLabelAngle(1.6);//标题内容显示角度(1.6时候水平)
rAxis.setLabelPaint(Color.red);//标题内容颜色
rAxis.setMinorTickMarksVisible(true);//标记线是否显示
rAxis.setMinorTickCount(7);//节段中的刻度数
rAxis.setMinorTickMarkInsideLength(3);//内刻度线向内长度
rAxis.setMinorTickMarkOutsideLength(3);//内刻度记线向外长度
rAxis.setTickMarkInsideLength(3);//外刻度线向内长度
rAxis.setTickMarkPaint(Color.red);//刻度线颜色
rAxis.setTickLabelsVisible(true);//刻度数值是否显示
// 所有Y标记线是否显示(如果前面设置rAxis.setMinorTickMarksVisible(true); 则其照样显示)
rAxis.setTickMarksVisible(true);
rAxis.setAxisLinePaint(Color.red);//Y轴竖线颜色
rAxis.setAxisLineVisible(true);//Y轴竖线是否显示
//设置最高的一个 Item 与图片顶端的距离 (在设置rAxis.setRange(100, 600);情况下不起作用)
rAxis.setUpperMargin(0.15);
//设置最低的一个 Item 与图片底端的距离
rAxis.setLowerMargin(0.15);
rAxis.setAutoRange(true);//是否自动适应范围
rAxis.setVisible(true);//Y轴内容是否显示
//数据轴精度
NumberAxis na = (NumberAxis) plot.getRangeAxis();
na.setAutoRangeIncludesZero(true);
DecimalFormat df = new DecimalFormat("#0.000");
//数据轴数据标签的显示格式
na.setNumberFormatOverride(df);
/**
* renderer设置 柱子相关属性设置
*/renderer.setBaseOutlinePaint(Color.ORANGE); //边框颜色
renderer.setDrawBarOutline(true);
renderer.setWallPaint(Color.gray);//设置墙体颜色
renderer.setMaximumBarWidth(0.08); //设置柱子宽度
renderer.setMinimumBarLength(0.1); //设置柱子高度
renderer.setSeriesPaint(0,Color.ORANGE); //设置柱的颜色
renderer.setItemMargin(0); //设置每个地区所包含的平行柱的之间距离
//在柱子上显示相应信息
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
renderer.setBaseItemLabelPaint(Color.BLACK);//设置数值颜色,默认黑色
//搭配ItemLabelAnchor TextAnchor 这两项能达到不同的效果,但是ItemLabelAnchor最好选OUTSIDE,因为INSIDE显示不出来
renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.CENTER_LEFT));
//下面可以进一步调整数值的位置,但是得根据ItemLabelAnchor选择情况.
renderer.setItemLabelAnchorOffset(10);
/**
* plot 设置
***/
//设置网格竖线颜色
plot.setDomainGridlinePaint(Color.blue);
plot.setDomainGridlinesVisible(true);
//设置网格横线颜色
plot.setRangeGridlinePaint(Color.blue);
plot.setRangeGridlinesVisible(true);
//图片背景色
plot.setBackgroundPaint(Color.LIGHT_GRAY);
plot.setOutlineVisible(true);
//图边框颜色
plot.setOutlinePaint(Color.magenta);
//设置柱的透明度
plot.setForegroundAlpha(1.0f);
//将类型放到上面
plot.setDomainAxisLocation(AxisLocation.TOP_OR_RIGHT);
//将默认放到左边的数值放到右边
plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
plot.setRenderer(renderer);//将修改后的属性值保存到图中
HttpSession session=request.getSession();
String filename="";
try{
//生成宽600,高420 png格式的图,并将图片保存到session中,好像只能保存到session中,要不就设置为null
filename = ServletUtilities.saveChartAsPNG(chart,600,420, null, session);
}catch(Exception ex){
ex.printStackTrace();
}
String graphURL = request.getContextPath() + "/DisplayChart?filename=" + filename;
request.setAttribute("graphURL", graphURL);
request.setAttribute("filename", filename);