import java.awt.Color; import java.io.IOException; import java.text.SimpleDateFormat; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.DateAxis; import org.jfree.chart.axis.DateTickUnit; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.plot.XYPlot; import org.jfree.data.time.Day; import org.jfree.data.time.Hour; import org.jfree.data.time.Month; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.data.xy.XYDataset; import org.jfree.ui.RectangleInsets; /** * 用于将统计结果显示成走势图 * @author lord * 调用方法: TrendChart trendChart = new TrendChart(); trendChart.chartTitle = "走势图"; trendChart.chartSeriesDesc = "走势曲线"; trendChart.chartXdesc = "时间"; trendChart.chartYdesc = "价格"; trendChart.graphHigh = 400; trendChart.graphWidth = 600; trendChart.timeFormat = "yyyy-MM"; trendChart.periodType = TrendChart.DAY; ...... trendChart.addTimeSeriesUnitData(mYear, mMonth, mDay, mHour, (int)rData); trendChart.createTrendGraphByServlet(request, response); */ public class TrendChart { public final static String MONTH = "MONTH"; public final static String DAY = "DAY"; public final static String HOUR = "HOUR"; private JFreeChart rChart = null; //图表对象 public String chartTitle = ""; //图表标题 public String chartXdesc = ""; //X轴标题 public String chartYdesc = ""; //Y轴标题 public String chartSeriesDesc = ""; //曲线说明 public int graphWidth = 600; //默认宽度 public int graphHigh = 400; //默认高度 public String timeFormat = "MM/yyyy"; // 按日:MM-dd ,按小时:hh:mm // 用于标志用户选择的是按哪种查询统计周期类型(年、月、天、小时). // 年:YEAR, 月:MONTH, 天:DAY, 小时:HOUR public String periodType = ""; // 用于确定时间间隔 public int dateInterval = 0; //统计结果数据集 TimeSeriesCollection statDataset = new TimeSeriesCollection(); TimeSeries monthSeries = null; //月份统计图数据集合 TimeSeries daySeries = null; //天数统计图数据集合 TimeSeries hourSeries = null; //小时统计图数据集合 /** * 创建Servlet方式走势图表 * @param req * @param res * @throws IOException */ public void createTrendGraphByServlet(ServletRequest req, ServletResponse res) throws IOException { res.setContentType("image/jpeg"); setTimeSeriesStatType(); rChart = createTrendChart(); ChartUtilities.writeChartAsJPEG(res.getOutputStream(), 1, rChart, graphWidth, graphHigh, null); } /** * 创建趋势图表 * @return JFreeChart 图表对象JFreeChart */ private JFreeChart createTrendChart(){ JFreeChart _freeChart = ChartFactory.createTimeSeriesChart(chartTitle, chartXdesc, chartYdesc, getTimeSeriesStatDataSet(), true, false, false); _freeChart.setBackgroundPaint(Color.white); XYPlot _xyplot = _freeChart.getXYPlot(); _xyplot.setOrientation(PlotOrientation.VERTICAL); _xyplot.setBackgroundPaint(Color.lightGray); _xyplot.setDomainGridlinePaint(Color.white); _xyplot.setRangeGridlinePaint(Color.white); _xyplot.setAxisOffset(new RectangleInsets(1.0, 2.0, 2.0, 10.0)); DateAxis dateaxis = (DateAxis) _xyplot.getDomainAxis(); if (periodType.equalsIgnoreCase("MONTH")){ if (dateInterval > 0) { dateaxis.setTickUnit(new DateTickUnit(DateTickUnit.MONTH, dateInterval)); } }else if (periodType.equalsIgnoreCase("DAY")){ if (dateInterval > 0) { dateaxis.setTickUnit(new DateTickUnit(DateTickUnit.DAY, dateInterval)); } }else if (periodType.equalsIgnoreCase("HOUR")){ if (dateInterval > 0) { dateaxis.setTickUnit(new DateTickUnit(DateTickUnit.HOUR, dateInterval)); } } dateaxis.setDateFormatOverride(new SimpleDateFormat(timeFormat)); return _freeChart; } /** * 增加走势图数据 * @param periodType 区间类型 * @param year 年份 * @param month 月份 * @param day 日期 * @param hour 时间 * @param statData 统计数据 */ public void addTimeSeriesUnitData(int year, int month, int day, int hour, int statData) { if (periodType.equalsIgnoreCase("MONTH")){ if (monthSeries == null){ monthSeries = new TimeSeries(chartSeriesDesc, Month.class); } monthSeries.add(new Month(month, year), statData); }else if (periodType.equalsIgnoreCase("DAY")){ if (daySeries == null){ daySeries = new TimeSeries(chartSeriesDesc, Day.class); } daySeries.add(new Day(day, month, year), statData); }else if (periodType.equalsIgnoreCase("HOUR")){ if (hourSeries == null){ hourSeries = new TimeSeries(chartSeriesDesc, Hour.class); } hourSeries.add(new Hour(hour, day, month, year), statData); } } /** * 设置走势图统计的区间类型 * @param periodType 区间类型 */ private void setTimeSeriesStatType() { if (periodType.equalsIgnoreCase("MONTH")){ statDataset.addSeries(monthSeries); }else if (periodType.equalsIgnoreCase("DAY")){ statDataset.addSeries(daySeries); }else if (periodType.equalsIgnoreCase("HOUR")){ statDataset.addSeries(hourSeries); } } /** * 获得时序图的统计数据 * @return XYDataset 统计数据 */ private XYDataset getTimeSeriesStatDataSet() { statDataset.setDomainIsPointsInTime(true); return statDataset; } public int getDateInterval() { return dateInterval; } public void setDateInterval(int dateInterval) { this.dateInterval = dateInterval; }
JSP调用代码如下:
TrendChart trendChart = new TrendChart(); trendChart.chartTitle = "一年走势图"; trendChart.chartSeriesDesc = "走势曲线"; trendChart.chartXdesc = "时间"; trendChart.chartYdesc = "价格"; trendChart.graphHigh = 400; trendChart.graphWidth = 600; trendChart.timeFormat = "yyyy-MM"; trendChart.periodType = TrendChart.DAY; double baseData = 100.0; double rData = baseData; java.util.Calendar calendar = java.util.Calendar.getInstance(); calendar.set(2007, 0, 0); for (int i = 1; i <= 365; i++){ rData = rData * (1 + (Math.random() - 0.495) / 10.0); calendar.add(java.util.Calendar.DAY_OF_MONTH, 1); System.out.println(calendar.get(java.util.Calendar.YEAR) + "||" + (calendar.get(java.util.Calendar.MONTH) + 1) + "||" + calendar.get(java.util.Calendar.DAY_OF_MONTH) + "||" + (calendar.get(java.util.Calendar.HOUR_OF_DAY) + "||" + calendar.get(java.util.Calendar.MINUTE)) ); int mYear = calendar.get(java.util.Calendar.YEAR); int mMonth = calendar.get(java.util.Calendar.MONTH) + 1; int mDay = calendar.get(java.util.Calendar.DAY_OF_MONTH); int mHour = calendar.get(java.util.Calendar.HOUR_OF_DAY); trendChart.addTimeSeriesUnitData(mYear, mMonth, mDay, mHour, (int)rData); } trendChart.createTrendGraphByServlet(request, response);
显示图结果如下: