您的位置:首页 > 其它

JFreeChart展示柱状图和折线图的组合

2012-09-27 11:02 183 查看
笔者最近工作需要在Web前端展示统计图表(基于SSH架构),使用了JFreeChart和amchart两个控件,谈谈使用心得。

JFreeChart的最大好处是可以在Server端保存jpg图片,并且前端代码简单,各浏览器兼容性好,但是相对来说动态展示效果较差。Amchart则可以更好的展示动态性,但是缺点也很明显,前端代码复杂,不能保存server端图片。另外,chrome和ff中对其支持较好,所需显示时间很短(2s左右),但是在ie8中需要30s以上时间(9张图表)。

JFreeChart前端代码简洁明了,中端API详尽,代码如下:

//1.jquery调用ajax请求
$(document).ready(function() {
$.ajax({
type: "POST",
url: "需要调用的url链接",
beforeSend :function() {//调用成功前前端显示内容
$("#testImgError").text("正在获取...");//可使用动态gif图片展示等待过程
},
success: function(data) {//调用成功后前端处理
$("#testImgError").text("");
$("#testImg").attr("src", "../test/"+data);
},
error: function() {//前端调用错误处理
$("#testImgError").text("调用失败");
$("#testImg").hide();
}
});
});
//2.前端form中的显示,只需两行代码,可嵌入到相应的table或者div中:
<label id="testImgError"></label>
<img id="testImg" width=500 height=270 border=0>


