转载

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

概述

旨在为 Cognos 报表开发人员提供一种 Report Studio 结合 JavaScript 实现钻取、过滤、动态列等效果的方法参考。ReportStudio 中通过引入 js 能大大丰富报表的交互方式和增强报表的展示效果。最终效果如图 1 所示:

图 1. 最终效果示意图

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

功能说明:

  • 单项按钮组:用户可以自定义不同维度的层级组合,比如直接选择具体产品和零售商国家进行组合查询数据。
  • 文本框:用户可以在对应的文本框中输入关键字,进行模糊查询。
  • 单选按钮:可以让用户选择哪些列需要展示和隐藏。
  • 展开维度:钻取到当前维度的下一层。
  • 只看选中数据: 把单元格中的数据作为参数去查询中过滤。
  • 返回并取消过滤:清除选择维度上的过滤条件并返回上一级。

适用范围

本文实例基于 IBM Cognos 10.2.1 版本编写,并测试通过。

应用场景

实现多个维度上实现下钻和上卷

通过多维模型能方便的实现下钻和上卷,但是在实践中发现当报表中使用维度数过多时,基于多维模型的报表响应速度将会大大降低。而使用 Cognos Cube 作为数据源的报表当报表当使用维度数太多时,不仅报表响应速度会下降而且会出现 crossjoin set 的报错。此时通过本文介绍的方法基于关系模型来制作报表既能在一张报表上实现多个维度的钻取和过滤,又能达到相对满意的报表响应速度

满足用户自定义的交互方式

用户对报表的交互方式的需求越来越高,越来越个性化。通过本文读者可以举一反三地将 js 方法运用到 Report Studio 报表的开发中以满足用户不同的需求。

实现方法

通过参数控制列的显示内容

  1. 新建空白报表,在 list 中拖入要展示的度量。

    图 2. 拖入度量

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  2. 在 list 对应的查询中拖入查询计算,该查询计算作用是接受参数以控制维度列展示的内容,所以要展示多少列维度就拖入多少个查询计算项。这里的内容都设置为常量。

    图 3. 控制展示内容的查询计算项

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    图 4. 控制展示内容的查询计算项

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  3. 对拖入的查询计算添加过滤,并将过滤设置为禁用。

    图 5. 过滤条件设为禁用

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  4. 拖入查询计算,用以展示维度的最高层,以产品这个维度为例,内容如下.

    图 6. 顶层定义

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    图 7. 维度的顶层定义

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  5. 拖入查询计算项,通过 case..when 语句实现同一列,根据参数不同展示不同内容。以产品为例内容如下(其他的内容类似):

    图 8. 条件判断

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    上面的表达式根据参数的不同而展示产品维度下的 3 个不同层级。(如果数据模型是多维模型请将查询项定义为“结果集”)

  6. 拖入值提示,控制参数的值

图 9. 新建参数

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

图 10. 参数对应的值提示

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

默认选项设置为 1

图 11. 值提示的默认选项

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

为了方便后面的 JavaScript 代码与值提示进行交互,请将这 4 个值提示的名称依次改为 DIM1、DIM2、DIM3、DIM4。

图 12. 值提示命名

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

完成后,您将可以通过单选按钮控制下面的产品这一列显示的内容。

图 13. 单选按钮组初步效果

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

同理将其他几个维度加上去,添加完维度后可以通过单选按钮切换列表显示的内容,效果如下:

图 14. 单选按钮组效果

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

此时用户可以自定义不同维度不同层级的组合来查看数据。

Javascript 实现钻取和过滤

为了丰富功能和更友好的交互,下面将介绍用 js 实现钻取和过滤。

