Jfreechart 与 Spring的结合

本文介绍如何通过Spring MVC框架和JFreeChart组件在Java Web应用中生成动态图表,包括饼图和折线图,并详细展示了配置过程及图表生成的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.在manage-servlet.xml中的配置

<!-- Jfreechart -->
<bean id="simpleUrlController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController" />
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >
<property name="defaultHandler" value="simpleUrlController"/>
<property name="mappings">
<map>
<entry key="/jfreechart.do"><ref local="graphController"/></entry>
<entry key="/jfreechart/list.do"><ref local="list_jfreechart"/></entry>
</map>
</property>
<property name="alwaysUseFullPath">
<value>true</value>
</property>
</bean>

<bean id="graphController" class="com.lenovomobile.wap.web.jfreechart.GraphController">
<property name="manage" ref="manage"/>
</bean>


2.在response中直接生成图片PNG

package com.lenovomobile.wap.web.jfreechart;

import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.Day;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.XYItemLabelGenerator;
import org.jfree.chart.labels.StandardXYItemLabelGenerator;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.ui.RectangleInsets;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.lenovomobile.wap.domain.logic.ManageFacade;
import com.lenovomobile.wap.web.report.Helper;
import com.lenovomobile.wap.report.domain.ReportByDay;

import java.awt.*;
import java.io.FileOutputStream;
import java.io.File;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.text.SimpleDateFormat;

/**
* Created by IntelliJ IDEA.
* User: wangqiaowqo
* Date: 2009-6-8
* Time: 16:20:33
* 该类的用途:利用jfreechart技术生成报表.
*/
public class GraphController implements Controller {

private ManageFacade manage;

public void setManage(ManageFacade manage) {
this.manage = manage;
}

public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception {

/* response.setContentType("image/png");
DefaultPieDataset pieDataset = new DefaultPieDataset();
pieDataset.setValue("Nokia", new Integer(60));
pieDataset.setValue("Samsung", new Integer(20));
pieDataset.setValue("Sony Ericsson", new Integer(10));
pieDataset.setValue("LG", new Integer(10));
JFreeChart chart= ChartFactory.createPieChart("手机设备饼图",pieDataset,true,true,true);
chart.getTitle().setFont(new Font("宋体", Font.BOLD,12)); //显示中文
ChartUtilities.writeChartAsPNG(response.getOutputStream(), chart, 400, 400);
response.getOutputStream().close();*/
/*
double[][] data = new double[][]{
{672, 766, 223, 540, 126},
{325, 521, 210, 340, 106},
{332, 256, 523, 240, 526}
};
String[] rowKeys = {"苹果", "梨子", "葡萄"};
String[] columnKeys = {"北京", "上海", "广州", "成都", "深圳"};
*/


response.setCharacterEncoding("utf-8");
String date = request.getParameter("date");
String year = request.getParameter("year");
SimpleDateFormat ymd = new SimpleDateFormat("yyyyMMdd");
SimpleDateFormat ym = new SimpleDateFormat("yyyy");

String start = null;
String end = null;

Date today = parse(date);
Calendar yesterday = Calendar.getInstance();
yesterday.setTime(today);
yesterday.add(Calendar.DATE, -1);
Date yesterDay = yesterday.getTime();
end = ymd.format(yesterDay);

yesterday.set(Calendar.DAY_OF_YEAR, 1);
start= ymd.format(yesterday.getTime());

//year不为空时,取得start与end
String yearlastDay = null;
if (year != null && !"".equals(year) && compareYear(start, year)) {
//当前月的第一天
start= year + "0101";

//取得下个年的第一天
Date day = parse(start);
Calendar endDay = Calendar.getInstance();
endDay.setTime(day);
endDay.add(Calendar.YEAR, 1);
endDay.set(Calendar.DAY_OF_YEAR,1);
end = ymd.format(endDay.getTime());
endDay.add(Calendar.DATE, -1);
yearlastDay = ymd.format(endDay.getTime());
}

//判断时间点是否超出头尾范围
//范围:20061112-至今
Date temp1 = Helper.parse(start);
Date temp2 = Helper.parse("20061112");
int t = temp2.compareTo(temp1);
if ( t > 0){
start = "20061112";
}

if (compareEndYear("20061231", end)){
end = "20070101";
yearlastDay = "20061231";
}

Date endDay = parse(yearlastDay);
Calendar cal = Calendar.getInstance();
cal.setTime(endDay);

Calendar next = (Calendar) cal.clone();
Calendar prior = (Calendar) cal.clone();

next.add(Calendar.YEAR, 1);
prior.add(Calendar.YEAR, -1);

// 如何处理跨年份的情况

List lists = this.manage.getReportDay(start, end,
String.valueOf(cal.get(Calendar.YEAR)));

XYDataset dataset = createDataset(lists);
createTimeXYChar("折线图", start + "-" + end, "number", dataset, "lineAndShap.png", response);

return null;
}

private XYDataset createDataset(List list) {

TimeSeries s1 = new TimeSeries("page visit number");
TimeSeries s2 = new TimeSeries("visitor number");

for(int i=0;i<list.size(); i ++){
ReportByDay r = (ReportByDay) list.get(i);
try{
s1.add(new Day(parse(r.getDate())), r.getView());
s2.add(new Day(parse(r.getDate())), r.getVisit());
} catch(Exception e){
e.printStackTrace();
s1.update(new Day(parse(r.getDate())), r.getView());
s2.update(new Day(parse(r.getDate())), r.getVisit());
}
}

TimeSeriesCollection dataset = new TimeSeriesCollection();
//dataset.addSeries(s1);
dataset.addSeries(s2);

return dataset;

}

// 柱状图,折线图 数据集
public CategoryDataset getBarData(double[][] data, String[] rowKeys,
String[] columnKeys) {
return DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);

}


