{"version":3,"file":"Gauge.mjs","sources":["../../../../src/components/Gauge/Gauge.tsx"],"sourcesContent":["import $ from 'jquery';\nimport { PureComponent } from 'react';\nimport * as React from 'react';\n\nimport {\n  DisplayValue,\n  formattedValueToString,\n  FieldConfig,\n  ThresholdsMode,\n  GAUGE_DEFAULT_MAXIMUM,\n  GAUGE_DEFAULT_MINIMUM,\n  GrafanaTheme2,\n} from '@grafana/data';\nimport { VizTextDisplayOptions, VizOrientation } from '@grafana/schema';\n\nimport { calculateFontSize } from '../../utils/measureText';\nimport { clearButtonStyles } from '../Button/Button';\n\nimport { calculateGaugeAutoProps, DEFAULT_THRESHOLDS, getFormattedThresholds } from './utils';\n\nexport interface Props {\n  height: number;\n  field: FieldConfig;\n  showThresholdMarkers: boolean;\n  showThresholdLabels: boolean;\n  width: number;\n  value: DisplayValue;\n  text?: VizTextDisplayOptions;\n  onClick?: React.MouseEventHandler<HTMLElement>;\n  className?: string;\n  theme: GrafanaTheme2;\n  orientation?: VizOrientation;\n}\n\nexport class Gauge extends PureComponent<Props> {\n  canvasElement: HTMLDivElement | null = null;\n\n  static defaultProps: Partial<Props> = {\n    showThresholdMarkers: true,\n    showThresholdLabels: false,\n    field: {\n      min: 0,\n      max: 100,\n      thresholds: DEFAULT_THRESHOLDS,\n    },\n  };\n\n  componentDidMount() {\n    this.draw();\n  }\n\n  componentDidUpdate() {\n    this.draw();\n  }\n\n  draw() {\n    const { field, showThresholdLabels, showThresholdMarkers, width, height, theme, value, orientation } = this.props;\n\n    const autoProps = calculateGaugeAutoProps(width, height, value.title);\n    // If the gauge is in vertical layout, we need to set the width of the gauge to the height of the gauge\n    const calculatedGaugeWidth = orientation === VizOrientation.Vertical ? autoProps.gaugeHeight : width;\n    const dimension = Math.min(calculatedGaugeWidth, autoProps.gaugeHeight);\n    const backgroundColor = theme.colors.background.secondary;\n    const gaugeWidthReduceRatio = showThresholdLabels ? 1.5 : 1;\n    const gaugeWidth = Math.min(dimension / 5.5, 40) / gaugeWidthReduceRatio;\n    const thresholdMarkersWidth = gaugeWidth / 5;\n    const text = formattedValueToString(value);\n    // This not 100% accurate as I am unsure of flot's calculations here\n    const valueWidthBase = Math.min(calculatedGaugeWidth, dimension * 1.3) * 0.9;\n    // remove gauge & marker width (on left and right side)\n    // and 10px is some padding that flot adds to the outer canvas\n    const valueWidth =\n      valueWidthBase -\n      ((gaugeWidth + (showThresholdMarkers ? thresholdMarkersWidth : 0) + (showThresholdLabels ? 10 : 0)) * 2 + 10);\n    const fontSize = this.props.text?.valueSize ?? calculateFontSize(text, valueWidth, dimension, 1, gaugeWidth * 1.7);\n    const thresholdLabelFontSize = Math.max(fontSize / 2.5, 12);\n\n    let min = field.min ?? GAUGE_DEFAULT_MINIMUM;\n    let max = field.max ?? GAUGE_DEFAULT_MAXIMUM;\n    let numeric = value.numeric;\n\n    if (field.thresholds?.mode === ThresholdsMode.Percentage) {\n      min = 0;\n      max = 100;\n      if (value.percent === undefined) {\n        numeric = ((numeric - min) / (max - min)) * 100;\n      } else {\n        numeric = value.percent! * 100;\n      }\n    }\n\n    const decimals = field.decimals === undefined ? 2 : field.decimals!;\n\n    if (showThresholdMarkers) {\n      min = +min.toFixed(decimals);\n      max = +max.toFixed(decimals);\n    }\n\n    const options = {\n      series: {\n        gauges: {\n          gauge: {\n            min,\n            max,\n            neutralValue: field.custom?.neutral,\n            background: { color: backgroundColor },\n            border: { color: null },\n            shadow: { show: false },\n            width: gaugeWidth,\n          },\n          frame: { show: false },\n          label: { show: false },\n          layout: { margin: 0, thresholdWidth: 0, vMargin: 0 },\n          cell: { border: { width: 0 } },\n          threshold: {\n            values: getFormattedThresholds(decimals, field, value, theme),\n            label: {\n              show: showThresholdLabels,\n              margin: thresholdMarkersWidth + 1,\n              font: { size: thresholdLabelFontSize },\n            },\n            show: showThresholdMarkers,\n            width: thresholdMarkersWidth,\n          },\n          value: {\n            color: value.color,\n            formatter: () => {\n              return text;\n            },\n            font: { size: fontSize, family: theme.typography.fontFamily },\n          },\n          show: true,\n        },\n      },\n    };\n\n    const plotSeries = {\n      data: [[0, numeric]],\n      label: value.title,\n    };\n\n    try {\n      if (this.canvasElement) {\n        $.plot(this.canvasElement, [plotSeries], options);\n      }\n    } catch (err) {\n      console.error('Gauge rendering error', err, options, value);\n    }\n  }\n\n  renderVisualization = () => {\n    const { width, value, height, onClick, text, theme, orientation } = this.props;\n    const autoProps = calculateGaugeAutoProps(width, height, value.title, orientation);\n\n    // If the gauge is in vertical layout, we need to set the width of the gauge to the height of the gauge\n    const gaugeWidth = orientation === VizOrientation.Vertical ? `${autoProps.gaugeHeight}px` : '100%';\n\n    const gaugeElement = (\n      <div\n        style={{ height: `${autoProps.gaugeHeight}px`, width: gaugeWidth }}\n        ref={(element) => (this.canvasElement = element)}\n      />\n    );\n\n    return (\n      <>\n        {onClick ? (\n          <button className={clearButtonStyles(theme)} type=\"button\" onClick={onClick}>\n            {gaugeElement}\n          </button>\n        ) : (\n          gaugeElement\n        )}\n        {autoProps.showLabel && (\n          <div\n            style={{\n              textAlign: 'center',\n              fontSize: text?.titleSize ?? autoProps.titleFontSize,\n              overflow: 'hidden',\n              textOverflow: 'ellipsis',\n              whiteSpace: 'nowrap',\n              position: 'relative',\n              width: gaugeWidth,\n              top: '-4px',\n              cursor: 'default',\n            }}\n          >\n            {value.title}\n          </div>\n        )}\n      </>\n    );\n  };\n\n  render() {\n    return (\n      <div\n        style={{\n          width: '100%',\n          height: '100%',\n          display: 'flex',\n          flexDirection: 'column',\n          justifyContent: 'center',\n          overflow: 'hidden',\n        }}\n        className={this.props.className}\n      >\n        {this.renderVisualization()}\n      </div>\n    );\n  }\n}\n"],"names":[],"mappings":"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"}