package com.trulytech.mantis.util;
import java.io.*;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map.Entry;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.*;
import org.jfree.chart.*;
import org.jfree.chart.plot.*;
import org.jfree.data.category.*;
import org.jfree.data.general.*;
import org.jfree.data.xy.*;
import com.trulytech.mantis.result.*;
import org.jfree.chart.title.TextTitle;
/**
* <p>
* Title: ChartManagement
* </p>
* <p>
* Description:后台产生图形(JFreeChart)
* </p>
* <p>
* Copyright: Copyright (c) 2002
* </p>
* <p>
* Company:
* </p>
*
* @author Wang Xian
* @version 1.2 PIE RING BAR LINE STACKBAR AREA STACKAREA XYLINE XYAREA 输出为PNG类型
*/
public class ChartManagement {
static final private String CONTENT_TYPE = "image/png";
// Http Response
private HttpServletResponse response = null;
// 标识图表的类型
final public static String PIE = "pie";
final public static String RING = "ring";
final public static String BAR = "bar";
final public static String LINE = "line";
final public static String STACKBAR = "stackbar";
final public static String AREA = "area";
final public static String STACKAREA = "stackbararea";
final public static String XYLINE = "xyline";
final public static String XYAREA = "xyarea";
final public static int RESPONSE = 0;
final public static int FILE = 1;
final public static int BUFFERIMAGE = 2;
// 是否是3D的图表
private boolean is3d = true;
// 是否是alpha的图表
private boolean isalpha = true;
// 输出图的高度和宽度
private int width = 400;
private int height = 300;
// 数据源
private DBResult result = null;
// 标识图表的类型,输入方式和输出方式
private String chart_type = "";
// 图表的各种标识
private String title = "图表标题";
private String categoryTag = "目录轴的显示标签";
private String valueTag = "数值轴的显示标签";
private String[] Legend = null;
private Color backGroundColor = null;
// 存储目标文件名
private String descFile = "";
// 子标题
private String subTitle = "";
/**
*
* @param chart_type
* String
* @param response
* Object HttpServletResponse或者String,如果是String,则保存为文件,必须是GIF图形
* @param Result
* DBResult
* @param is3d
* boolean
* @param Legend
* 图例
*/
public ChartManagement(String chart_type, HttpServletResponse response,
DBResult Result, boolean is3d, String[] Legend) {
this.chart_type = chart_type;
this.result = Result;
this.response = response;
this.is3d = is3d;
this.Legend = Legend;
if (Legend == null) {
this.Legend = new String[this.result.getColumnCount() - 1];
for (int i = 0; i < this.result.getColumnCount() - 1; i++)
this.Legend[i] = "项目" + new Integer(i);
}
if (Legend.length < this.result.getColumnCount() - 1) {
this.Legend = new String[this.result.getColumnCount() - 1];
for (int i = 0; i < this.result.getColumnCount() - 1; i++)
this.Legend[i] = "项目" + new Integer(i);
}
}
/**
*
* @param chart_type
* String
* @param response
* Object HttpServletResponse或者String,如果是String,则保存为文件,必须是GIF图形
* @param Result
* DBResult
* @param is3d
* boolean
*/
public ChartManagement(String chart_type, HttpServletResponse response,
DBResult Result, boolean is3d) {
this.chart_type = chart_type;
this.result = Result;
this.response = response;
this.is3d = is3d;
this.Legend = new String[this.result.getColumnCount() - 1];
for (int i = 0; i < this.result.getColumnCount() - 1; i++)
this.Legend[i] = "项目" + new Integer(i);
}
/**
* 生成Web图形
*
* @return String
* @throws Exception
*/
public String generateChart() throws Exception {
outputChart(this.getInputData(), ChartManagement.RESPONSE);
return "";
}
/**
* 生成BufferImage
*
* @return BufferedImage
* @throws Exception
*/
public BufferedImage generateChartImage() throws Exception {
return outputChart(this.getInputData(), ChartManagement.BUFFERIMAGE);
}
/**
* 生成文件
*
* @return BufferedImage
* @throws Exception
*/
public BufferedImage generateChartFile() throws Exception {
return outputChart(this.getInputData(), ChartManagement.FILE);
}
/**
* 组织数据源
*
* @return Dataset 数据源
* @throws Exception
*/
private Dataset getInputData() throws Exception {
Dataset dataset = null;
if (result != null) {
// 生成PieDataset
if (chart_type.equalsIgnoreCase(ChartManagement.PIE)
|| chart_type.equalsIgnoreCase(ChartManagement.RING)) {
dataset = new DefaultPieDataset();
if (result.getColumnCount() == 2) {
// 循环赋值
LinkedHashMap al = null;
int nSize = result.getResultBuffer().size();
for (int i = 0; i < nSize; i++) {
al = (LinkedHashMap) result.getResultBuffer().get(i);
String categoryTag = null;
double value = 0d;
if (al.size() >= 2) {
Iterator iter = al.entrySet().iterator();
Entry valueEntry = (Entry) iter.next();
Entry labelEntry = (Entry) iter.next();
value = new Double((String) labelEntry.getValue())
.doubleValue();
categoryTag = (String) valueEntry.getValue();
}
((DefaultPieDataset) dataset).setValue(categoryTag,
value);
}
} else {
throw new Exception("得到的数据的列数不对,应该是两列");
}
}
// 生成XYDataSet
else if (chart_type.equalsIgnoreCase(ChartManagement.XYLINE)
|| chart_type.equalsIgnoreCase(ChartManagement.XYAREA)) {
if (result.getColumnCount() > 1) {
// 分别代表x和y值
if (result.getColumnCount() == 2) {
XYSeries xyseries = new XYSeries("First");
LinkedHashMap al = null;
XYSeriesCollection xyseriescollection = new XYSeriesCollection();
int nSize = result.getResultBuffer().size();
for (int i = 0; i < nSize; i++) {
al = (LinkedHashMap) result.getResultBuffer()
.get(i);
if (al.size() >= 2) {
Iterator iter = al.entrySet().iterator();
Entry labelEntry = (Entry) iter.next();
Entry valueEntry = (Entry) iter.next();
xyseries.add(new Double((String) valueEntry
.getValue()).doubleValue(), new Double(
(String) labelEntry.getValue())
.doubleValue());
}
}
xyseriescollection.addSeries(xyseries);
dataset = xyseriescollection;
}
// 仅仅去前3个值, 第一个为类型,后两个分别是x和y值
else if (result.getColumnCount() > 2) {
LinkedHashMap al = null;
LinkedHashMap map = new LinkedHashMap();
XYSeriesCollection xyseriescollection = new XYSeriesCollection();
int nSize = result.getResultBuffer().size();
for (int i = 0; i < nSize; i++) {
al = (LinkedHashMap) result.getResultBuffer()
.get(i);
Iterator iter = al.entrySet().iterator();
Entry valueEntry = (Entry) iter.next();
Entry labelEntry = (Entry) iter.next();
Entry axisEntry = (Entry) iter.next();
if (map.get(valueEntry.getValue()) == null) {
XYSeries xyseries = new XYSeries(
(String) valueEntry.getValue());
xyseries.add(new Double((String) labelEntry
.getValue()).doubleValue(), new Double(
(String) axisEntry.getValue())
.doubleValue());
map.put((String) valueEntry.getValue(),
xyseries);
} else {
XYSeries xyseries = (XYSeries) map
.get((String) valueEntry.getValue());
xyseries.add(new Double((String) labelEntry
.getValue()).doubleValue(), new Double(
(String) axisEntry.getValue())
.doubleValue());
map.put((String) valueEntry.getValue(),
xyseries);
}
}
this.Legend = new String[map.size()];
Iterator it = map.keySet().iterator();
int i = 0;
while (it.hasNext()) {
Object obj = it.next();
Legend[i] = (String) obj;
xyseriescollection.addSeries((XYSeries) map
.get(obj));
i++;
}
map.clear();
map = null;
dataset = xyseriescollection;
}
} else {
throw new Exception("得到的数据的列数错误");
}
}
// 生成CategoryDataSet
else if (chart_type.equalsIgnoreCase(ChartManagement.BAR)
|| chart_type.equalsIgnoreCase(ChartManagement.LINE)
|| chart_type.equalsIgnoreCase(ChartManagement.STACKBAR)
|| chart_type.equalsIgnoreCase(ChartManagement.AREA)
|| chart_type.equalsIgnoreCase(ChartManagement.STACKAREA)) {
dataset = new DefaultCategoryDataset();
if (result.getColumnCount() > 1) {
// 循环赋值
LinkedHashMap al = null;
int nSize = result.getResultBuffer().size();
for (int i = 0; i < nSize; i++) {
al = (LinkedHashMap) result.getResultBuffer().get(i);
String categoryTag = null;
double value = 0d;
// 判断是复杂的数据集还是简单的数据集
if (result.getColumnCount() == 2) {
Iterator iter = al.entrySet().iterator();
Entry valueEntry = (Entry) iter.next();
Entry labelEntry = (Entry) iter.next();
value = new Double((String) labelEntry.getValue())
.doubleValue();
categoryTag = (String) valueEntry.getValue();
((DefaultCategoryDataset) dataset).addValue(value,
Legend[0], categoryTag);
}
// ////////
// 例如: name, age, income
// a,20,2000
// b,35 3000
// 则有两中颜色的类别 : age和income
// ///////////
else if (result.getColumnCount() > 2) {
Iterator iter = al.entrySet().iterator();
Entry[] entry = new Entry[result.getColumnCount()];
for (int n = 0; n < result.getColumnCount(); n++) {
entry[n] = (Entry) iter.next();
}
for (int m = 1; m < result.getColumnCount(); m++) {
value = new Double((String) entry[m].getValue())
.doubleValue();
categoryTag = (String) entry[0].getValue();
((DefaultCategoryDataset) dataset).addValue(
value, Legend[m - 1], categoryTag);
}
}
}
} else {
throw new Exception("得到的数据的列数错误");
}
} else {
dataset = getExtInputData();
}
} else {
throw new Exception("数据集DBResult是空的");
}
return dataset;
}
/**
* 根据数据源生成图形
*
* @param ds
* Dataset 数据源
* @param flag
* 生成类型
* @return BufferedImage
* @throws Exception
*/
private BufferedImage outputChart(Dataset ds, int flag) throws Exception {
OutputStream out = null;
if (flag == ChartManagement.RESPONSE) {
// 设置头信息
((HttpServletResponse) response).setContentType(CONTENT_TYPE);
((HttpServletResponse) response).setHeader("Content-Disposition",
" filename=image.png");
out = ((HttpServletResponse) response).getOutputStream();
} else if (flag == ChartManagement.FILE) {
out = new BufferedOutputStream(new FileOutputStream(
(String) this.descFile));
}
try {
JFreeChart chart = null;
// 生成Pie
if (chart_type.equalsIgnoreCase(ChartManagement.PIE)) {
// 如果是3DPie
if (is3d) {
// 如果有aplha效果
if (isalpha) {
PiePlot3D plot = new PiePlot3D((PieDataset) ds);
plot.setForegroundAlpha(0.5f);
// 如果有背景图片
if (this.backGroundColor != null)
plot.setBackgroundPaint(this.backGroundColor);
chart = new JFreeChart(title, plot);
}
// 如果没有alpha效果
else {
chart = ChartFactory.createPieChart3D(title,
(PieDataset) ds, true, false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
}
// 如果是2DPie
else {
if (isalpha) {
PiePlot plot = new PiePlot((PieDataset) ds);
plot.setForegroundAlpha(0.5f);
// 如果有背景图片
if (this.backGroundColor != null)
plot.setBackgroundPaint(this.backGroundColor);
chart = new JFreeChart(title, plot);
} else {
chart = ChartFactory.createPieChart(title,
(PieDataset) ds, true, false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
}
}
// Ring 2D
else if (chart_type.equalsIgnoreCase(ChartManagement.RING)) {
if (isalpha) {
RingPlot plot = new RingPlot((PieDataset) ds);
plot.setForegroundAlpha(0.5f);
// 如果有背景图片
if (this.backGroundColor != null)
plot.setBackgroundPaint(this.backGroundColor);
chart = new JFreeChart(title, plot);
} else {
chart = ChartFactory.createRingChart(title,
(PieDataset) ds, true, false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
}
// 生成Bar
else if (chart_type.equalsIgnoreCase(ChartManagement.BAR)) {
// 如果是3D bar
if (is3d) {
chart = ChartFactory.createBarChart3D(title, categoryTag,
valueTag, (CategoryDataset) ds,
PlotOrientation.VERTICAL, this.result
.getColumnCount() > 2 ? true : false,
false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
} else {
chart = ChartFactory.createBarChart(title, categoryTag,
valueTag, (CategoryDataset) ds,
PlotOrientation.VERTICAL, this.result
.getColumnCount() > 2 ? true : false,
false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
}
// 生成Line
else if (chart_type.equalsIgnoreCase(ChartManagement.LINE)) {
chart = ChartFactory.createLineChart(title, categoryTag,
valueTag, (CategoryDataset) ds,
PlotOrientation.VERTICAL,
this.result.getColumnCount() > 2 ? true : false, false,
false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
// 生成XYLine
else if (chart_type.equalsIgnoreCase(ChartManagement.XYLINE)) {
chart = ChartFactory.createXYLineChart(title, categoryTag,
valueTag, (XYDataset) ds, PlotOrientation.VERTICAL,
true, false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
// XYAREA
else if (chart_type.equalsIgnoreCase(ChartManagement.XYAREA)) {
chart = ChartFactory.createXYAreaChart(title, categoryTag,
valueTag, (XYDataset) ds, PlotOrientation.VERTICAL,
true, false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
// 生成StackBar
else if (chart_type.equalsIgnoreCase(ChartManagement.STACKBAR)) {
if (is3d) {
chart = ChartFactory.createStackedBarChart(title,
categoryTag, valueTag, (CategoryDataset) ds,
PlotOrientation.VERTICAL, this.result
.getColumnCount() > 2 ? true : false,
false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
} else {
chart = ChartFactory.createStackedBarChart3D(title,
categoryTag, valueTag, (CategoryDataset) ds,
PlotOrientation.VERTICAL, this.result
.getColumnCount() > 2 ? true : false,
false, false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
}
// 生成Area
else if (chart_type.equalsIgnoreCase(ChartManagement.AREA)) {
chart = ChartFactory.createAreaChart(title, categoryTag,
valueTag, (CategoryDataset) ds,
PlotOrientation.VERTICAL,
this.result.getColumnCount() > 2 ? true : false, false,
false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
// 生成StackArea
else if (chart_type.equalsIgnoreCase(ChartManagement.STACKAREA)) {
chart = ChartFactory.createStackedAreaChart(title, categoryTag,
valueTag, (CategoryDataset) ds,
PlotOrientation.VERTICAL,
this.result.getColumnCount() > 2 ? true : false, false,
false);
if (this.backGroundColor != null)
chart.setBackgroundPaint(this.backGroundColor);
}
// 设置副标题
if (this.subTitle != null && this.subTitle.length() > 0
&& chart != null) {
chart.addSubtitle(new TextTitle(this.subTitle));
}
SetChartExtProperty(chart);
// 以PNG方式生成
if (flag == ChartManagement.FILE
|| flag == ChartManagement.RESPONSE) {
ChartUtilities.writeChartAsPNG(out, chart, width, height, null);
return null;
} else {
return chart.createBufferedImage(width, height);
}
} finally {
if (out != null) {
out.flush();
out.close();
}
}
}
/**
* 获得其他的数据信息,用于扩展
*
* @return Dataset
*/
protected Dataset getExtInputData() {
return null;
}
/**
* 设置更多的图形属性,用于扩展
*
* @param chart
* JFreeChart
*/
protected void SetChartExtProperty(JFreeChart chart) {
}
public void setIs3d(boolean is3d) {
this.is3d = is3d;
}
public void setTitle(String title) {
this.title = title;
}
public void setValueTag(String valueTag) {
this.valueTag = valueTag;
}
public void setCategoryTag(String categoryTag) {
this.categoryTag = categoryTag;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public void setChartType(String ChartType) {
this.chart_type = ChartType;
}
public void setResult(DBResult result) {
this.result = result;
}
public void setBackGroundColor(Color backGroundColor) {
this.backGroundColor = backGroundColor;
}
public void setIsalpha(boolean isalpha) {
this.isalpha = isalpha;
}
public void setDescFile(String descFile) {
this.descFile = descFile;
}
public void setSubTitle(String subTitle) {
this.subTitle = subTitle;
}
public void setLegend(String[] Legend) {
this.Legend = Legend;
}
public Color getBackGroundColor() {
return backGroundColor;
}
public String getDescFile() {
return descFile;
}
public String getSubTitle() {
return subTitle;
}
public String[] getLegend() {
return Legend;
}
}