/**
* 折线图
*
* @param chartTitle
* @param x
* @param y
* @param xyDataset
* @param charName
*/

public String createTimeXYChar(String chartTitle, String x, String y,
XYDataset xyDataset, String charName, HttpServletResponse response) {

response.setContentType("image/png");

JFreeChart chart = ChartFactory.createTimeSeriesChart(chartTitle, x, y,
xyDataset, true, true, false);

chart.setTextAntiAlias(false);
chart.setBackgroundPaint(Color.WHITE);
// 设置图标题的字体重新设置title
Font font = new Font("宋体", Font.BOLD, 25);
TextTitle title = new TextTitle(chartTitle);
title.setFont(font);
chart.setTitle(title);
// 设置面板字体
Font labelFont = new Font("宋体", Font.TRUETYPE_FONT, 12);

chart.setBackgroundPaint(Color.WHITE);

XYPlot plot = (XYPlot) chart.getPlot();
plot.setBackgroundPaint(Color.white);
plot.setDomainGridlinePaint(Color.lightGray);
plot.setRangeGridlinePaint(Color.lightGray);
plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
plot.setDomainCrosshairVisible(true);
plot.setRangeCrosshairVisible(true);

XYItemRenderer r = plot.getRenderer();
if (r instanceof XYLineAndShapeRenderer) {
XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) r;
renderer.setBaseShapesVisible(true);
renderer.setBaseShapesFilled(true);
renderer.setDrawSeriesLineAsPath(true);
}

DateAxis domainAxis = (DateAxis) plot.getDomainAxis();

/*
CategoryPlot categoryplot = (CategoryPlot) chart.getPlot();
// x轴 // 分类轴网格是否可见
categoryplot.setDomainGridlinesVisible(true);
// y轴 //数据轴网格是否可见
categoryplot.setRangeGridlinesVisible(true);

categoryplot.setRangeGridlinePaint(Color.WHITE);// 虚线色彩

categoryplot.setDomainGridlinePaint(Color.WHITE);// 虚线色彩

categoryplot.setBackgroundPaint(Color.lightGray);
*/

// 设置轴和面板之间的距离
// categoryplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));

//CategoryAxis domainAxis = categoryplot.getDomainAxis();

domainAxis.setLabelFont(labelFont);// 轴标题

domainAxis.setTickLabelFont(labelFont);// 轴数值

// domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45); // 横轴上的
// Lable
// 45度倾斜
// 设置距离图片左端距离

domainAxis.setLowerMargin(0.0);
// 设置距离图片右端距离
domainAxis.setUpperMargin(0.0);

NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();
numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
numberaxis.setAutoRangeIncludesZero(true);

// 获得renderer 注意这里是下嗍造型到lineandshaperenderer!!
XYLineAndShapeRenderer xyLineAndShapeRenderer = (XYLineAndShapeRenderer) plot.getRenderer();

xyLineAndShapeRenderer.setBaseShapesVisible(true); // series 点(即数据点)可见

xyLineAndShapeRenderer.setBaseLinesVisible(true); // series 点(即数据点)间有连线可见

xyLineAndShapeRenderer.setSeriesFillPaint(1, Color.white);

// 显示折点数据
//xyLineAndShapeRenderer.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator());
//xyLineAndShapeRenderer.setBaseItemLabelsVisible(true);

//FileOutputStream fos_jpg = null;
try {

/*isChartPathExist(CHART_PATH);
String chartName = CHART_PATH + charName;
fos_jpg = new FileOutputStream(chartName);*/

// 将报表保存为png文件
ChartUtilities.writeChartAsPNG(response.getOutputStream(), chart, 3380, 680);
response.getOutputStream().close();
//return chartName;
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
try {
//fos_jpg.close();
System.out.println("create time-createTimeXYChar.");
} catch (Exception e) {
e.printStackTrace();
}
}
}

/**
* 判断文件夹是否存在,如果不存在则新建
* @param chartPath
*/
/* private void isChartPathExist(String chartPath) {
File file = new File(chartPath);
if (!file.exists()) {
file.mkdirs();
// log.info("CHART_PATH="+CHART_PATH+"create.");
}
}*/

/**
* ************************************************************************
* Date Tool
* ************************************************************************
*/
private Date parse(String date) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
Date d = new Date();
try {
d = sdf.parse(date);
} catch (Exception e) {

}
return d;
}

private boolean compareYear(String start, String year) {
Date date1 = Helper.parse(start);
Date date2 = Helper.parse(year+"0101");

int n = date1.compareTo(date2);
return n > 0;
}

private boolean compareEndYear(String start, String year) {
Date date1 = Helper.parse(start);
Date date2 = Helper.parse(year);

int n = date1.compareTo(date2);
return n > 0;
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值