{"version":3,"file":"UPlotAxisBuilder.mjs","sources":["../../../../../src/components/uPlot/config/UPlotAxisBuilder.ts"],"sourcesContent":["import uPlot, { Axis } from 'uplot';\n\nimport {\n  dateTimeFormat,\n  DecimalCount,\n  GrafanaTheme2,\n  guessDecimals,\n  isBooleanUnit,\n  roundDecimals,\n  systemDateFormats,\n  TimeZone,\n} from '@grafana/data';\nimport { AxisPlacement, ScaleDistribution } from '@grafana/schema';\n\nimport { measureText } from '../../../utils/measureText';\nimport { PlotConfigBuilder } from '../types';\n\nimport { optMinMax } from './UPlotScaleBuilder';\n\nexport interface AxisProps {\n  scaleKey: string;\n  theme: GrafanaTheme2;\n  label?: string;\n  show?: boolean;\n  size?: number | null;\n  gap?: number;\n  tickLabelRotation?: number;\n  placement?: AxisPlacement;\n  grid?: Axis.Grid;\n  ticks?: Axis.Ticks;\n  filter?: Axis.Filter;\n  space?: Axis.Space;\n  formatValue?: (v: any, decimals?: DecimalCount) => string;\n  incrs?: Axis.Incrs;\n  splits?: Axis.Splits;\n  values?: Axis.Values;\n  isTime?: boolean;\n  timeZone?: TimeZone;\n  color?: uPlot.Axis.Stroke;\n  border?: uPlot.Axis.Border;\n  decimals?: DecimalCount;\n  distr?: ScaleDistribution;\n}\n\nexport const UPLOT_AXIS_FONT_SIZE = 12;\n\n// for panels with small heights, we increase tick density by reducing the minumum tick spacing\n// all values in CSS pixels\nconst Y_TICK_SPACING_PANEL_HEIGHT = 150;\nconst Y_TICK_SPACING_NORMAL = 30;\nconst Y_TICK_SPACING_SMALL = 15;\n\nconst X_TICK_SPACING_NORMAL = 40;\nconst X_TICK_VALUE_GAP = 18;\n\nconst labelPad = 8;\n\nexport class UPlotAxisBuilder extends PlotConfigBuilder<AxisProps, Axis> {\n  merge(props: AxisProps) {\n    this.props.size = optMinMax('max', this.props.size, props.size);\n    if (!this.props.label) {\n      this.props.label = props.label;\n    }\n    if (this.props.placement === AxisPlacement.Auto) {\n      this.props.placement = props.placement;\n    }\n  }\n\n  getConfig(): Axis {\n    let {\n      scaleKey,\n      label,\n      show = true,\n      placement = AxisPlacement.Auto,\n      grid = { show: true },\n      ticks,\n      space,\n      filter,\n      gap = 5,\n      formatValue,\n      splits,\n      values,\n      incrs,\n      isTime,\n      timeZone,\n      theme,\n      tickLabelRotation,\n      size,\n      color,\n      border,\n      decimals,\n      distr = ScaleDistribution.Linear,\n    } = this.props;\n\n    const font = `${UPLOT_AXIS_FONT_SIZE}px ${theme.typography.fontFamily}`;\n\n    const gridColor = theme.isDark ? 'rgba(240, 250, 255, 0.09)' : 'rgba(0, 10, 23, 0.09)';\n\n    // TODO: this is pretty flimsy now that scaleKey is composed from multiple parts :/\n    if (isBooleanUnit(scaleKey)) {\n      splits = [0, 1];\n    }\n\n    if (decimals === 0 && distr === ScaleDistribution.Linear) {\n      filter = (u, splits) => splits.map((v) => (Number.isInteger(v) ? v : null));\n    }\n\n    let config: Axis = {\n      scale: scaleKey,\n      show,\n      stroke: color ?? theme.colors.text.primary,\n      side: getUPlotSideFromAxis(placement),\n      font,\n      size:\n        size ??\n        ((self, values, axisIdx) => {\n          return calculateAxisSize(self, values, axisIdx);\n        }),\n      rotate: tickLabelRotation,\n      gap,\n\n      labelGap: 0,\n\n      grid: {\n        show: grid.show,\n        stroke: gridColor,\n        width: 1 / devicePixelRatio,\n      },\n      ticks: Object.assign(\n        {\n          show: true,\n          stroke: border?.show ? (color ?? theme.colors.text.primary) : gridColor,\n          width: 1 / devicePixelRatio,\n          size: 4,\n        },\n        ticks\n      ),\n      splits,\n      values,\n      space:\n        space ??\n        ((self, axisIdx, scaleMin, scaleMax, plotDim) => {\n          return calculateSpace(self, axisIdx, scaleMin, scaleMax, plotDim, formatValue);\n        }),\n      filter,\n      incrs,\n    };\n\n    if (border?.show) {\n      config.border = {\n        stroke: color ?? theme.colors.text.primary,\n        width: 1 / devicePixelRatio,\n        ...border,\n      };\n    }\n\n    if (label != null && label.length > 0) {\n      config.label = label;\n      config.labelSize = UPLOT_AXIS_FONT_SIZE + labelPad;\n      config.labelFont = font;\n      config.labelGap = labelPad;\n    }\n\n    if (values) {\n      config.values = values;\n    } else if (isTime) {\n      config.values = formatTime;\n    } else if (formatValue) {\n      config.values = (u: uPlot, splits, axisIdx, tickSpace, tickIncr) => {\n        let decimals = guessDecimals(roundDecimals(tickIncr, 6));\n        return splits.map((v) => {\n          if (v == null) {\n            return null;\n          } else {\n            return formatValue!(v, decimals > 0 ? decimals : undefined);\n          }\n        });\n      };\n    }\n\n    // store timezone\n    (config as any).timeZone = timeZone;\n\n    return config;\n  }\n}\n\n/** @internal */\nexport const timeUnitSize = {\n  second: 1000,\n  minute: 60 * 1000,\n  hour: 60 * 60 * 1000,\n  day: 24 * 60 * 60 * 1000,\n  month: 28 * 24 * 60 * 60 * 1000,\n  year: 365 * 24 * 60 * 60 * 1000,\n};\n\n/** Format time axis ticks */\nexport function formatTime(\n  self: uPlot,\n  splits: number[],\n  axisIdx: number,\n  foundSpace: number,\n  foundIncr: number\n): string[] {\n  const axis = self.axes[axisIdx];\n  const timeZone = 'timeZone' in axis && typeof axis.timeZone === 'string' ? axis.timeZone : undefined;\n  const scale = self.scales.x;\n  const range = (scale?.max ?? 0) - (scale?.min ?? 0);\n  const yearRoundedToDay = Math.round(timeUnitSize.year / timeUnitSize.day) * timeUnitSize.day;\n  const incrementRoundedToDay = Math.round(foundIncr / timeUnitSize.day) * timeUnitSize.day;\n\n  let format = systemDateFormats.interval.year;\n\n  if (foundIncr < timeUnitSize.second) {\n    format = systemDateFormats.interval.millisecond;\n  } else if (foundIncr <= timeUnitSize.minute) {\n    format = systemDateFormats.interval.second;\n  } else if (range <= timeUnitSize.day) {\n    format = systemDateFormats.interval.minute;\n  } else if (foundIncr <= timeUnitSize.day) {\n    format = systemDateFormats.interval.hour;\n  } else if (range < timeUnitSize.year) {\n    format = systemDateFormats.interval.day;\n  } else if (incrementRoundedToDay === yearRoundedToDay) {\n    format = systemDateFormats.interval.year;\n  } else if (foundIncr <= timeUnitSize.year) {\n    format = systemDateFormats.interval.month;\n  }\n\n  return splits.map((v) => (v == null ? '' : dateTimeFormat(v, { format, timeZone })));\n}\n\n/* Minimum grid & tick spacing in CSS pixels */\nfunction calculateSpace(\n  self: uPlot,\n  axisIdx: number,\n  scaleMin: number,\n  scaleMax: number,\n  plotDim: number,\n  formatValue?: (value: unknown) => string\n): number {\n  const axis = self.axes[axisIdx];\n  const scale = self.scales[axis.scale!];\n\n  // for axis left & right\n  if (axis.side !== 2 || !scale) {\n    return plotDim <= Y_TICK_SPACING_PANEL_HEIGHT ? Y_TICK_SPACING_SMALL : Y_TICK_SPACING_NORMAL;\n  }\n\n  const maxTicks = plotDim / X_TICK_SPACING_NORMAL;\n  const increment = (scaleMax - scaleMin) / maxTicks;\n\n  // not super great, since 0.000005 has many more chars than 1.0\n  // it also doesn't work well with \"short\" or adaptive units, e.g. 7 K and 6.40 K\n  const bigValue = Math.max(Math.abs(scaleMin), Math.abs(scaleMax));\n\n  let sample = '';\n\n  if (scale.time) {\n    sample = formatTime(self, [bigValue], axisIdx, X_TICK_SPACING_NORMAL, increment)[0];\n  } else if (formatValue != null) {\n    sample = formatValue(bigValue);\n  } else {\n    return X_TICK_SPACING_NORMAL;\n  }\n\n  const valueWidth = measureText(sample, UPLOT_AXIS_FONT_SIZE).width;\n\n  return valueWidth + X_TICK_VALUE_GAP;\n}\n\n/** height of x axis or width of y axis in CSS pixels alloted for values, gap & ticks, but excluding axis label */\nfunction calculateAxisSize(self: uPlot, values: string[], axisIdx: number) {\n  const axis = self.axes[axisIdx];\n\n  let axisSize = axis.ticks!.size!;\n\n  if (axis.side === 2) {\n    axisSize += axis!.gap! + UPLOT_AXIS_FONT_SIZE;\n  } else if (values?.length) {\n    let maxTextWidth = values.reduce((acc, value) => Math.max(acc, measureText(value, UPLOT_AXIS_FONT_SIZE).width), 0);\n    // limit y tick label width to 40% of visualization\n    const textWidthWithLimit = Math.min(self.width * 0.4, maxTextWidth);\n    // Not sure why this += and not normal assignment\n    axisSize += axis!.gap! + axis!.labelGap! + textWidthWithLimit;\n  }\n\n  return Math.ceil(axisSize);\n}\n\nexport function getUPlotSideFromAxis(axis: AxisPlacement) {\n  switch (axis) {\n    case AxisPlacement.Top:\n      return 0;\n    case AxisPlacement.Right:\n      return 1;\n    case AxisPlacement.Bottom:\n      return 2;\n    case AxisPlacement.Left:\n  }\n\n  return 3; // default everythign to the left\n}\n"],"names":["splits","values","decimals"],"mappings":"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"}