//3.中后端的代码也不复杂,需要处理一下数据获取和图片的保存和发送过程,代码如下:
//3.1.数据获取
public void createTestImg() throws IOException {
//获取参数, id不能为空
Integer id = Integer.parseInt(this.getRequest().getParameter("id"));
//根据id获取数据
List distributed = testService.getData(id);

ChartConstruction mtd = new ChartConstruction("");
JFreeChart demo = mtd.getTestChart(distributed);
//保存为图片,创建所需保存图片的文件夹
String prefix = "InvestTypeDistributed-";
String path1 = "D://Chart//paperIrrByYear";
File newPath = new File(path1);
if (!newPath.exists())
newPath.mkdir();
File tempFile1 = File.createTempFile(prefix, ".jpeg", newPath);
ChartUtilities.saveChartAsJPEG(tempFile1, demo, 500, 270);//实际JFreeChart保存图片方法

//向前台传递Json
sendJSON(distributed);
}
//3.2.向前台发送Json,方法多种多样,大家可以根据需要自行编写
private void sendJSON(List distributed){
Map<String, Object> map = new HashMap<String, Object>();
if ((distributed == null) || (distributed.size() == 0))
map.put("rows", new ArrayList<Object>());
else
map.put("rows", distributed);
senderJson(this.getResponse(), map);
}
//3.3组织数据,两个dataset,形成柱状图和折线图的组合
public JFreeChart getTestChart(List distributed, Integer companyId, String begin, String end){
//List distributed = peCompanyInvestAnalysisService.getCompanyMoneyTypeDistributed(companyId, begin, end);
DefaultCategoryDataset datasetSum = new DefaultCategoryDataset();
DefaultCategoryDataset datasetNum = new DefaultCategoryDataset();
Double maxSum = 0.0d;
Double minSum = 0.0d;
Double tempSum = 0.0d;
Integer maxNum = 0;
Integer minNum = 0;
Integer tempNum = 0;
if(distributed!=null)
for(int i=0;i<distributed.size();i++){
Map mm=(Map)distributed.get(i);
if(mm.get("amount")==null)
tempSum = 0.0d;
else
tempSum = Double.parseDouble(mm.get("amount").toString());
if(mm.get("num")==null)
tempNum = 0;
else
tempNum = Integer.parseInt(mm.get("num").toString());
if(tempNum==null)
tempNum = 0;

datasetSum.addValue(tempSum, "投资币种", mm.get("moneyType").toString());
datasetNum.addValue(tempNum,"投资项目数",mm.get("moneyType").toString());
}

JFreeChart chart = creatChart("投资币种分布图",datasetSum,datasetNum);

return chart;
}
//3.4调用JFreeChart的api,创建图片样式
private JFreeChart creatChart(String title, DefaultCategoryDataset datasetSum, DefaultCategoryDataset datasetNum){
//创建主题样式
StandardChartTheme standardChartTheme=new StandardChartTheme("CN");
standardChartTheme.setExtraLargeFont(new Font("黑体",Font.BOLD,15)); //设置标题字体
standardChartTheme.setRegularFont(new Font("宋书",Font.PLAIN,12));//设置图例的字体
standardChartTheme.setLargeFont(new Font("宋书",Font.PLAIN,12));//设置轴向的字体
ChartFactory.setChartTheme(standardChartTheme);//应用主题样式

JFreeChart chart = ChartFactory.createBarChart(
title, // chart title
"", // x轴标题,domain axis label
"", // y轴标题,range axis label
datasetSum, // data
PlotOrientation.VERTICAL, // orientation
false, // include legend
true, // tooltips?
false // URLs?
);
chart.setBackgroundPaint(Color.white);

CategoryPlot plot = (CategoryPlot) chart.getPlot();
CategoryDataset categorydataset = datasetNum;       //设置第二个数据集
plot.setDataset(1, categorydataset);
plot.mapDatasetToRangeAxis(1, 1);
plot.setBackgroundPaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setOutlinePaint(Color.white);  //设置图片边框颜色,去掉边框

//柱体的样式设计
BarRenderer renderer = (BarRenderer) plot.getRenderer();
renderer.setSeriesPaint(0, Color.orange);
renderer.setDrawBarOutline(false);
//设置柱顶数据,API中居然没有StandardCategoryItemLabelGenerator这个类
renderer.setItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setSeriesItemLabelsVisible(0, true);
//防止由于柱体太少而动态增加柱体宽度(JFreeChart默认是根据柱体多少而显示柱体宽度的)
int k = datasetSum.getColumnCount();
if (k == 1) {
plot.getDomainAxis().setLowerMargin(0.26);
plot.getDomainAxis().setUpperMargin(0.66);
} else if (k < 6) {
double margin = (1.0 - k * 0.08) / 3;
plot.getDomainAxis().setLowerMargin(margin);
plot.getDomainAxis().setUpperMargin(margin);
((BarRenderer) plot.getRenderer()).setItemMargin(margin);
} else {
((BarRenderer) plot.getRenderer()).setItemMargin(0.1);
}

/*------设置Y轴----*/
double unit=1d;//刻度的长度
//右边Y轴,相关属性设置
NumberAxis numberaxis1 = new NumberAxis("");
unit=Math.floor(10);//刻度的长度
NumberTickUnit ntu= new NumberTickUnit(unit);
numberaxis1.setTickUnit(ntu);
numberaxis1.setRange(0,100);//刻度范围
plot.setRangeAxis(1, numberaxis1);
//左边Y轴
NumberAxis numberaxis = (NumberAxis) plot.getRangeAxis();
numberaxis .setAutoTickUnitSelection(false);
numberaxis.setRange(0.0, 100.0);//刻度的范围
ntu= new NumberTickUnit(unit);
numberaxis .setTickUnit(ntu);
/*------设置柱状体与图片边框的上下间距---*/
numberaxis.setUpperMargin(0.05);
numberaxis.setLowerMargin(0.05);

/*------设置X轴----*/
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.STANDARD);
/*------设置X轴标题的倾斜程度----*/
domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0));
/*------设置柱状体与图片边框的左右间距--*/
//domainAxis.setLowerMargin(0.01);
//domainAxis.setUpperMargin(0.01);

//设置折线图的样式
LineAndShapeRenderer lineandshaperenderer = new LineAndShapeRenderer();
lineandshaperenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
lineandshaperenderer.setBaseItemLabelsVisible(true);
lineandshaperenderer.setBaseItemLabelFont(new Font("隶书", Font.BOLD, 10));

plot.setRenderer(1, lineandshaperenderer);
plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD);
//图例1声明及相关样式设置
LegendTitle legendtitle = new LegendTitle(plot.getRenderer(0));
//图例2声明及相关样式设置
LegendTitle legendtitle1 = new LegendTitle(plot.getRenderer(1));
BlockContainer blockcontainer = new BlockContainer(new BorderArrangement());
blockcontainer.add(legendtitle, RectangleEdge.LEFT);
blockcontainer.add(legendtitle1, RectangleEdge.RIGHT);
blockcontainer.add(new EmptyBlock(20D, 0.0D));
CompositeTitle compositetitle = new CompositeTitle(blockcontainer);
compositetitle.setPosition(RectangleEdge.BOTTOM);
chart.addSubtitle(compositetitle);

chart.setAntiAlias(false);
chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);

return chart;
}




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: