{"version":3,"file":"groupingToMatrix.cjs","sources":["../../../../src/transformations/transformers/groupingToMatrix.ts"],"sourcesContent":["import { map } from 'rxjs/operators';\n\nimport { DataFrame, Field, FieldType } from '../../types/dataFrame';\nimport {\n  SpecialValue,\n  DataTransformerInfo,\n  TransformationApplicabilityLevels,\n  DataTransformContext,\n} from '../../types/transformations';\nimport { fieldMatchers } from '../matchers';\nimport { FieldMatcherID } from '../matchers/ids';\n\nimport { DataTransformerID } from './ids';\nimport { getSpecialValue } from './utils';\n\nexport interface GroupingToMatrixTransformerOptions {\n  columnField?: string;\n  rowField?: string;\n  valueField?: string;\n  emptyValue?: SpecialValue;\n}\n\nconst DEFAULT_COLUMN_FIELD = 'Time';\nconst DEFAULT_ROW_FIELD = 'Time';\nconst DEFAULT_VALUE_FIELD = 'Value';\nconst DEFAULT_EMPTY_VALUE = SpecialValue.Empty;\n\nexport const groupingToMatrixTransformer: DataTransformerInfo<GroupingToMatrixTransformerOptions> = {\n  id: DataTransformerID.groupingToMatrix,\n  name: 'Grouping to Matrix',\n  description: 'Groups series by field and return a matrix visualisation',\n  defaultOptions: {\n    columnField: DEFAULT_COLUMN_FIELD,\n    rowField: DEFAULT_ROW_FIELD,\n    valueField: DEFAULT_VALUE_FIELD,\n  },\n  /**\n   * Grouping to matrix requires at least 3 fields to work.\n   */\n  isApplicable: (data: DataFrame[]) => {\n    let numFields = 0;\n\n    for (const frame of data) {\n      numFields += frame.fields.length;\n    }\n\n    return numFields >= 3\n      ? TransformationApplicabilityLevels.Applicable\n      : TransformationApplicabilityLevels.NotApplicable;\n  },\n  isApplicableDescription: (data: DataFrame[]) => {\n    let numFields = 0;\n\n    for (const frame of data) {\n      numFields += frame.fields.length;\n    }\n\n    return `Grouping to matrix requires at least 3 fields to work. Currently there are ${numFields} fields.`;\n  },\n  operator: (options: GroupingToMatrixTransformerOptions, ctx: DataTransformContext) => (source) =>\n    source.pipe(\n      map((data) => {\n        const columnFieldMatch = options.columnField || DEFAULT_COLUMN_FIELD;\n        const rowFieldMatch = options.rowField || DEFAULT_ROW_FIELD;\n        const valueFieldMatch = options.valueField || DEFAULT_VALUE_FIELD;\n        const emptyValue = options.emptyValue || DEFAULT_EMPTY_VALUE;\n\n        // Accept only single queries\n        if (data.length !== 1) {\n          return data;\n        }\n\n        const frame = data[0];\n        const keyColumnField = findKeyField(frame, columnFieldMatch);\n        const keyRowField = findKeyField(frame, rowFieldMatch);\n        const valueField = findKeyField(frame, valueFieldMatch);\n        const rowColumnField = `${rowFieldMatch}\\\\${columnFieldMatch}`;\n\n        if (!keyColumnField || !keyRowField || !valueField) {\n          return data;\n        }\n\n        const columnValues = uniqueValues(keyColumnField.values);\n        const rowValues = uniqueValues(keyRowField.values);\n\n        const matrixValues: { [key: string]: { [key: string]: unknown } } = {};\n\n        for (let index = 0; index < valueField.values.length; index++) {\n          const columnName = keyColumnField.values[index];\n          const rowName = keyRowField.values[index];\n          const value = valueField.values[index];\n\n          if (!matrixValues[columnName]) {\n            matrixValues[columnName] = {};\n          }\n\n          matrixValues[columnName][rowName] = value;\n        }\n\n        const fields: Field[] = [\n          {\n            name: rowColumnField,\n            values: rowValues,\n            type: keyRowField.type,\n            config: { ...keyRowField.config },\n          },\n        ];\n\n        for (const columnName of columnValues) {\n          let values = [];\n          for (const rowName of rowValues) {\n            // nested dataframes need to be undefined when empty\n            const value =\n              matrixValues[columnName][rowName] ??\n              (valueField.type === FieldType.frame ? undefined : getSpecialValue(emptyValue));\n            values.push(value);\n          }\n\n          // setting the displayNameFromDS in prometheus overrides\n          // the column name based on value fields that are numbers\n          // this prevents columns that should be named 1000190\n          // from becoming named {__name__: 'metricName'}\n          if (typeof columnName === 'number') {\n            valueField.config = { ...valueField.config, displayNameFromDS: undefined };\n          }\n\n          // the names of these columns need to be the selected column values, and not be overridden with the display name\n          delete valueField.config.displayName;\n\n          fields.push({\n            name: columnName?.toString() ?? null,\n            values: values,\n            config: valueField.config,\n            type: valueField.type,\n          });\n        }\n\n        return [\n          {\n            fields,\n            length: rowValues.length,\n          },\n        ];\n      })\n    ),\n};\n\nfunction uniqueValues<T>(values: T[]): T[] {\n  const unique = new Set<T>(values);\n  return Array.from(unique);\n}\n\nfunction findKeyField(frame: DataFrame, matchTitle: string): Field | null {\n  for (let fieldIndex = 0; fieldIndex < frame.fields.length; fieldIndex++) {\n    const field = frame.fields[fieldIndex];\n\n    // support for dataplane contract with Prometheus and change in location of field name\n    let matches: boolean;\n    const matcher = fieldMatchers.get(FieldMatcherID.byName).get(matchTitle);\n    matches = matcher(field, frame, [frame]);\n\n    if (matches) {\n      return field;\n    }\n  }\n\n  return null;\n}\n"],"names":["SpecialValue","DataTransformerID","TransformationApplicabilityLevels","map","FieldType","getSpecialValue","fieldMatchers","FieldMatcherID"],"mappings":";;;;;;;;;;;;;AAsBA,MAAM,oBAAA,GAAuB,MAAA;AAC7B,MAAM,iBAAA,GAAoB,MAAA;AAC1B,MAAM,mBAAA,GAAsB,OAAA;AAC5B,MAAM,sBAAsBA,4BAAA,CAAa,KAAA;AAElC,MAAM,2BAAA,GAAuF;AAAA,EAClG,IAAIC,qBAAA,CAAkB,gBAAA;AAAA,EACtB,IAAA,EAAM,oBAAA;AAAA,EACN,WAAA,EAAa,0DAAA;AAAA,EACb,cAAA,EAAgB;AAAA,IACd,WAAA,EAAa,oBAAA;AAAA,IACb,QAAA,EAAU,iBAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACd;AAAA;AAAA;AAAA;AAAA,EAIA,YAAA,EAAc,CAAC,IAAA,KAAsB;AACnC,IAAA,IAAI,SAAA,GAAY,CAAA;AAEhB,IAAA,KAAA,MAAW,SAAS,IAAA,EAAM;AACxB,MAAA,SAAA,IAAa,MAAM,MAAA,CAAO,MAAA;AAAA,IAC5B;AAEA,IAAA,OAAO,SAAA,IAAa,CAAA,GAChBC,iDAAA,CAAkC,UAAA,GAClCA,iDAAA,CAAkC,aAAA;AAAA,EACxC,CAAA;AAAA,EACA,uBAAA,EAAyB,CAAC,IAAA,KAAsB;AAC9C,IAAA,IAAI,SAAA,GAAY,CAAA;AAEhB,IAAA,KAAA,MAAW,SAAS,IAAA,EAAM;AACxB,MAAA,SAAA,IAAa,MAAM,MAAA,CAAO,MAAA;AAAA,IAC5B;AAEA,IAAA,OAAO,8EAA8E,SAAS,CAAA,QAAA,CAAA;AAAA,EAChG,CAAA;AAAA,EACA,UAAU,CAAC,OAAA,EAA6C,GAAA,KAA8B,CAAC,WACrF,MAAA,CAAO,IAAA;AAAA,IACLC,aAAA,CAAI,CAAC,IAAA,KAAS;AA7DpB,MAAA,IAAA,EAAA,EAAA,EAAA;AA8DQ,MAAA,MAAM,gBAAA,GAAmB,QAAQ,WAAA,IAAe,oBAAA;AAChD,MAAA,MAAM,aAAA,GAAgB,QAAQ,QAAA,IAAY,iBAAA;AAC1C,MAAA,MAAM,eAAA,GAAkB,QAAQ,UAAA,IAAc,mBAAA;AAC9C,MAAA,MAAM,UAAA,GAAa,QAAQ,UAAA,IAAc,mBAAA;AAGzC,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,KAAA,GAAQ,KAAK,CAAC,CAAA;AACpB,MAAA,MAAM,cAAA,GAAiB,YAAA,CAAa,KAAA,EAAO,gBAAgB,CAAA;AAC3D,MAAA,MAAM,WAAA,GAAc,YAAA,CAAa,KAAA,EAAO,aAAa,CAAA;AACrD,MAAA,MAAM,UAAA,GAAa,YAAA,CAAa,KAAA,EAAO,eAAe,CAAA;AACtD,MAAA,MAAM,cAAA,GAAiB,CAAA,EAAG,aAAa,CAAA,EAAA,EAAK,gBAAgB,CAAA,CAAA;AAE5D,MAAA,IAAI,CAAC,cAAA,IAAkB,CAAC,WAAA,IAAe,CAAC,UAAA,EAAY;AAClD,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,MAAM,YAAA,GAAe,YAAA,CAAa,cAAA,CAAe,MAAM,CAAA;AACvD,MAAA,MAAM,SAAA,GAAY,YAAA,CAAa,WAAA,CAAY,MAAM,CAAA;AAEjD,MAAA,MAAM,eAA8D,EAAC;AAErE,MAAA,KAAA,IAAS,QAAQ,CAAA,EAAG,KAAA,GAAQ,UAAA,CAAW,MAAA,CAAO,QAAQ,KAAA,EAAA,EAAS;AAC7D,QAAA,MAAM,UAAA,GAAa,cAAA,CAAe,MAAA,CAAO,KAAK,CAAA;AAC9C,QAAA,MAAM,OAAA,GAAU,WAAA,CAAY,MAAA,CAAO,KAAK,CAAA;AACxC,QAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,MAAA,CAAO,KAAK,CAAA;AAErC,QAAA,IAAI,CAAC,YAAA,CAAa,UAAU,CAAA,EAAG;AAC7B,UAAA,YAAA,CAAa,UAAU,IAAI,EAAC;AAAA,QAC9B;AAEA,QAAA,YAAA,CAAa,UAAU,CAAA,CAAE,OAAO,CAAA,GAAI,KAAA;AAAA,MACtC;AAEA,MAAA,MAAM,MAAA,GAAkB;AAAA,QACtB;AAAA,UACE,IAAA,EAAM,cAAA;AAAA,UACN,MAAA,EAAQ,SAAA;AAAA,UACR,MAAM,WAAA,CAAY,IAAA;AAAA,UAClB,MAAA,EAAQ,EAAE,GAAG,WAAA,CAAY,MAAA;AAAO;AAClC,OACF;AAEA,MAAA,KAAA,MAAW,cAAc,YAAA,EAAc;AACrC,QAAA,IAAI,SAAS,EAAC;AACd,QAAA,KAAA,MAAW,WAAW,SAAA,EAAW;AAE/B,UAAA,MAAM,KAAA,GAAA,CACJ,EAAA,GAAA,YAAA,CAAa,UAAU,CAAA,CAAE,OAAO,CAAA,KAAhC,IAAA,GAAA,EAAA,GACC,UAAA,CAAW,IAAA,KAASC,mBAAA,CAAU,KAAA,GAAQ,KAAA,CAAA,GAAYC,sBAAgB,UAAU,CAAA;AAC/E,UAAA,MAAA,CAAO,KAAK,KAAK,CAAA;AAAA,QACnB;AAMA,QAAA,IAAI,OAAO,eAAe,QAAA,EAAU;AAClC,UAAA,UAAA,CAAW,SAAS,EAAE,GAAG,UAAA,CAAW,MAAA,EAAQ,mBAAmB,KAAA,CAAA,EAAU;AAAA,QAC3E;AAGA,QAAA,OAAO,WAAW,MAAA,CAAO,WAAA;AAEzB,QAAA,MAAA,CAAO,IAAA,CAAK;AAAA,UACV,IAAA,EAAA,CAAM,EAAA,GAAA,UAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,UAAA,CAAY,QAAA,EAAA,KAAZ,IAAA,GAAA,EAAA,GAA0B,IAAA;AAAA,UAChC,MAAA;AAAA,UACA,QAAQ,UAAA,CAAW,MAAA;AAAA,UACnB,MAAM,UAAA,CAAW;AAAA,SAClB,CAAA;AAAA,MACH;AAEA,MAAA,OAAO;AAAA,QACL;AAAA,UACE,MAAA;AAAA,UACA,QAAQ,SAAA,CAAU;AAAA;AACpB,OACF;AAAA,IACF,CAAC;AAAA;AAEP;AAEA,SAAS,aAAgB,MAAA,EAAkB;AACzC,EAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAO,MAAM,CAAA;AAChC,EAAA,OAAO,KAAA,CAAM,KAAK,MAAM,CAAA;AAC1B;AAEA,SAAS,YAAA,CAAa,OAAkB,UAAA,EAAkC;AACxE,EAAA,KAAA,IAAS,aAAa,CAAA,EAAG,UAAA,GAAa,KAAA,CAAM,MAAA,CAAO,QAAQ,UAAA,EAAA,EAAc;AACvE,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,MAAA,CAAO,UAAU,CAAA;AAGrC,IAAA,IAAI,OAAA;AACJ,IAAA,MAAM,UAAUC,sBAAA,CAAc,GAAA,CAAIC,qBAAe,MAAM,CAAA,CAAE,IAAI,UAAU,CAAA;AACvE,IAAA,OAAA,GAAU,OAAA,CAAQ,KAAA,EAAO,KAAA,EAAO,CAAC,KAAK,CAAC,CAAA;AAEvC,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;;;;"}