export function getKAGCube()

in zeppelin-web/src/app/tabledata/advanced-transformation-util.js [788:897]


export function getKAGCube(rows, keyColumns, groupColumns, aggrColumns) {
  const schema = {
    key: keyColumns.length !== 0,
    group: groupColumns.length !== 0,
    aggregator: aggrColumns.length !== 0,
  };

  let cube = {};

  const keyColumnName = keyColumns.map((c) => c.name).join('.');
  const groupNameSet = new Set();
  const keyNameSet = new Set();
  const selectorNameWithIndex = {}; /** { selectorName: index } */
  let indexCounter = 0;

  for (let i = 0; i < rows.length; i++) {
    const row = rows[i];
    let c = cube;

    // key: add to entry
    let mergedKeyName;
    if (schema.key) {
      mergedKeyName = keyColumns.map((c) => row[c.index]).join('.');
      // key: add to row
      if (!c[mergedKeyName]) {
        c[mergedKeyName] = {};
      }
      c = c[mergedKeyName];

      keyNameSet.add(mergedKeyName);
    }

    let mergedGroupName;
    if (schema.group) {
      mergedGroupName = groupColumns.map((c) => row[c.index]).join('.');
      groupNameSet.add(mergedGroupName);
    }

    for (let a = 0; a < aggrColumns.length; a++) {
      const aggrColumn = aggrColumns[a];
      const aggrName = `${aggrColumn.name}(${aggrColumn.aggr})`;

      // update groupNameSet
      if (!mergedGroupName) {
        groupNameSet.add(aggrName); /** aggr column name will be used as group name if group is empty */
      }

      // update selectorNameWithIndex
      const selector = getSelectorName(mergedKeyName, aggrColumns.length, aggrName);
      if (typeof selectorNameWithIndex[selector] === 'undefined' /** value might be 0 */) {
        selectorNameWithIndex[selector] = indexCounter;
        indexCounter = indexCounter + 1;
      }

      // add aggregatorName to row
      if (!c[aggrName]) {
        const value = (aggrColumn.aggr !== 'count') ? row[aggrColumn.index] : 1;
        const count = 1;

        c[aggrName] = {aggr: aggrColumn.aggr, value: value, count: count, children: {}};
      } else {
        const value = AggregatorFunctions[aggrColumn.aggr](
          c[aggrName].value, row[aggrColumn.index], c[aggrName].count + 1);
        const count = (AggregatorFunctionDiv[aggrColumn.aggr])
          ? c[aggrName].count + 1 : c[aggrName].count;

        c[aggrName].value = value;
        c[aggrName].count = count;
      }

      // add aggregated group (for drill-down) to row iff group is enabled
      if (mergedGroupName) {
        if (!c[aggrName].children[mergedGroupName]) {
          const value = (aggrColumn.aggr !== 'count') ? row[aggrColumn.index] : 1;
          const count = 1;

          c[aggrName].children[mergedGroupName] = {value: value, count: count};
        } else {
          const drillDownedValue = c[aggrName].children[mergedGroupName].value;
          const drillDownedCount = c[aggrName].children[mergedGroupName].count;
          const value = AggregatorFunctions[aggrColumn.aggr](
            drillDownedValue, row[aggrColumn.index], drillDownedCount + 1);
          const count = (AggregatorFunctionDiv[aggrColumn.aggr])
            ? drillDownedCount + 1 : drillDownedCount;

          c[aggrName].children[mergedGroupName].value = value;
          c[aggrName].children[mergedGroupName].count = count;
        }
      }
    } /** end loop for aggrColumns */
  }

  let keyNames = null;
  if (!schema.key) {
    const mergedGroupColumnName = groupColumns.map((c) => c.name).join('.');
    cube = {[mergedGroupColumnName]: cube};
    keyNames = [mergedGroupColumnName];
  } else {
    keyNames = sortWithNumberSupport(Object.keys(cube)); /** keys should be sorted */
  }

  return {
    cube: cube,
    schema: schema,
    keyColumnName: keyColumnName,
    keyNames: keyNames,
    groupNameSet: groupNameSet,
    selectorNameWithIndex: selectorNameWithIndex,
  };
}