UNPKG

@skydive-project/skydive-ui

Version:
248 lines (199 loc) 6.72 kB
/* * Copyright (C) 2019 Sylvain Afchain * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import { GoogleChartWrapperChartType } from 'react-google-charts/dist/types' export interface Graph { type: GoogleChartWrapperChartType data: Array<Array<any>> } export interface Column { name: string options: { filterList: Array<any> display: string } } interface Row { entries: Map<string, any> details: any } export class Result { private _columns: Array<Column> private _rows: Array<Row> graph?: Graph private colIndexes: Map<string, number> constructor() { this._columns = new Array<Column>() this._rows = new Array<Row>() this.colIndexes = new Map<string, number>() } addColumn(name: string) { let index = this.colIndexes.get(name) if (index === undefined) { this.colIndexes.set(name, this._columns.length) this._columns.push({ "name": name, options: { filterList: new Array<any>(), display: 'true' } }) } } columnIndex(name: string): number | undefined { return this.colIndexes.get(name) } newRow(): Row { return { entries: new Map<string, any>(), details: null } } addRow(row: Row) { if (row.entries.size) { for (let key of row.entries.keys()) { this.addColumn(key) } this._rows.push(row) } } // sort only if the format in key-value sortRowsByKeys(keys: Array<string>) { if (this._columns.length === 2 && this._columns[0].name === "Key") { this._rows = this._rows.sort((a, b) => { var ka = a.entries.get("Key"), kb = b.entries.get("Key") var ia = keys.indexOf(ka), ib = keys.indexOf(kb) if (ia === ib) return ka.localeCompare(kb) // -1 == -1 if (ia === -1) return 1 if (ib === -1) return -1 return ia - ib }) } } get rows(): Array<Array<any>> { var rows = new Array<Array<any>>() for (let row of this._rows) { let plain = new Array<any>() for (let i = 0; i != this.colIndexes.size; i++) { plain[i] = "" } row.entries.forEach((value, key) => { var index = this.columnIndex(key) if (index === undefined) { return } plain[index] = value }) rows.push(plain) } return rows } get details(): Map<number, any> { var details = new Map<number, any>() this._rows.forEach((row, index) => { if (row.details) { details.set(index, row.details) } }) return details } get columns(): Array<Column> { return this._columns } } export class DataNormalizer { normalizer: ((any) => any) | null graph: ((any) => Graph) | null exclude: Array<string> | null sortKeys: Array<string> | null constructor(normalizer?: (data: any) => any, graph?: ((data: any) => Graph), exclude?: Array<string>, sortKeys?: Array<string>) { this.normalizer = normalizer || null this.graph = graph || null this.exclude = exclude || [] this.sortKeys = sortKeys || [] } private normalizeMap(data: any, result: Result) { for (let attr in data) { if (this.exclude && this.exclude.includes(attr)) { continue } let row = result.newRow() let value = data[attr] switch (typeof value) { case "object": row.entries.set("Key", attr) row.entries.set("Value", "") row.details = value break case "boolean": row.entries.set("Key", attr) row.entries.set("Value", value ? "true" : "false") break default: row.entries.set("Key", attr) row.entries.set("Value", value) break } result.addRow(row) } return result } private normalizeScalarArray(data: any, result: Result) { for (let value of data) { let row = result.newRow() if (typeof value === "boolean") { row.entries.set("Value", value ? "true" : "false") } else { row.entries.set("Value", value) } result.addRow(row) } return result } private normalizeObjectArray(data: any, result: Result) { for (let value of data) { let row = result.newRow() for (let attr in value) { var type = typeof value[attr] if (type === "boolean") { row.entries.set(attr, value ? "true" : "false") } if (type === "string" || type === "number") { row.entries.set(attr, value[attr] === null ? "" : value[attr]) } } result.addRow(row) } return result } private normalizeArray(data: any, result: Result) { if ((data as Array<any>).some(value => typeof value === "object")) { return this.normalizeObjectArray(data, result) } this.normalizeScalarArray(data, result) } private normalizeData(data: any, result: Result) { if (Array.isArray(data)) { this.normalizeArray(data, result) } else if (typeof data === "object") { this.normalizeMap(data, result) } } normalize(data: any): Result { var result = new Result() if (this.graph) { result.graph = this.graph(data) } if (this.normalizer) { data = this.normalizer(data) } this.normalizeData(data, result) if (this.sortKeys) { result.sortRowsByKeys(this.sortKeys) } return result } }