Skip to content

行分组算法

Model 数据层分组算法

行数据结构

let rows = [
  {_id: '01', '0000': 'a', '1111': 2, '2222': 102},
  {_id: '02', '0000': 'a', '1111': 2, '2222': 100},
  {_id: '03', '0000': 'b', '1111': 1, '2222': 102},
  {_id: '04', '0000': 'b', '1111': 3, '2222': 100},
  {_id: '05', '0000': 'b', '1111': 5, '2222': 100},
  {_id: '06', '0000': 'b', '1111': 3, '2222': 100},
  {_id: '07', '0000': 'b', '1111': 5, '2222': 100},
];

分组数据结构,每一项是行的键,表示用这些键分组

let group_bys = ['0000', '1111', '2222'];

基本思路:根据每一层分组条件进行递归,然后把新的子分组放在父分组中。

多层分组并不是线性的,是多层级的树状结构,那么尝试把数组转换成树状结构,然后递归树。

function runNode(node = {}, rows, depth) {
  const column_key = group_bys[depth];
  // 如果已经到最下层,那么就是叶子树
  if (!column_key) {
    return rows;
  }
  let dict = [];
  // 遍历当前子树的全部节点,使用字典分组
  rows.forEach(row => {
    let value = row[column_key];
    // 如果当前子分组没有这个键,那么新建这个子分组
    if (!dict[value]) {
      dict[value] = [];
    }
    dict[value].push(row);
  });
  // 设置当前节点的深度
  node.depth = depth;
  // 现在字典构建完毕,然后转换成树节点
  for (let key in dict) {
    node[key] = runNode(node[key], dict[key], depth + 1);
  }
  return node;
}

let root = {};
const initDepth = 0;
root = runNode(root, rows, initDepth);
console.log(root);

上面分组的实际结果数据结构,这样就把数组转换成需要的树状结构

{
    "depth": 0,
    "a": {
        "2": {
            "100": [
                {
                    "1111": 2,
                    "2222": 100,
                    "_id": "02",
                    "0000": "a"
                }
            ],
            "102": [
                {
                    "1111": 2,
                    "2222": 102,
                    "_id": "01",
                    "0000": "a"
                }
            ],
            "depth": 2
        },
        "depth": 1
    },
    "b": {
        "1": {
            "102": [
                {
                    "1111": 1,
                    "2222": 102,
                    "_id": "03",
                    "0000": "b"
                }
            ],
            "depth": 2
        },
        "3": {
            "100": [
                {
                    "1111": 3,
                    "2222": 100,
                    "_id": "04",
                    "0000": "b"
                },
                {
                    "1111": 3,
                    "2222": 100,
                    "_id": "06",
                    "0000": "b"
                }
            ],
            "depth": 2
        },
        "5": {
            "100": [
                {
                    "1111": 5,
                    "2222": 100,
                    "_id": "05",
                    "0000": "b"
                },
                {
                    "1111": 5,
                    "2222": 100,
                    "_id": "07",
                    "0000": "b"
                }
            ],
            "depth": 2
        },
        "depth": 1
    }
}

View 视图层渲染算法

视图渲染分成两个思路

  • 所有的行都是同级,使用绝对定位,然后设置不同的 top 值,好处是便于执行行动画。分组的背景框做成一个DIV,在一个层级中。全部的行在另一个层级中。当分组变化时,分组的框直接变化,然后不同的行重新设置 top 值,这样界面上显示行动画效果更好。
  • 所有的行都是块级元素,直接把树结构,渲染成块级结构,但是动画效果不好实现。

不同的深度 depth 左侧的偏移量和背景色是不同的


Last update: November 5, 2023