{"version":3,"file":"UPlotScaleBuilder.mjs","sources":["../../../../../src/components/uPlot/config/UPlotScaleBuilder.ts"],"sourcesContent":["import uPlot, { Scale, Range } from 'uplot';\n\nimport { DecimalCount, incrRoundDn, incrRoundUp, isBooleanUnit } from '@grafana/data';\nimport { ScaleOrientation, ScaleDirection, ScaleDistribution, StackingMode } from '@grafana/schema';\n\nimport { PlotConfigBuilder } from '../types';\n\nexport interface ScaleProps {\n  scaleKey: string;\n  isTime?: boolean;\n  min?: number | null;\n  max?: number | null;\n  softMin?: number | null;\n  softMax?: number | null;\n  range?: Scale.Range;\n  distribution?: ScaleDistribution;\n  orientation: ScaleOrientation;\n  direction: ScaleDirection;\n  log?: number;\n  linearThreshold?: number;\n  centeredZero?: boolean;\n  decimals?: DecimalCount;\n  stackingMode?: StackingMode;\n}\n\nexport class UPlotScaleBuilder extends PlotConfigBuilder<ScaleProps, Scale> {\n  merge(props: ScaleProps) {\n    this.props.min = optMinMax('min', this.props.min, props.min);\n    this.props.max = optMinMax('max', this.props.max, props.max);\n  }\n\n  getConfig(): Scale {\n    let {\n      isTime,\n      scaleKey,\n      min: hardMin,\n      max: hardMax,\n      softMin,\n      softMax,\n      range,\n      direction,\n      orientation,\n      centeredZero,\n      decimals,\n      stackingMode,\n    } = this.props;\n\n    if (stackingMode === StackingMode.Percent) {\n      if (hardMin == null && softMin == null) {\n        softMin = 0;\n      }\n\n      if (hardMax == null && softMax == null) {\n        softMax = 1;\n      }\n    }\n\n    const distr = this.props.distribution;\n\n    const distribution = !isTime\n      ? {\n          distr:\n            distr === ScaleDistribution.Symlog\n              ? 4\n              : distr === ScaleDistribution.Log\n                ? 3\n                : distr === ScaleDistribution.Ordinal\n                  ? 2\n                  : 1,\n          log:\n            distr === ScaleDistribution.Log || distr === ScaleDistribution.Symlog ? (this.props.log ?? 2) : undefined,\n          asinh: distr === ScaleDistribution.Symlog ? (this.props.linearThreshold ?? 1) : undefined,\n        }\n      : {};\n\n    // guard against invalid log scale limits <= 0, or snap to log boundaries\n    if (distr === ScaleDistribution.Log) {\n      let logBase = this.props.log!;\n      let logFn = logBase === 2 ? Math.log2 : Math.log10;\n\n      if (hardMin != null) {\n        if (hardMin <= 0) {\n          hardMin = null;\n        } else {\n          hardMin = logBase ** Math.floor(logFn(hardMin));\n        }\n      }\n\n      if (hardMax != null) {\n        if (hardMax <= 0) {\n          hardMax = null;\n        } else {\n          hardMax = logBase ** Math.ceil(logFn(hardMax));\n        }\n      }\n\n      if (softMin != null) {\n        if (softMin <= 0) {\n          softMin = null;\n        } else {\n          softMin = logBase ** Math.floor(logFn(softMin));\n        }\n      }\n\n      if (softMax != null) {\n        if (softMax <= 0) {\n          softMax = null;\n        } else {\n          softMax = logBase ** Math.ceil(logFn(softMax));\n        }\n      }\n    }\n    /*\n    // snap to symlog boundaries\n    else if (distr === ScaleDistribution.Symlog) {\n      let logBase = this.props.log!;\n      let logFn = logBase === 2 ? Math.log2 : Math.log10;\n\n      let sign = Math.sign(hardMin);\n\n      if (hardMin != null) {\n        hardMin = logBase ** Math.floor(logFn(hardMin));\n      }\n\n      if (hardMax != null) {\n        hardMax = logBase ** Math.ceil(logFn(hardMax));\n      }\n\n      if (softMin != null) {\n        softMin = logBase ** Math.floor(logFn(softMin));\n      }\n\n      if (softMax != null) {\n        softMax = logBase ** Math.ceil(logFn(softMax));\n      }\n    }\n    */\n\n    // uPlot's default ranging config for both min & max is {pad: 0.1, hard: null, soft: 0, mode: 3}\n    let softMinMode: Range.SoftMode = softMin == null ? 3 : 1;\n    let softMaxMode: Range.SoftMode = softMax == null ? 3 : 1;\n\n    const rangeConfig: Range.Config = {\n      min: {\n        pad: 0.1,\n        hard: hardMin ?? -Infinity,\n        soft: softMin || 0,\n        mode: softMinMode,\n      },\n      max: {\n        pad: 0.1,\n        hard: hardMax ?? Infinity,\n        soft: softMax || 0,\n        mode: softMaxMode,\n      },\n    };\n\n    let hardMinOnly = softMin == null && hardMin != null;\n    let hardMaxOnly = softMax == null && hardMax != null;\n    let hasFixedRange = hardMinOnly && hardMaxOnly;\n\n    const rangeFn: uPlot.Range.Function = (\n      u: uPlot,\n      dataMin: number | null,\n      dataMax: number | null,\n      scaleKey: string\n    ) => {\n      const scale = u.scales[scaleKey];\n\n      let minMax: uPlot.Range.MinMax = [dataMin, dataMax];\n\n      // happens when all series on a scale are `show: false`, re-returning nulls will auto-disable axis\n      if (!hasFixedRange && dataMin == null && dataMax == null) {\n        return minMax;\n      }\n\n      let logBase = scale.log ?? 10;\n\n      if (scale.distr === 1 || scale.distr === 2 || scale.distr === 4) {\n        if (centeredZero) {\n          let absMin = Math.abs(dataMin!);\n          let absMax = Math.abs(dataMax!);\n          let max = Math.max(absMin, absMax);\n\n          // flat 0\n          if (max === 0) {\n            max = 80;\n          }\n\n          dataMin = -max;\n          dataMax = max;\n        }\n\n        if (scale.distr === 4) {\n          minMax = uPlot.rangeAsinh(dataMin!, dataMax!, logBase, true);\n        } else {\n          // @ts-ignore here we may use hardMin / hardMax to make sure any extra padding is computed from a more accurate delta\n          minMax = uPlot.rangeNum(hardMinOnly ? hardMin : dataMin, hardMaxOnly ? hardMax : dataMax, rangeConfig);\n        }\n      } else if (scale.distr === 3) {\n        minMax = uPlot.rangeLog(hardMin ?? dataMin!, hardMax ?? dataMax!, logBase, true);\n      }\n\n      if (decimals === 0) {\n        if (scale.distr === 1 || scale.distr === 2) {\n          minMax[0] = incrRoundDn(minMax[0]!, 1);\n          minMax[1] = incrRoundUp(minMax[1]!, 1);\n        }\n        // log2 or log10 scale min must be clamped to 1\n        else if (scale.distr === 3) {\n          let logFn = scale.log === 2 ? Math.log2 : Math.log10;\n\n          if (minMax[0]! <= 1) {\n            // clamp min\n            minMax[0] = 1;\n          } else {\n            // snap min to nearest mag below\n            let minExp = Math.floor(logFn(minMax[0]!));\n            minMax[0] = logBase ** minExp;\n          }\n\n          // snap max to nearest mag above\n          let maxExp = Math.ceil(logFn(minMax[1]!));\n          minMax[1] = logBase ** maxExp;\n\n          // inflate max by mag if same\n          if (minMax[0] === minMax[1]) {\n            minMax[1] *= logBase;\n          }\n        }\n        // TODO: this should be better. symlog values can be <= 0, but should also be snapped to log2 or log10 boundaries\n        // for now we just do same as linear snapping above, so may have non-neat range and ticks at edges\n        else if (scale.distr === 4) {\n          minMax[0] = incrRoundDn(minMax[0]!, 1);\n          minMax[1] = incrRoundUp(minMax[1]!, 1);\n        }\n      }\n\n      if (scale.distr === 1 || scale.distr === 4) {\n        // if all we got were hard limits, treat them as static min/max\n        if (hardMinOnly) {\n          minMax[0] = hardMin!;\n        }\n\n        if (hardMaxOnly) {\n          minMax[1] = hardMax!;\n        }\n      }\n\n      // guard against invalid y ranges\n      if (minMax[0]! >= minMax[1]!) {\n        minMax[0] = scale.distr === 3 ? 1 : 0;\n        minMax[1] = 100;\n      }\n\n      return minMax;\n    };\n\n    let auto = !isTime && !hasFixedRange;\n\n    if (isBooleanUnit(scaleKey)) {\n      auto = false;\n      range = [0, 1];\n    }\n\n    return {\n      [scaleKey]: {\n        time: isTime,\n        auto,\n        range: range ?? rangeFn,\n        dir: direction,\n        ori: orientation,\n        ...distribution,\n      },\n    };\n  }\n}\n\nexport function optMinMax(minmax: 'min' | 'max', a?: number | null, b?: number | null): undefined | number | null {\n  const hasA = !(a === undefined || a === null);\n  const hasB = !(b === undefined || b === null);\n  if (hasA) {\n    if (!hasB) {\n      return a;\n    }\n    if (minmax === 'min') {\n      return a! < b! ? a : b;\n    }\n    return a! > b! ? a : b;\n  }\n  return b;\n}\n"],"names":["scaleKey","_a"],"mappings":"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"}