一、HTML中map对象和area元素:
在Web开发中,我们使用可以jfreechart引擎在server端绘制图表,并在浏览器端呈现给用户。但是,有时可能需要以下一些操作,比如在柱状图中光标悬停在某个柱体上得到它的取值,点击饼图中某个扇形获取更详细信 息等等,为此就要求该图形具有交互操作 的功能。在HTML规范中为了让<img>具有交互性,需要为其定义一个Map对象。先来看一个具体的实例:
源图像solar.gif
这个实例提供了一个太阳系的图像映射代码。该代码在 map 元素中使用 area 元素及其 coords 和 shape 属性创建了由图象映射指向单个行星图像的链接。shape取值有3种:rect 或 rectangle 表示矩形区域、circ 或 circle 表示圆形区域、poly 或 polygon表示多边形区域。coords取值格式取决于 shape 属性的值,具体如下:
你也许要说,看了coords就要晕了,我怎么可能写出这个Map啊!放心吧,这种脏活累活会由任劳任怨的jfreechart搞定。具体来说,
二、jfreechart创建包含Map对象的统计图
为了生成Map对象还需要另外一个对象
1、创建一个ChartRenderingInfo对象。
2、调用ServletUtilities类的saveChartAsJPEG方法、ChartRenderingInfo对象作为参数传入。
3、作为参数被传入的ChartRenderingInfo对象已经填充好Map数据,调用writeImageMap方法。
在Web开发中,我们使用可以jfreechart引擎在server端绘制图表,并在浏览器端呈现给用户。但是,有时可能需要以下一些操作,比如在柱状图中光标悬停在某个柱体上得到它的取值,点击饼图中某个扇形获取更详细信 息等等,为此就要求该图形具有交互操作 的功能。在HTML规范中为了让<img>具有交互性,需要为其定义一个Map对象。先来看一个具体的实例:
<
p
><
img
src
="solar.gif"
width
="504"
height
="126"
alt
="太阳系"
usemap
="#myMap"
>
< map name ="myMap" >
< area shape ="rect" coords ="0,0,82,126" title ="sun" href ="sun.gif" >
< area shape ="circle" coords ="90,58,3" title ="mercury" href =" mercury .gif" >
< area shape ="circle" coords ="124,58,8" title ="venus" href =" venus .gif" >
< area shape ="circle" coords ="162,58,10" title ="earth" href =" earth .gif" >
< area shape ="circle" coords ="203,58,8" title ="mars" href =" mars .gif" >
< area shape ="poly" coords ="221,34,238,37,257,32,278,44,284,60,281,75,288,91,267,87,253,89,
237,81,229,64,228,54" title ="jupitor" href =" jupitor .gif" >
< area shape ="poly" coords ="288,19,316,39,330,37,348,47,351,66,349,74,367,105,337,85,324,85,
307,77,303,60,307,50" title ="saturn" href =" saturn .gif" >
< area shape ="poly" coords ="405,39,408,50,411,57,410,71,404,78,393,80,383,86,381,75,376,69,
376,56,380,48,393,44" title ="uranus" href =" uranus .gif" >
< area shape ="poly" coords ="445,38,434,49,431,53,427,62,430,72,435,77,445,92,456,77,463,72,
463,62,462,53,455,47" title ="neptune" href =" neptune .gif" >
< area shape ="circle" coords ="479,66,3" title ="pluto" href =" pluto .gif" >
</ map >
< map name ="myMap" >
< area shape ="rect" coords ="0,0,82,126" title ="sun" href ="sun.gif" >
< area shape ="circle" coords ="90,58,3" title ="mercury" href =" mercury .gif" >
< area shape ="circle" coords ="124,58,8" title ="venus" href =" venus .gif" >
< area shape ="circle" coords ="162,58,10" title ="earth" href =" earth .gif" >
< area shape ="circle" coords ="203,58,8" title ="mars" href =" mars .gif" >
< area shape ="poly" coords ="221,34,238,37,257,32,278,44,284,60,281,75,288,91,267,87,253,89,
237,81,229,64,228,54" title ="jupitor" href =" jupitor .gif" >
< area shape ="poly" coords ="288,19,316,39,330,37,348,47,351,66,349,74,367,105,337,85,324,85,
307,77,303,60,307,50" title ="saturn" href =" saturn .gif" >
< area shape ="poly" coords ="405,39,408,50,411,57,410,71,404,78,393,80,383,86,381,75,376,69,
376,56,380,48,393,44" title ="uranus" href =" uranus .gif" >
< area shape ="poly" coords ="445,38,434,49,431,53,427,62,430,72,435,77,445,92,456,77,463,72,
463,62,462,53,455,47" title ="neptune" href =" neptune .gif" >
< area shape ="circle" coords ="479,66,3" title ="pluto" href =" pluto .gif" >
</ map >
源图像solar.gif
这个实例提供了一个太阳系的图像映射代码。该代码在 map 元素中使用 area 元素及其 coords 和 shape 属性创建了由图象映射指向单个行星图像的链接。shape取值有3种:rect 或 rectangle 表示矩形区域、circ 或 circle 表示圆形区域、poly 或 polygon表示多边形区域。coords取值格式取决于 shape 属性的值,具体如下:
shape
=
circ
/
circle coords
=
"
x1,y1,r
"
// 以(x1,y2)为圆心、r为半径的圆形区域
shape = poly / polygon coords = " x1,y1,x2,y2...xn,yn "
// 以每个(x,y)为一个顶点、依次构成的多边形区域
shape = rect / rectangle coords = " x1,y1,x2,y2 "
// 以(x1,y1)为左上角顶点、(x2,y2)为右下角顶点所构成的矩形区域
// 以(x1,y2)为圆心、r为半径的圆形区域
shape = poly / polygon coords = " x1,y1,x2,y2...xn,yn "
// 以每个(x,y)为一个顶点、依次构成的多边形区域
shape = rect / rectangle coords = " x1,y1,x2,y2 "
// 以(x1,y1)为左上角顶点、(x2,y2)为右下角顶点所构成的矩形区域
ChartUtilities类中的
writeImageMap方法
会帮我们生成Map对象。二、jfreechart创建包含Map对象的统计图
当我们在sevlet/jsp中使用jfreechart的时候,总会用到一个类,他就是org.jfree.chart.ChartUtilities。这个类包含了常用的公用方法:从chart对象来生成图像(支持JPEG和PNG两种格式)、生成图像的Map对象。这个类的所有方法都是static的。
通过第一部分的介绍,
Map
是
究竟什么呢?简而言之,
Map
定义了一个图像中不同区域的信息,包括了位置、提示和链接。而后两项信息在创建一个chart对象时最后两个参数相关联:
//
获取JFreeChart对象
JFreeChart chart = ChartFactory.createMultiplePieChart (
chartTitle, // 图表标题
dataset, // 数据集
TableOrder.BY_COLUMN, // 指定被提取数据的顺序
false , // 是否包含图例
true , // 是否包含提示工具
true // 是否包含url
);
JFreeChart chart = ChartFactory.createMultiplePieChart (
chartTitle, // 图表标题
dataset, // 数据集
TableOrder.BY_COLUMN, // 指定被提取数据的顺序
false , // 是否包含图例
true , // 是否包含提示工具
true // 是否包含url
);
org.jfree.chart.ChartRenderingInfo。
因为jfreechart
没有直接的方法从一个chart对象直接生成Map,而是需要ChartRenderingInfo对象来过渡。具体步骤为:1、创建一个ChartRenderingInfo对象。
ChartRenderingInfo info
=
new
ChartRenderingInfo(
new
StandardEntityCollection());
2、调用ServletUtilities类的saveChartAsJPEG方法、ChartRenderingInfo对象作为参数传入。
//
调用该方法结束后将在临时目录产生一个名为fileName 的图像文件
// 该文件与HttpSession相关联,被一个ChartDeleter实例注册
// 也就是说当session结束后,会由ChartDeleter来删除这个临时图像文件
String fileName = ServletUtilities.saveChartAsJPEG(chart, width, height, info, session);
// 该文件与HttpSession相关联,被一个ChartDeleter实例注册
// 也就是说当session结束后,会由ChartDeleter来删除这个临时图像文件
String fileName = ServletUtilities.saveChartAsJPEG(chart, width, height, info, session);
3、作为参数被传入的ChartRenderingInfo对象已经填充好Map数据,调用writeImageMap方法。
//
从ChartRenderingInfo对象中读取信息。写HTML中的<map>元素
ChartUtilities.writeImageMap( new PrintWriter( out ), fileName, info);
ChartUtilities.writeImageMap( new PrintWriter( out ), fileName, info);
三、效果图以及
源代码:
源文件hot.jsp
<%
@ page language
=
"
java
"
contentType
=
"
text/html;charset=GB2312
"
import = " java.text.* "
import = " java.awt.* "
import = " org.jfree.chart.* "
import = " org.jfree.chart.servlet.* "
import = " org.jfree.chart.plot.* "
import = " org.jfree.chart.labels.StandardPieItemLabelGenerator "
import = " org.jfree.chart.entity.* "
import = " org.jfree.data.category.* "
import = " org.jfree.util.* "
import = " java.io.* "
%>
<%
String bookType[] = {"社科类", "文学类", "体育类", "少儿类"} ;
String week[] = {"第1周", "第2周", "第3周", "第4周"} ;
String category = request.getParameter( " category " ) == null ?
"" : request.getParameter( " category " );
category = new String(category.getBytes( " 8859_1 " ), " gb2312 " );
String pieIndexStr = request.getParameter( " pieIndex " ) == null ?
" -1 " : request.getParameter( " pieIndex " );
int pieIndex = Integer.parseInt(pieIndexStr);
int cateIndex = - 1 ;
for ( int i = 0 ; i < bookType.length; i ++ ) {
if (bookType[i].equals(category))
cateIndex = i;
}
String title = " 各周图书销量 " ;
String chartTitle = request.getParameter( " category " ) == null ?
title : title + " —— " + category + week[pieIndex];
// 创建数据集
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// 构建数据
int bookSales;
for ( int i = 0 ; i < bookType.length; i ++ ) {
for (int j =0 ; j < week.length; j++) {
bookSales = 50 + i * 10 + j * 100;
dataset.addValue(bookSales, bookType[i], week[j]);
}
}
// 获取JFreeChart对象
JFreeChart chart = ChartFactory.createMultiplePieChart (
chartTitle, // 图表标题
dataset, // 数据集
TableOrder.BY_COLUMN, // 指定被提取数据的顺序
false , // 是否包含图例
true , // 是否包含提示工具
true // 是否包含url
);
// 创建图像
int width = 800 , height = 600 ;
// 获取PiePlot对象
MultiplePiePlot multiPlot = (MultiplePiePlot) chart.getPlot();
JFreeChart obj = multiPlot.getPieChart();
PiePlot plot = (PiePlot) obj.getPlot();
plot.setURLGenerator( new org.jfree.chart.urls.StandardPieURLGenerator( " hot.jsp " ));
// 设置标签格式
plot.setLabelGenerator( new StandardPieItemLabelGenerator( " {0}:{1}({2}) " ,
NumberFormat.getNumberInstance(),
new DecimalFormat( " 0.00% " )));
// 分离圆弧
if (cateIndex != - 1 )
plot.setExplodePercent(cateIndex, 0.2 );
// 设置饼图标签的绘制字体
plot.setLabelFont( new Font( " 黑体 " , Font.PLAIN, 12 ));
ChartRenderingInfo info = new ChartRenderingInfo( new StandardEntityCollection());
// 设置图片生成格式
String fileName = ServletUtilities.saveChartAsJPEG(chart,
width, height, info, session);
ChartUtilities.writeImageMap( new PrintWriter(out), fileName, info);
// 设置图片生成路径
String graphURL = request.getContextPath() +
" /servlet/org.jfree.chart.servlet.DisplayChart?filename= " + fileName;
%>
<p align="center">
<img src="<%= graphURL %>" usemap="#<%= fileName %>" />
</p>
import = " java.text.* "
import = " java.awt.* "
import = " org.jfree.chart.* "
import = " org.jfree.chart.servlet.* "
import = " org.jfree.chart.plot.* "
import = " org.jfree.chart.labels.StandardPieItemLabelGenerator "
import = " org.jfree.chart.entity.* "
import = " org.jfree.data.category.* "
import = " org.jfree.util.* "
import = " java.io.* "
%>
<%
String bookType[] = {"社科类", "文学类", "体育类", "少儿类"} ;
String week[] = {"第1周", "第2周", "第3周", "第4周"} ;
String category = request.getParameter( " category " ) == null ?
"" : request.getParameter( " category " );
category = new String(category.getBytes( " 8859_1 " ), " gb2312 " );
String pieIndexStr = request.getParameter( " pieIndex " ) == null ?
" -1 " : request.getParameter( " pieIndex " );
int pieIndex = Integer.parseInt(pieIndexStr);
int cateIndex = - 1 ;
for ( int i = 0 ; i < bookType.length; i ++ ) {
if (bookType[i].equals(category))
cateIndex = i;
}
String title = " 各周图书销量 " ;
String chartTitle = request.getParameter( " category " ) == null ?
title : title + " —— " + category + week[pieIndex];
// 创建数据集
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
// 构建数据
int bookSales;
for ( int i = 0 ; i < bookType.length; i ++ ) {
for (int j =0 ; j < week.length; j++) {
bookSales = 50 + i * 10 + j * 100;
dataset.addValue(bookSales, bookType[i], week[j]);
}
}
// 获取JFreeChart对象
JFreeChart chart = ChartFactory.createMultiplePieChart (
chartTitle, // 图表标题
dataset, // 数据集
TableOrder.BY_COLUMN, // 指定被提取数据的顺序
false , // 是否包含图例
true , // 是否包含提示工具
true // 是否包含url
);
// 创建图像
int width = 800 , height = 600 ;
// 获取PiePlot对象
MultiplePiePlot multiPlot = (MultiplePiePlot) chart.getPlot();
JFreeChart obj = multiPlot.getPieChart();
PiePlot plot = (PiePlot) obj.getPlot();
plot.setURLGenerator( new org.jfree.chart.urls.StandardPieURLGenerator( " hot.jsp " ));
// 设置标签格式
plot.setLabelGenerator( new StandardPieItemLabelGenerator( " {0}:{1}({2}) " ,
NumberFormat.getNumberInstance(),
new DecimalFormat( " 0.00% " )));
// 分离圆弧
if (cateIndex != - 1 )
plot.setExplodePercent(cateIndex, 0.2 );
// 设置饼图标签的绘制字体
plot.setLabelFont( new Font( " 黑体 " , Font.PLAIN, 12 ));
ChartRenderingInfo info = new ChartRenderingInfo( new StandardEntityCollection());
// 设置图片生成格式
String fileName = ServletUtilities.saveChartAsJPEG(chart,
width, height, info, session);
ChartUtilities.writeImageMap( new PrintWriter(out), fileName, info);
// 设置图片生成路径
String graphURL = request.getContextPath() +
" /servlet/org.jfree.chart.servlet.DisplayChart?filename= " + fileName;
%>
<p align="center">
<img src="<%= graphURL %>" usemap="#<%= fileName %>" />
</p>