UNPKG

virool-pivot

Version:

A web-based exploratory visualization UI for Druid.io

121 lines (105 loc) 3.26 kB
import * as numeral from 'numeral'; import { NumberRange } from 'plywood'; import { Dimension, FilterClause, Essence } from '../../models/index'; import { DisplayYear, formatTimeRange } from '../../utils/time/time'; export interface Formatter { (n: number): string; } var scales: Lookup<Lookup<number>> = { 'a': { '': 1, 'k': 1e3, 'm': 1e6, 'b': 1e9, 't': 1e12 }, 'b': { 'B': 1, 'KB': 1024, 'MB': 1024 * 1024, 'GB': 1024 * 1024 * 1024, 'TB': 1024 * 1024 * 1024 * 1024, 'PB': 1024 * 1024 * 1024 * 1024 * 1024, 'EB': 1024 * 1024 * 1024 * 1024 * 1024 * 1024, 'ZB': 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024, 'YB': 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 } }; export function getMiddleNumber(values: number[]): number { var filteredAbsData: number[] = []; for (var v of values) { if (v === 0 || isNaN(v) || !isFinite(v)) continue; filteredAbsData.push(Math.abs(v)); } var n = filteredAbsData.length; if (n) { filteredAbsData.sort((a, b) => b - a); return filteredAbsData[Math.ceil((n - 1) / 2)]; } else { return 0; } } export function formatterFromData(values: number[], format: string): Formatter { var match = format.match(/^(\S*)( ?)([ab])$/); if (match) { var numberFormat = match[1]; var space = match[2]; var formatType = match[3]; var middle = getMiddleNumber(values); var formatMiddle = numeral(middle).format('0 ' + formatType); var unit = formatMiddle.split(' ')[1] || ''; var scale = scales[formatType][unit]; var append = unit ? space + unit : ''; return (n: number) => { if (isNaN(n) || !isFinite(n)) return '-'; return numeral(n / scale).format(numberFormat) + append; }; } else { return (n: number) => { if (isNaN(n) || !isFinite(n)) return '-'; return numeral(n).format(format); }; } } export function formatValue(value: any): string { if (NumberRange.isNumberRange(value)) { return `${formatValue(value.start)}-${formatValue(value.end)}`; } else { return '' + value; } } export interface LabelFormatOptions { dimension: Dimension; clause: FilterClause; essence: Essence; verbose?: boolean; } export function formatFilterClause(options: LabelFormatOptions): string { const { dimension, clause, essence, verbose } = options; // ToDo: get essence out of here var label = dimension.title; switch (dimension.kind) { case 'boolean': case 'number': case 'string': if (verbose) { label += `: ${clause.getLiteralSet().toString()}`; } else { var setElements = clause.getLiteralSet().elements; label += setElements.length > 1 ? ` (${setElements.length})` : `: ${formatValue(setElements[0])}`; } break; case 'time': var timeSelection = clause.selection; var timeRange = essence.evaluateSelection(timeSelection); if (verbose) { label += `: ${formatTimeRange(timeRange, essence.timezone, DisplayYear.IF_DIFF)}`; } else { label = formatTimeRange(timeRange, essence.timezone, DisplayYear.IF_DIFF); } break; default: throw new Error(`unknown kind ${dimension.kind}`); } return label; }