原理:report studio 中 JavaScript 是不能直接和报表进行数据交互的,要通过值提示组件作为中介进行。下钻的动作就是把单选按钮组的当前选项设置为下一个,上卷则设置为上一个。过滤就是通过 JavaScript 将对应的值赋给文本提示框。

  1. 为了实现过滤,在查询中加入过滤条件,注意到这里是用的 like 进行模糊匹配,这样会带来更好的用户体验。

    图 15. 过滤条件设置

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  2. 拖入文本提示框来接收上面的参数

    图 16. 对应的文本提示框

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  3. 在列表上面拖入 html 项目,通过 JavaScript 实现点击时弹出蒙层菜单:

    图 17. 弹出蒙层的 JavaScript

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    清单 1. 实现重新点击事件和弹出蒙层

    清单 1. 实现重新点击事件和弹出蒙层

    <styletype="text/css"> .cMenu{ BORDER-RIGHT:#0000001pxsolid; BORDER-TOP:#0000001pxsolid; FONT-WEIGHT:normal; FONT-SIZE:14px; VISIBILITY:hidden; BORDER-LEFT:#0000001pxsolid; WIDTH:150px; CURSOR:default; COLOR:#000000; LINE-HEIGHT:20px; BORDER-BOTTOM:#0000001pxsolid; FONT-FAMILY:Verdana,Arial,Helvetica,sans-serif; POSITION:absolute; BACKGROUND-COLOR:#eeeeff } .menuitems{ PADDING-RIGHT:5px; PADDING-LEFT:5px } </style> <divid='contextMenu'class="cMenu"style="position:absolute;left:100px;top:100px"> <DIVclass=menuitemsonclick="UnflodDim();"onmouseover="highLightMenu()"onmouseout="LowMenu()">展开维度</DIV> <DIVclass=menuitemsonclick="FilterData();"onmouseover="highLightMenu()"onmouseout="LowMenu()">只看选中的数据</DIV> <DIVclass=menuitemsonclick="FlodDim();"onmouseover="highLightMenu()"onmouseout="LowMenu()">返回并取消过滤</DIV> <HRcolor=#aaaaaasize="0"> <DIVclass=menuitemsonclick="hideContexMenu();"onmouseover="highLightMenu()"onmouseout="LowMenu()">关闭菜单</DIV> </div> <scriptlanguage="javascript"> //自定义右键菜单对象 varcontexMenu=document.getElementById('contextMenu'); //获取 COGNOS 对象后缀 functiongetPostFix() { varpostFix; postFix=document.getElementById('cv.id'); returnpostFix; } //隐藏 COGNOS 右键菜单 functionhideContexMenu() { contexMenu.style.visibility="hidden"; } //显示 cognos 右键菜单 functionshowContexMenu() { contexMenu.style.visibility="visible"; //确定菜单显示位置 contexMenu.style.left=event.x; contexMenu.style.top=event.y; returnclearCognosMenu(); } //强制清除自带右键菜单 functionclearCognosMenu() { varpostFix=getPostFix(); returneval("oCV"+postFix.value+".bCanUseCognosViewerContextMenu=false"); } //高亮显示菜单 functionhighLightMenu() { varmenuItem=event.srcElement; if(menuItem.className="menuitems") { menuItem.style.backgroundColor="highlight"; menuItem.style.color="white"; } } //不高亮显示 functionLowMenu() { varmenuItem=event.srcElement; if(menuItem.className="menuitems") { menuItem.style.backgroundColor=""; menuItem.style.color="black"; } } document.body.onload=clearCognosMenu; </script>
  4. 给列表中的内容添加点击事件,在解锁的前提下向维度单元格中拖入 4 个 html 项目。其中第二个 html 项目定义改为数据项。

    图 18. 列表内容添加点击事件

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    四个 html 项目内容分别为:

    清单 2. 给列表中内容添加点击事件

    1 <uonclick="ShowPan(' 2 [查询 1].[产品]+'#DIM1' 3 ')"> 4 </u>

    同理将所有的维度都加上上面的四个 html。

  5. 通过 js 实现“钻取”和过滤

    图 19. 实现钻取的 JavaScript 代码

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

清单 3. 实现钻取和过滤的代码

<script> varrealValues; varflag; //获取 cognos 中的值提示对象 varform=getFormWarpRequest(); functionShowPan(cellValue){ //截取最后 4 位以确定点击的是哪个维度 flag=cellValue.slice(-4); realValues=cellValue.slice(0,-5); showContexMenu(); } //-------------------展开所选择的维度--------------- functionUnflodDim(){ vardim1A; if(flag=='DIM1'){ dim1A=form._oLstChoicesDIM1; }elseif(flag=='DIM2') { dim1A=form._oLstChoicesDIM2; }elseif(flag=='DIM3') { dim1A=form._oLstChoicesDIM3; }elseif(flag=='DIM4'){ dim1A=form._oLstChoicesDIM4; } for(i=0;i<=dim1A.length;i++){ if(dim1A[i].selected){ if(i==dim1A.length-1){ alert('该层已经是最小层级,不能被展开'); break; }else{ dim1A[i+1].checked=true; promptButtonFinish(); break; } } } } //-----------返回上一级并取消该维度上的过滤条件------------ functionFlodDim(){ //接收按钮组和文本提示的两个对象 vardim1A1; vartextpar; //清空过滤条件 if(flag=='DIM1'){ //form._oLstChoices 后面是单选按钮组的名称 dim1A1=form._oLstChoicesDIM1; for(i=0;i<dim1A1.length;i++){ if(dim1A1[i].selected){ if((i-1)==1){ //form._textEditBox 后面是文本提示框的名称 textpar=form._textEditBoxPCPXL; textpar.value=''; break; }elseif((i-1)==2){ textpar=form._textEditBoxPCPLX; textpar.value=''; break; }elseif((i-1)==3){ textpar=form._textEditBoxPCP; textpar.value=''; break; } } } }elseif(flag=='DIM2') { dim1A1=form._oLstChoicesDIM2; textpar=form._textEditBoxPDGFFLX; textpar.value=''; }elseif(flag=='DIM3') { dim1A1=form._oLstChoicesDIM3; for(i=0;i<dim1A1.length;i++){ if(dim1A1[i].selected){ if((i-1)==1){ textpar=form._textEditBoxPLSSQY; textpar.value=''; break; }elseif((i-1)==2){ textpar=form._textEditBoxPLSSGJ; textpar.value=''; break; }elseif((i-1)==3){ textpar=form._textEditBoxPLSS; textpar.value=''; break; } } } }elseif(flag=='DIM4') { dim1A1=form._oLstChoicesDIM4; for(i=0;i<dim1A1.length;i++){ if(dim1A1[i].selected){ if((i-1)==1){ textpar=form._textEditBoxPYEAR; textpar.value=''; break; }elseif((i-1)==2){ textpar=form._textEditBoxPQUAR; textpar.value=''; break; }elseif((i-1)==3){ textpar=form._textEditBoxPMONTH; textpar.value=''; break; } } } } //返回上一级 for(i=0;i<dim1A1.length;i++){ if(dim1A1[i].selected){ if(i==0){ alert('根节点不能向上返回'); break; }else{ dim1A1[i-1].checked=true; promptButtonFinish(); break; } } } } //-----------------过滤数据------------ functionFilterData(){ vardim1A; varPcp; if(flag=='DIM1'){ dim1A=form._oLstChoicesDIM1; for(i=0;i<dim1A.length;i++){ if(dim1A[i].selected){ if(i==1){ Pcp=form._textEditBoxPCPXL; dim1A[i+1].checked=true; }elseif(i==2){ Pcp=form._textEditBoxPCPLX; dim1A[i+1].checked=true; }elseif(i==3){ Pcp=form._textEditBoxPCP; }elseif(i==0){ alert('根节点不能作为过滤条件'); } } } Pcp.value=realValues; }elseif(flag=='DIM2') { dim1A=form._oLstChoicesDIM2; Pcp=form._textEditBoxPDGFFLX; Pcp.value=realValues; }elseif(flag=='DIM3') { dim1A=form._oLstChoicesDIM3; for(i=0;i<dim1A.length;i++){ if(dim1A[i].selected){ if(i==1){ Pcp=form._textEditBoxPLSSQY; dim1A[i+1].checked=true; }elseif(i==2){ Pcp=form._textEditBoxPLSSGJ; dim1A[i+1].checked=true; }elseif(i==3){ Pcp=form._textEditBoxPLSS; }elseif(i==0){ alert('根节点不能作为过滤条件'); } } } Pcp.value=realValues; }elseif(flag=='DIM4') { dim1A=form._oLstChoicesDIM4; for(i=0;i<dim1A.length;i++){ if(dim1A[i].selected){ if(i==1){ Pcp=form._textEditBoxPYEAR; dim1A[i+1].checked=true; }elseif(i==2){ Pcp=form._textEditBoxPQUAR; dim1A[i+1].checked=true; }elseif(i==3){ Pcp=form._textEditBoxPMONTH; }elseif(i==0){ alert('根节点不能作为过滤条件'); } } } Pcp.value=realValues; } promptButtonFinish(); } </script>

经过以上步骤钻取过滤功能已经实现。

图 20. 钻取效果示意图

Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

实现动态列

为了用户交互界面更加友好,这里制作一个动态列的效果,实现根据用户自定义要显示哪些列。

  1. 拖入一个值提示,新建参数 p1, 并做以下设置:

    图 21. 动态列的参数设置 1

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    图 22. 动态列的参数设置 2

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    图 23. 动态列的参数设置 3

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  2. 新建列对应的布尔变量。

    图 24. 新建布尔型变量

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    图 25. 布尔型变量设置

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  3. 在报表页面,选中列后进行以下操作

    图 26. 让列表中的列对应刚刚建立的布尔变量

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

    对每一列进行类似操作,完成之后您将可以控制列的显示和隐藏。

    图 27. 动态列的初步效果

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列
  4. 优化页面显示,引入以下三个 JavaScript 代码

    图 28. 优化动态列显示效果的代码

    Cognos Report Studio 用 JavaScript 实现钻取、过滤和动态显示列

清单 4. 优化动态列显示效果的代码

1 <label><inputid=1type="checkbox"checked="checked"value=0onclick="ChangeIt(this)"/>产品</label> <label><inputid=2type="checkbox"checked="checked"value=1onclick="ChangeIt(this)"/>订购方法</label> <label><inputid=3type="checkbox"checked="checked"value=2onclick="ChangeIt(this)"/>零售商</label> <label><inputid=4type="checkbox"checked="checked"value=3onclick="ChangeIt(this)"/>时段</label> <label><inputid=5type="checkbox"checked="checked"value=4onclick="ChangeIt(this)"/>数量</label> <label><inputid=6type="checkbox"checked="checked"value=5onclick="ChangeIt(this)"/>收入</label> <label><inputid=7type="checkbox"checked="checked"value=6onclick="ChangeIt(this)"/>毛利润</label> 2 <divstyle="display:none"> 3 <script> varform=getFormWarpRequest(); vardim1=form._oLstChoicesAAA; if(!dim1[0].selected){ document.getElementById("1").checked=false; } if(!dim1[1].selected){ document.getElementById("2").checked=false; } if(!dim1[2].selected){ document.getElementById("3").checked=false; } if(!dim1[3].selected){ document.getElementById("4").checked=false; } if(!dim1[4].selected){ document.getElementById("5").checked=false; } if(!dim1[5].selected){ document.getElementById("6").checked=false; } if(!dim1[6].selected){ document.getElementById("7").checked=false; } functionChangeIt(obj){ //如果要选中 if(obj.checked){ varn=obj.value; dim1[n].checked=true; promptButtonFinish(); }else{ //如果要取消选中 varn=obj.value; dim1[n].checked=false; promptButtonFinish(); } } </script> </div> <br> <br>

至此开发完成。读者也可以下载附件中本报表对应的 xml 文件,通过 Cognos 自带的示例包进行还原,能看到更具体的实现步骤。

结束语

随着客户对交互性要求的提高,单纯通过 report studio 的组件难以满足客户需求,运用本文介绍的引入 JavaScript 方法举一反三地将大大提高报表开发灵活性和丰富报表的交互方式。对于任何技术在实施之前,都要在测试环境测试验证,以确保技术可靠性。

下载

描述 名字 大小
Javascript钻取过滤demo jsfilterdemo.zip 5k
原文  http://www.ibm.com/developerworks/cn/analytics/library/ba-1605-cognosreportjs/index.html?ca=drs-
正文到此结束
Loading...