上一节,我们总结了动态生成mdx语句,下面,我们重点总结如何生成前端模型。

前端模型(viewGrid/formGrid),我们为前端模型起个名字--表格模型---大致可以理解为描述一个表格,每个数据区单元格,都有一个行、列坐标。

需要注意的是:前端模型(viewGrid/formGrid)是动态的,前端页面收缩、展开节点(对应olap上卷、下钻),其相关属性也会变化。

构建前端模型(viewGrid/formGrid),就是如何从mdx查询结果,生成这个一个前端模型的问题。

/**
 * 前端模型
 */
public class viewGrid {
	private int axisCount; 
	private int formId;   //对应的分析表单id
	//行维度
	private int[]  rowDims=null;
	//列维度
	private int[]  colDims=null;
	// 行列维度成员,这个是根据显示的情况,动态改变的,只有显示在页面上的元素,才在这个数组中存在
	private int[][] rowMembers = null;  //页面上显示的行维度成员数组,这貌似是最重要的属性了
	private int[][] colMembers = null;  //页面上显示的行维度成员数组,这貌似是最重要的属性了
	// 页面
	private int[] pageLayout = null;
	// 视点
	private int[] vpLayout = null;
	// 事实数据
	private DataCell[][] factDatas = null;
	//form模型,供生成MDX字符串使用
	private CommForm formShadow = null;
	/*
	 * rowGroup表示列布局上的分组信息
	 * 列:
	 * rowCrgoup={0, 15, 19}表示第一组坐标0~14 ,第二组坐标15~18 ,第三组坐标19~rowGroup.lenght
	 */
	private int[] rowGroupInfo = null;
	private int[] colGroupInfo = null;
	//单元格维度位置
	private int[]  cellDims=null;
	...
}

首先我们要理解执行mdx的结果result,它包括如下一些概念:

行、列坐标,由a tuple(元组)形成。

axis & Position:

前面我们提到:a cell is found by specifying a tuple of positions along every axis

cellSet

 ● Cellset is the set which contains the cell returned by the MDX query.

● Cellset is the set where results are founded.

 – Important API methods: getCell, getFilterAxis, getMetadata..

Cell

 ● Cell is the structure which contains a part of the cellset. Every cell, contains a part of the result we are searching with a MDX query.

● It could be said that cells are as rows in RDBs or documents in a document-oriented DB. This is just a very simple approach, a really simple analogy.

– Important API methods: drillThrough, getValue, isEmpty, isNull,...

CellSetAxis:

CellSetAxis is the axis of a cellset (OK?!!)

● A cell set has the same number of axes as the MDX statement which was executed to produce it.

单元格集具有与生成它的MDX语句相同的轴数。

● Each axis is an ordered collection of members or tuples.

● Each member or tuple on an axis is called Position.

– Important API methods: getPositions, getAxisMetada...

ps:tuples:元组

Position:

 ●Position is one of the CellSetAxis objects in a CellSet.

● An axis has a particular dimensionality, that is, a set of one or more dimensions which will appear on than axis, and every position on that axis will have a member of each of those dimensions. (Extracted from official API) 

– Important API methods: getMembers, getOrdinal...

tuple:

A tuple is a combination of members from one or more dimensions. It is essentially a multidimensional member

tuple本身是个成员,可以是个多维度成员。

tuple用“()”标记。

A tuple can stand for a slice of a cube, where the cube is sliced by each member in the tuple.

理解以上概念,就容易理解如下代码,根据mdx查询结果,构建前端模型:

