pivot()

in zeppelin-web/src/app/tabledata/pivot.js [138:279]


  pivot(data, keys, groups, values) {
    let aggrFunc = {
      sum: function(a, b) {
        let varA = (a !== undefined) ? (isNaN(a) ? 0 : parseFloat(a)) : 0;
        let varB = (b !== undefined) ? (isNaN(b) ? 0 : parseFloat(b)) : 0;
        return varA + varB;
      },
      count: function(a, b) {
        let varA = (a !== undefined) ? parseInt(a) : 0;
        let varB = (b !== undefined) ? 1 : 0;
        return varA + varB;
      },
      min: function(a, b) {
        let aIsValid = isValidNumber(a);
        let bIsValid = isValidNumber(b);
        if (!aIsValid) {
          return parseFloat(b);
        } else if (!bIsValid) {
          return parseFloat(a);
        } else {
          return Math.min(parseFloat(a), parseFloat(b));
        }
      },
      max: function(a, b) {
        let aIsValid = isValidNumber(a);
        let bIsValid = isValidNumber(b);
        if (!aIsValid) {
          return parseFloat(b);
        } else if (!bIsValid) {
          return parseFloat(a);
        } else {
          return Math.max(parseFloat(a), parseFloat(b));
        }
      },
      avg: function(a, b, c) {
        let varA = (a !== undefined) ? (isNaN(a) ? 0 : parseFloat(a)) : 0;
        let varB = (b !== undefined) ? (isNaN(b) ? 0 : parseFloat(b)) : 0;
        return varA + varB;
      },
    };

    let isValidNumber = function(num) {
      return num !== undefined && !isNaN(num);
    };

    let aggrFuncDiv = {
      sum: false,
      count: false,
      min: false,
      max: false,
      avg: true,
    };

    let schema = {};
    let rows = {};

    for (let i = 0; i < data.rows.length; i++) {
      let row = data.rows[i];
      let s = schema;
      let p = rows;

      for (let k = 0; k < keys.length; k++) {
        let key = keys[k];

        // add key to schema
        if (!s[key.name]) {
          s[key.name] = {
            order: k,
            index: key.index,
            type: 'key',
            children: {},
          };
        }
        s = s[key.name].children;

        // add key to row
        let keyKey = row[key.index];
        if (!p[keyKey]) {
          p[keyKey] = {};
        }
        p = p[keyKey];
      }

      for (let g = 0; g < groups.length; g++) {
        let group = groups[g];
        let groupKey = row[group.index];

        // add group to schema
        if (!s[groupKey]) {
          s[groupKey] = {
            order: g,
            index: group.index,
            type: 'group',
            children: {},
          };
        }
        s = s[groupKey].children;

        // add key to row
        if (!p[groupKey]) {
          p[groupKey] = {};
        }
        p = p[groupKey];
      }

      for (let v = 0; v < values.length; v++) {
        let value = values[v];
        let valueKey = value.name + '(' + value.aggr + ')';

        // add value to schema
        if (!s[valueKey]) {
          s[valueKey] = {
            type: 'value',
            order: v,
            index: value.index,
          };
        }

        // add value to row
        if (!p[valueKey]) {
          p[valueKey] = {
            value: (value.aggr !== 'count') ? row[value.index] : 1,
            count: 1,
          };
        } else {
          p[valueKey] = {
            value: aggrFunc[value.aggr](p[valueKey].value, row[value.index], p[valueKey].count + 1),
            count: (aggrFuncDiv[value.aggr]) ? p[valueKey].count + 1 : p[valueKey].count,
          };
        }
      }
    }

    // console.log('schema=%o, rows=%o', schema, rows);
    return {
      keys: keys,
      groups: groups,
      values: values,
      schema: schema,
      rows: rows,
    };
  }