olap分析平台的设计与实现(十四)- 形成前端(下)

前端呈现olap表格二种实现方式:

 

后端拼接olap表格的html字符串,吐到前端,Hyperion应该就是采取这种方式实现的。

另外一种,就是前端vue/react/js方式实现。本文对第一种方式均进行阐述。

纯js实现方式:

1、绘制左顶第一个单元格

2、绘制列头区,判断单元格上是否有上卷、下钻图标、跨多少列colspan

3、判断是否有行维,如果没有行维度,仅仅根据结果输出一行factdata

4、如果有行维,则循环绘制每一行的标头、行数据

绘制左顶第一个单元格

一行行的绘制,先绘制表头部分(左顶部第一个单元格+后面的列表头)

按头部区占用的行数遍历
   绘制左上角第一个单元格, 设置其rowspan、colspan,rowspan的值是行维区的列数,colspan的值是列维区占用的行数

					if (i == 0 && axesCount > 1) {
						html.append("<th style='border-top:solid 1px silver;' rowspan='")//第一行第一列添加顶部边框样式
							.append(columnsSize)   //列表头行数
							.append("' colspan='")
							.append(rowLength)    //行表头列数
							.append("' class='Locked1 scrollCR'>");
						html.append("&nbsp;</th>").append(Util.nl);
					}

     ps: viewGrid类中,有private int[][] colMembers = null;  第1[]表示行数,第2[]表示列,
     colMembers.length 就是第一个单元格占用的跨行数。

生成列表头的总体过程:

viewGrid模型中 有属性:
    // 行列维度成员
    private int[][] rowMembers = null;
    private int[][] colMembers = null;
这里对colMembers 进行遍历
按行循环遍历
    按列循环遍历
       获取该单元格是否需要加上上卷\下钻图标
       while ((j + 1) < 本行最后的元素)
        { 
          if(和上一个元素是一样的)
          {j++;colspan++;}  //确定colspan ,及需要跳过的列
        }
        根据上面的结果,拼接html字符串        

绘制列头区,判断单元格上是否有上卷、下钻图标

(上卷、下钻图标)

对是否有上卷下钻图标的判断:
是否有子节点显示中:
是否有子节点处于显示中,返回1表示"+" , 返回 -1 表示"-", 返回0表示无上卷下钻符号

-1表示可上卷,1表示可下钻

判断逻辑如下:

  1.          从成员角度验证  如有无子代返回0,有 子代往下验证:dimMember.getHasChildren()==0
  2.          从表单角度验证  如果其子代不在表单中 返回0,其子代在表单中往下验证:
  3.          从组角度验证      如果其子代不在该组中 返回0, 其子代在组中往下验证,由于我们开始只搞一个组,所有这块可忽略?
  4.          从层级别验证?    我们的模型一般就一个层,级有多个。以列表头为例,我们以当前节点为起点,需要判断本行(本组?)后面节点上的数据,是否是本层的下一级元素。

从表单角度验证  如果其子代不在表单中 返回0,其子代在表单中往下验证的相关代码:

//index 是分组index	,这里遍历viewGrid中的List<List<List<DimMember>>> rowColDimMemberList
//进行遍历,判断是否要+-上卷、下钻标记	
List<List<DimMember>>  childList=rowColDimMemberList.get(index);
		for(int j=0;j<childList.size();j++){
			List<DimMember> dimMemberList=childList.get(j);
			for(int k=0;k<dimMemberList.size();k++){
				DimMember dimMemberInForm=dimMemberList.get(k);
			    if(dimMemberInForm.getParentId()==dimMember.getMemberId()){
				   flag=true;  //flag=ture,表示存在下级成员,可能需要上卷、或者下钻
				   break;
			    }
			}
			if(flag){break;}
		}

如果是列标题表头第一行元素,判断是否有“-”标志的代码如下:

member 就是当前遍历到元素,dimMember 当然是我们目标点位上的维度成员了,
 if(member!=null && member.getParentId()==dimMember.getMemberId()){
						      childFlag=true;  //可以有上卷标志
						      ......;
 }

不是第一行的判断,判断相对复杂?后面再补充。 

一个头部单元格应该跨多少列?

这个好办,按列循环过程当中,判断下一个单元格是否和本单元格内容一致即可。即询问arr[i][j]!=arr[i][j+1],即可知道如何处理。

ps1:获取组号

    /**
     * 根据所给viewgrid的布局及布局上操作点位置的信息计算此操作点所在的布局分组号,返回分组号(从1开始)
     *实现原理是:行、列组信息本来就有完整坐标,这个坐标信息在viewGrid对象中,把表格行列表头点位信息和这个坐*标数组比较即可得出每个点的组位置
     * @param viewGrid 上卷或下钻的FormGrid
     * @param mbrLayout 布局位置 (0 - 列        1 - 行)
     * @param rowPoint (需要判断组号点位-行)
     * @param colPoint (需要判断组号点位-列)
     * @return
     */
    public static int getGroupNumber(FormGrid viewGrid, int layout,
            int rowPoint, int colPoint)

ps2:如果对于只有一组的情况,其实就是记录开始行、列号

记录展开 收缩位置的坐标	
newDrillDownOrRollUpPoint(FormGrid viewGrid,int mbrLayout, int groupNumber, int rowPoint, int colPoint)	

行维表头、事实数据区的绘制步骤,在这里就不展开描述,其过程和列表头的步骤类似。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值