/**
	 * @param result
	 * @param form
	 * @param o (o instanceOf BgForm表示通过formId创建grid
	 * 				o instanceOf FormGrid表示通过grid创建新的grid,即分析表页面切换
	 * 				o == null 表示局部下钻调用此方法,不需要对返回的FormGrid行列布局信息做调整)
	 * @return
	 */
	private FormGrid buildFormGridByResult(Result result, FormShadow formShadow, int[] pageLayoutOId, Object o) {
		
		StringBuffer rowDimsBuffer=new StringBuffer();
		StringBuffer colDimsBuffer=new StringBuffer();
		StringBuffer viewDimsBuffer=new StringBuffer(); //存放的是视点维度成员的id字符串,用逗号分隔
		
		FormGrid formGrid = null;
		try{
			int[] vpLayout = buildViewInfo(formShadow,viewDimsBuffer);  //存放的是视点维度成员的id
			int[] pageLayout = pageLayoutOId;
			if(pageLayoutOId==null){	//如果页面没有选择,则取得第一个元素
				pageLayout = buildPageInfo(formShadow);
			}
			
			int[][] rowMembers = buildRowsInfo(result, formShadow,rowDimsBuffer);
			int[][] colMembers = buildColsInfo(result, formShadow,colDimsBuffer);
			DataCell[][] factDatas = buildFactDatas(result, formShadow);
			int cubeId = formShadow.getCubeId();
			int formId = formShadow.getId();
			formGrid = new FormGrid(cubeId, formId, rowMembers, colMembers,
					pageLayout, vpLayout, factDatas, formShadow);
			formGrid.setAxisCount(result.getAxes().length);
			/*
			 * 这里确定DataCell位置的维度成员id,DataCell 中有 private int[] members = null;....
			 * 根据这个members *数组,可以定位到一个单元格cell的数据,就是说通过这里的设置,单元格数据和全部相关维度成员建立**了关联关系,他们之间能相互感知
			 */
            ......
			
			/*
			 * 设置formGrid中关于行、列布局上组的信息
			 */
			if (o instanceof CommForm) {
					/**
					*
					*通过formId创建grid 的相关处理
					*
					**/
			} else if (o instanceof FormGrid) {
			  /**
			  *通过grid创建新的grid,即分析表页面切换 的相关处理
			  **/
			}
		}catch (Exception e) {
			......
		}
		return formGrid;
	}

建立前端表格模型之行维的完整信息:

/**
	 *  建立行维的完整信息  
	 * @param result
	 * @param rowDimsBuffer 
	 * @param form
	 * @return
	 */
	private int[][] buildRowsInfo(Result result, FormShadow formShadow, StringBuffer rowDimsBuffer) {
		int[][] rowsInfo = null;
		try{
			Axis colAxis = result.getAxes()[1];
			int rowNum = colAxis.getPositions().size();
			int colNum = colAxis.getPositions().get(0).size();
			rowsInfo = new int[rowNum][colNum];
			for (int i = 0; i < rowNum; i++) {
				for (int j = 0; j < colNum; j++) {
					Member member = colAxis.getPositions().get(i).get(j);
					//将mondrian.olap.Member转换成自定义的DimMember
					DimMember dimMember = memberConversion(member,formShadow); /
					rowsInfo[i][j] = dimMember.getMemberId();
					if(i==0 && rowDimsBuffer!=null){
						if(j!=colNum-1){
							rowDimsBuffer.append(dimMember.getDimension().getId()+",");
						}else{
							rowDimsBuffer.append(dimMember.getDimension().getId()+"");
						}
					}
				}
			}
		}catch (Exception e) {
			......
		}
		return rowsInfo;
	}

举个例子:

上面代码中:int rowNum = colAxis.getPositions().size();  行数是78,

int colNum = colAxis.getPositions().get(0).size(); colNum是2;

再举个例子:

怎么看ollama模型位置_javascript

上面代码中:int rowNum = colAxis.getPositions().size();  行数是3,

int colNum = colAxis.getPositions().get(0).size(); colNum是2;

buildRowsInfo方法,就是形成左边行维的完整信息,且把信息存放到int[][]当中。

这里举个执行结果的例子:(每个数字就是一个维度成员id)

