很多情况我们不仅仅要求可以在浏览器上显示一个图表,我们更需要客户可以直接在图表上做一下交互的操作,例如获取信息提示,点击图表某个部分进行更详细信息的展示等等。例如前面生成的简单柱状图,用户需要在看到柱状图后点击某种水果例如是苹果即可看到各个地区苹果产量的情况。为此就要求该图形具有交互操作的功能。在HTML中为了让一个图像具有可交互的功能就必须给该图像定义一个Map对象。下表节选一段具有该功能的HTML代码
<MAP NAME="chartMap"> <AREA SHAPE="RECT" COORDS="81,15,126,254" href="?series=0&category=100" title="100 = 7,048" onclick="javascript:clickChart('100');return false;"> <AREA SHAPE="RECT" COORDS="143,27,188,255" href="?series=0&category=200" title="200 = 6,721" onclick="javascript: clickChart ('200');return false;"> <AREA SHAPE="RECT" COORDS="205,54,250,255" href="?series=0&category=300" title="300 = 5,929" onclick="javascript: clickChart ('300');return false;"> <AREA SHAPE="RECT" COORDS="267,85,312,255" href="?series=0&category=400" title="400 = 5,005" onclick="javascript: clickChart ('400');return false;"> <AREA SHAPE="RECT" COORDS="329,17,374,255" href="?series=0&category=Diet" title="Diet = 7,017" onclick="javascript: clickChart ('Diet');return false;"> </MAP> |
由此就产生了一个问题:如果根据一个图像来生成对应的MAP对象。我们回头看看刚才的代码,在创建一个图表对象时候有两个参数,我们举柱状图的例子来讲这两个参数就是ChartFactory. createBarChart3D方法中的最后两个参数,这两个参数的类型都是布尔值。这两个参数意思分别是:是否创建工具提示(tooltip)以及是否生成URL。这两个参数分别对应着MAP中一个AREA的title属性以及href属性。
可是我想知道的是怎么来产生这个MAP啊!哈哈,不要着急,JFreeChart已经帮我们做好生成MAP对象的功能。为了生成MAP对象就要引入另外一个对象:ChartRenderingInfo。因为JFreeChart没有直接的方法利用一个图表对象直接生成MAP数据,它需要一个中间对象来过渡,这个对象就是ChartRenderingInfo。下图是生成MAP数据的流程图:
图7
如上图所示,ChartUtilities类是整个流程的核心,它周围的对象都是一些例如数据对象或者是文件等。这个流程简单描述如下:首先创建一个ChartRenderingInfo对象并在调用ChartUtilities的writeChartAsJPEG时作为最后一个参数传递进去。调用该方法结束后将产生一个图像文件以及一个填充好MAP数据的ChartRenderingInfo对象,有了这个对象我们还是没有办法获取具体的MAP数据,我们还必须借助于ChartUtilities的writeImageMap方法来将ChartRenderingInfo对象读取出来,获取MAP数据的代码片断如下:
PrintWriter w = null; FileOutputStream fos_jpg = null; FileOutputStream fos_cri = null; try{ //根据不同类型的图表使用不同类,以下是针对饼图的操作 PiePlot plot = (PiePlot) chart.getPlot(); plot.setURLGenerator(new StandardPieURLGenerator(url)); //设置工具提示 plot.setToolTipGenerator(new StandardPieToolTipGenerator()); fos_jpg = new FileOutputStream(“d:\\fruit.jpg”); ChartUtilities.writeChartAsJPEG( fos_jpg, 100, chart, 400, 300, info); fos_cri = new FileOutputStream(__d:\\fruit.map__); w = new PrintWriter(fos_cri); ChartUtilities.writeImageMap(w, __mapname__, info); w.flush(); }finally{ try{ w.close(); }catch(Exception e){} try{ fos_cri.close(); }catch(Exception e){} try{ fos_jpg.close(); }catch(Exception e){} } |
打开文件D:\fruit.map,文件的内容就是要写到页面上的MAP数据。把生成的图像文件以及MAP数据文件写到页面上即可完成热点图表的功能。至于怎么结合两者之间的关系例如图像的useMap属性值必须与MAP对象的名称结合起来,必须根据实际的应用情况进行相应的处理。笔者建议把二者通过标签库封装起来,图像文件的名称以及MAP对象的名称由标签库统一进行控制,这样可以保证二者的一致性。
关于作者 刘冬,他已经不再叫凤梨罐头了。珠海市创我科技发展有限公司软件工程师,主要从事在J2EE平台上实现商业智能(BI)方面的开发。 联系电话:0756-3377435-383 电子邮件: winter.lau@163.com
|