turnilo
Version:
Business intelligence, data exploration and visualization web application for Druid, formerly known as Swiv and Pivot
244 lines • 9.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const chronoshift_1 = require("chronoshift");
const constants_1 = require("../../../client/config/constants");
const general_1 = require("../../utils/general/general");
const duration_1 = require("../../utils/plywood/duration");
const MENU_LENGTH = 5;
function validateGranularity(kind, granularity) {
if (kind === "time") {
if (!duration_1.isValidDuration(granularity)) {
return constants_1.STRINGS.invalidDurationFormat;
}
if (!duration_1.isFloorableDuration(granularity)) {
return constants_1.STRINGS.notFloorableDuration;
}
}
if (kind === "number" && !general_1.isDecimalInteger(granularity)) {
return constants_1.STRINGS.invalidNumberFormat;
}
return null;
}
exports.validateGranularity = validateGranularity;
function isGranularityValid(kind, granularity) {
return validateGranularity(kind, granularity) === null;
}
exports.isGranularityValid = isGranularityValid;
function makeCheckpoint(checkPoint, returnValue) {
return { checkPoint, returnValue };
}
function makeNumberBuckets(centerAround, count, coarse) {
const granularities = [];
let logTen = Math.log(centerAround) / Math.LN10;
const digits = general_1.getNumberOfWholeDigits(centerAround);
const decimalBase = 10;
while (granularities.length <= count) {
if (!coarse) {
const halfStep = general_1.toSignificantDigits(5 * Math.pow(decimalBase, logTen - 1), digits);
granularities.push(halfStep);
}
if (granularities.length >= count)
break;
const wholeStep = general_1.toSignificantDigits(Math.pow(decimalBase, logTen), digits);
granularities.push(wholeStep);
logTen++;
}
return granularities;
}
function days(count) {
return count * chronoshift_1.day.canonicalLength;
}
function hours(count) {
return count * chronoshift_1.hour.canonicalLength;
}
function minutes(count) {
return count * chronoshift_1.minute.canonicalLength;
}
class TimeHelper {
}
exports.TimeHelper = TimeHelper;
TimeHelper.dimensionKind = "time";
TimeHelper.minGranularity = chronoshift_1.Duration.fromJS("PT1M");
TimeHelper.defaultGranularity = chronoshift_1.Duration.fromJS("P1D");
TimeHelper.supportedGranularities = (_) => {
return [
"PT1S", "PT1M", "PT5M", "PT15M",
"PT1H", "PT6H", "PT8H", "PT12H",
"P1D", "P1W", "P1M", "P3M", "P6M",
"P1Y", "P2Y"
].map(duration => chronoshift_1.Duration.fromJS(duration));
};
TimeHelper.checkers = [
makeCheckpoint(days(95), chronoshift_1.Duration.fromJS("P1W")),
makeCheckpoint(days(8), chronoshift_1.Duration.fromJS("P1D")),
makeCheckpoint(hours(8), chronoshift_1.Duration.fromJS("PT1H")),
makeCheckpoint(hours(3), chronoshift_1.Duration.fromJS("PT5M"))
];
TimeHelper.coarseCheckers = [
makeCheckpoint(days(95), chronoshift_1.Duration.fromJS("P1M")),
makeCheckpoint(days(20), chronoshift_1.Duration.fromJS("P1W")),
makeCheckpoint(days(6), chronoshift_1.Duration.fromJS("P1D")),
makeCheckpoint(days(2), chronoshift_1.Duration.fromJS("PT12H")),
makeCheckpoint(hours(23), chronoshift_1.Duration.fromJS("PT6H")),
makeCheckpoint(hours(3), chronoshift_1.Duration.fromJS("PT1H")),
makeCheckpoint(minutes(30), chronoshift_1.Duration.fromJS("PT5M"))
];
TimeHelper.defaultGranularities = TimeHelper.checkers.map(c => c.returnValue).concat(TimeHelper.minGranularity).reverse();
TimeHelper.coarseGranularities = TimeHelper.coarseCheckers.map(c => c.returnValue).concat(TimeHelper.minGranularity).reverse();
class NumberHelper {
}
exports.NumberHelper = NumberHelper;
NumberHelper.dimensionKind = "number";
NumberHelper.minGranularity = 1;
NumberHelper.defaultGranularity = 10;
NumberHelper.checkers = [
makeCheckpoint(5000, 1000),
makeCheckpoint(500, 100),
makeCheckpoint(100, 10),
makeCheckpoint(1, 1),
makeCheckpoint(0.1, 0.1)
];
NumberHelper.defaultGranularities = NumberHelper.checkers.map((c) => c.returnValue).reverse();
NumberHelper.coarseGranularities = null;
NumberHelper.coarseCheckers = [
makeCheckpoint(500000, 50000),
makeCheckpoint(50000, 10000),
makeCheckpoint(5000, 5000),
makeCheckpoint(1000, 1000),
makeCheckpoint(100, 100),
makeCheckpoint(10, 10),
makeCheckpoint(1, 1),
makeCheckpoint(0.1, 0.1)
];
NumberHelper.supportedGranularities = (bucketedBy) => {
return makeNumberBuckets(getBucketSize(bucketedBy), 10);
};
function getHelperForKind(kind) {
if (kind === "time")
return TimeHelper;
return NumberHelper;
}
function getHelperForRange({ start }) {
if (start instanceof Date)
return TimeHelper;
return NumberHelper;
}
function getBucketSize(input) {
if (input instanceof chronoshift_1.Duration)
return input.getCanonicalLength();
if (typeof input === "number")
return input;
throw new Error(`unrecognized granularity: ${input} must be number or Duration`);
}
function startValue({ start }) {
return start instanceof Date ? start.valueOf() : start;
}
function endValue({ end }) {
return end instanceof Date ? end.valueOf() : end;
}
function findBestMatch(array, target) {
const exactMatch = general_1.findExactIndex(array, target, getBucketSize);
if (exactMatch !== -1) {
return array[exactMatch];
}
const minBiggerIdx = general_1.findFirstBiggerIndex(array, target, getBucketSize);
if (minBiggerIdx !== -1) {
return array[minBiggerIdx];
}
return array[general_1.findMaxValueIndex(array, getBucketSize)];
}
function generateGranularitySet(allGranularities, bucketedBy) {
const start = general_1.findFirstBiggerIndex(allGranularities, bucketedBy, getBucketSize);
const returnGranularities = allGranularities.slice(start, start + MENU_LENGTH);
if (general_1.findExactIndex(returnGranularities, bucketedBy, getBucketSize) === -1) {
return [bucketedBy].concat(returnGranularities.slice(0, returnGranularities.length - 1));
}
return returnGranularities;
}
function granularityFromJS(input) {
if (typeof input === "number")
return input;
if (duration_1.isValidDuration(input))
return chronoshift_1.Duration.fromJS(input);
throw new Error("input should be number or Duration");
}
exports.granularityFromJS = granularityFromJS;
function coerceGranularity(granularity, kind) {
switch (kind) {
case "string":
return null;
case "boolean":
return null;
case "time":
return chronoshift_1.Duration.fromJS(granularity);
case "number":
return parseInt(granularity, 10);
}
}
exports.coerceGranularity = coerceGranularity;
function granularityToString(input) {
return input.toString();
}
exports.granularityToString = granularityToString;
function formatGranularity(bucket) {
if (bucket instanceof chronoshift_1.Duration) {
return `${bucket.getSingleSpanValue()}${bucket.getSingleSpan().charAt(0).toUpperCase()}`;
}
return bucket.toString();
}
exports.formatGranularity = formatGranularity;
function granularityEquals(g1, g2) {
if (g1 instanceof chronoshift_1.Duration) {
try {
return g1.equals(g2);
}
catch (_a) {
return false;
}
}
return g1 === g2;
}
exports.granularityEquals = granularityEquals;
function getGranularities(kind, bucketedBy, coarse) {
const kindHelper = getHelperForKind(kind);
const coarseGranularities = kindHelper.coarseGranularities;
if (!bucketedBy)
return coarse && coarseGranularities ? coarseGranularities : kindHelper.defaultGranularities;
const allGranularities = kindHelper.supportedGranularities(bucketedBy);
return generateGranularitySet(allGranularities, bucketedBy);
}
exports.getGranularities = getGranularities;
function getDefaultGranularityForKind(kind, bucketedBy, customGranularities) {
if (bucketedBy)
return bucketedBy;
if (customGranularities)
return customGranularities[2];
return getHelperForKind(kind).defaultGranularity;
}
exports.getDefaultGranularityForKind = getDefaultGranularityForKind;
function getBestBucketUnitForRange(inputRange, bigChecker, bucketedBy, customGranularities) {
const rangeLength = Math.abs(endValue(inputRange) - startValue(inputRange));
const rangeHelper = getHelperForRange(inputRange);
const bucketLength = bucketedBy ? getBucketSize(bucketedBy) : 0;
const checkPoints = bigChecker && rangeHelper.coarseCheckers ? rangeHelper.coarseCheckers : rangeHelper.checkers;
for (const { checkPoint, returnValue } of checkPoints) {
if (rangeLength > checkPoint || bucketLength > checkPoint) {
if (bucketedBy) {
const granArray = customGranularities || getGranularities(rangeHelper.dimensionKind, bucketedBy);
const closest = general_1.findBiggerClosestToIdeal(granArray, bucketedBy, returnValue, getBucketSize);
if (closest === null)
return rangeHelper.defaultGranularity;
return closest;
}
else {
if (!customGranularities)
return returnValue;
return findBestMatch(customGranularities, returnValue);
}
}
}
const minBucket = customGranularities ? customGranularities[general_1.findMinValueIndex(customGranularities, getBucketSize)] : rangeHelper.minGranularity;
return bucketLength > getBucketSize(minBucket) ? bucketedBy : minBucket;
}
exports.getBestBucketUnitForRange = getBestBucketUnitForRange;
//# sourceMappingURL=granularity.js.map