[[63176, 67813], [63176, 67826], [63176, 68027], [63177, 67813], [63177, 67826], [63177, 68027], [63178, 67813], [63178, 67826], [63178, 68027], [63179, 67813], [63179, 67826], [63179, 68027], [63180, 67813], [63180, 67826], [63180, 68027], [63181, 67813], [63181, 67826], [63181, 68027], [63182, 67813], [63182, 67826], [63182, 68027], [63183, 68027], [63183, 68028], [63184, 68027], [63184, 68028], [63185, 68027], [63185, 68028], [63186, 68027], [63186, 68028], [63187, 67809], [63190, 67824], [63190, 67825], [63191, 67824], [63191, 67825], [63192, 67824], [63192, 67825], [63193, 67824], [63193, 67825], [63194, 67824], [63194, 67825], [63195, 67824], [63195, 67825], [63196, 67824], [63196, 67825], [63197, 67824], [63197, 67825], [63198, 67824], [63198, 67825], [63199, 67824], [63199, 67825], [63202, 67813], [63202, 67814], [63202, 67819], [63202, 67820], [63202, 67823], [63202, 67826], [63202, 67827], [63203, 67813], [63203, 67814], [63203, 67819], [63203, 67820], [63203, 67823], [63203, 67826], [63203, 67827], [63204, 67813], [63204, 67814], [63204, 67819], [63204, 67820], [63204, 67823], [63204, 67826], [63204, 67827], [63205, 67813], [63205, 67814], [63205, 67819], [63205, 67820], [63205, 67823], [63205, 67826], [63205, 67827]]

除了获取行维度成员的全部明细信息,获取维度信息也是这个函数的作用,结果存放在rowDimsBuffer,其形式如:110,112。

获取列轴上的详细信息:

基本步骤为:遍历每个position---->遍历每个position上的meber(every position on that axis will have a member of each of those dimensions.);取得相关维度放入二维数组,值得注意的是,数组是按【列】【行】形式出差列维详细信息的,具体代码和行维详细信息类似,这里就不展开了。

获取事实数据:

事实数据model:

/**
 * 数据单元格
 *
 */
public class DataCell {
	
	private int formId;
	private int cubeId;
	private Object[] factValues = null;
	private boolean[] exist = null;
	//确定DataCell位置的维度成员id
	private int[] members = null;
	......
	
}

a cell is found by specifying a tuple of positions along every axis

/**
	 *建立事实数据部分
	 * @param result
	 * @param form
	 * @return
	 */
	private DataCell[][] buildFactDatas(Result result, IcpForm form) {
		int rowCount = result.getAxes()[1].getPositions().size();
		int colCount = result.getAxes()[0].getPositions().size();
		DataCell[][] dataCells = new DataCell[rowCount][colCount / 2];
		try{
			Cell cell = null;
			for (int i = 0; i < rowCount; i++) {
				for (int j = 0; j < colCount; j = j) {
					/*
					 * 在mondrian中,一个结果集的事实数据表格【列】【行】形式
					 */
					cell_1 = result.getCell(new int[] { j, i });
	
					dataCells[i][j] = cellConversion(new Cell[] { cell}, form);
				}
			}
		}catch (Exception e) {
			......
		}
		return dataCells;
	}

DataCell:

   datacell中有个重要属性,就是    private int[] members = null;  存放的个一一个cell管理的所有维度成员id,在获取行、列、数据区详细信息后,遍历factDatas,设置members属性,我们通过这个方式,建立cell与相关维度成员间的相互感知。

前端模型viewGrid(FormGrid)其他辅助属性:

private int[] rowGroupInfo = null; private int[] colGroupInfo = null;

怎么看ollama模型位置_前端_02

(示意图)

这里行信息是:{0, 2},有2个组,就有2个数组元素,3个组就有3个数组元素,以此类推。

0表示第一个组的起始位置,2表示第2组的起始位置,以此类推。

再举个例子 [0, 1, 2, 3, 4, 17],这表示有6个组,数组元素的值就是每组开始位置。

1)rowGroupInfo、colGroupInfo  都是根据后端模型生成的。

2)private int[]  rowDims=null; //行维度
3)private int[]  colDims=null;//列维度

4)private int[]  cellDims=null;//单元格维度位置,每个单元格都有维度成员信息,顺序和这个是一样的?

这些属性,都是为在web层展示做准备。