{"version":3,"file":"index.mjs","names":["ReChartsRadarChart","Tooltip"],"sources":["../../src/RadarChart/index.tsx"],"sourcesContent":["'use client';\n\nimport { Flexbox } from '@lobehub/ui';\nimport { Skeleton } from '@lobehub/ui/base-ui';\nimport { cssVar } from 'antd-style';\nimport { ReactNode, forwardRef, useState } from 'react';\nimport {\n  Legend,\n  PolarAngleAxis,\n  PolarGrid,\n  PolarRadiusAxis,\n  Radar,\n  RadarChart as ReChartsRadarChart,\n  ResponsiveContainer,\n  Tooltip,\n} from 'recharts';\nimport { AxisDomain } from 'recharts/types/util/types';\n\nimport BaseChartProps from '@/common/BaseChartProps';\nimport ChartLegend from '@/common/ChartLegend';\nimport ChartTooltip from '@/common/ChartTooltip';\nimport NoData from '@/common/NoData';\nimport { constructCategoryColors, getYAxisDomain } from '@/common/utils';\nimport { useThemeColorRange } from '@/hooks/useThemeColorRange';\nimport { defaultValueFormatter } from '@/utils';\n\nimport { styles } from './styles';\n\nexport interface RadarChartProps extends BaseChartProps {\n  /**\n   * Format angle-axis labels. Receives the index value and the matching data row.\n   * Can return a string or ReactNode (e.g. colored `<tspan>`).\n   */\n  angleAxisLabelFormatter?: (value: string | number, payload?: Record<string, any>) => ReactNode;\n  /**\n   * When true, series after the first are rendered at `secondaryOpacity`.\n   * @default true\n   */\n  dimSecondarySeries?: boolean;\n  fillOpacity?: number;\n  /**\n   * Opacity applied to series after the first when `dimSecondarySeries` is enabled.\n   * @default 0.25\n   */\n  secondaryOpacity?: number;\n  shape?: 'polygon' | 'circle';\n  showRadiusAxis?: boolean;\n}\n\nconst RadarChart = forwardRef<HTMLDivElement, RadarChartProps>((props, ref) => {\n  const themeColorRange = useThemeColorRange();\n  const {\n    data = [],\n    categories = [],\n    customCategories,\n    index,\n    colors = themeColorRange,\n    valueFormatter = defaultValueFormatter,\n    animationDuration = 900,\n    showAnimation = false,\n    showTooltip = true,\n    showLegend = true,\n    showGridLines = true,\n    autoMinValue = false,\n    minValue,\n    maxValue,\n    allowDecimals = true,\n    noDataText,\n    onValueChange,\n    enableLegendSlider = false,\n    customTooltip,\n    loading,\n    className,\n    width = '100%',\n    height = 280,\n    style,\n    shape = 'polygon',\n    fillOpacity = 0.33,\n    showRadiusAxis = false,\n    dimSecondarySeries = true,\n    secondaryOpacity = 0.25,\n    angleAxisLabelFormatter,\n    xAxisLabelFormatter,\n    yAxisDomain: yAxisDomainOverride,\n    ...rest\n  } = props;\n\n  const [activeLegend, setActiveLegend] = useState<string | undefined>();\n  const [legendHeight, setLegendHeight] = useState(60);\n\n  if (loading || !data) return <Skeleton height={height} width={width} />;\n\n  const CustomTooltip = customTooltip;\n  const categoryColors = constructCategoryColors(categories, colors);\n  const hasOnValueChange = !!onValueChange;\n  const yAxisDomain = (yAxisDomainOverride ??\n    getYAxisDomain(autoMinValue, minValue, maxValue)) as AxisDomain;\n\n  const onCategoryClick = (dataKey: string) => {\n    if (!hasOnValueChange) return;\n    if (dataKey === activeLegend) {\n      setActiveLegend(undefined);\n      onValueChange?.(null);\n    } else {\n      setActiveLegend(dataKey);\n      onValueChange?.({\n        categoryClicked: dataKey,\n        eventType: 'category',\n      });\n    }\n  };\n\n  return (\n    <Flexbox\n      className={className}\n      height={height}\n      ref={ref}\n      style={{ position: 'relative', ...style }}\n      width={width}\n      {...rest}\n    >\n      <ResponsiveContainer>\n        {data?.length ? (\n          <ReChartsRadarChart\n            data={data}\n            margin={{ bottom: 10, left: 10, right: 10, top: 10 }}\n            onClick={\n              hasOnValueChange && activeLegend\n                ? () => {\n                    setActiveLegend(undefined);\n                    onValueChange?.(null);\n                  }\n                : undefined\n            }\n          >\n            {showGridLines ? (\n              <PolarGrid\n                className={styles.gridLines}\n                fill=\"none\"\n                gridType={shape}\n                stroke={cssVar.colorBorderSecondary}\n              />\n            ) : undefined}\n            <PolarAngleAxis\n              axisLine={false}\n              className={styles.label}\n              dataKey={index}\n              tick={(tickProps: any) => {\n                const { x, y, textAnchor, payload: tickPayload } = tickProps;\n                const value = tickPayload?.value;\n                const row = data.find((item) => item[index] === value);\n                let content: ReactNode = value;\n                if (angleAxisLabelFormatter) {\n                  content = angleAxisLabelFormatter(value, row);\n                } else if (xAxisLabelFormatter) {\n                  content = xAxisLabelFormatter(value);\n                }\n                return (\n                  <text\n                    className=\"recharts-polar-angle-axis-tick-value\"\n                    fill={cssVar.colorTextDescription}\n                    fontSize={12}\n                    textAnchor={textAnchor}\n                    x={x}\n                    y={y}\n                  >\n                    {content}\n                  </text>\n                );\n              }}\n              tickLine={false}\n            />\n            <PolarRadiusAxis\n              allowDecimals={allowDecimals}\n              axisLine={false}\n              className={styles.radiusLabel}\n              domain={yAxisDomain}\n              stroke={cssVar.colorTextQuaternary}\n              tick={showRadiusAxis}\n              tickFormatter={valueFormatter}\n              tickLine={false}\n            />\n            {showTooltip ? (\n              <Tooltip\n                content={({ active, payload, label }) =>\n                  CustomTooltip ? (\n                    <CustomTooltip\n                      active={active}\n                      customCategories={customCategories}\n                      label={label}\n                      payload={payload?.map((payloadItem: any) => ({\n                        ...payloadItem,\n                        color: categoryColors.get(payloadItem.dataKey) ?? cssVar.colorPrimary,\n                      }))}\n                      valueFormatter={valueFormatter}\n                    />\n                  ) : (\n                    <ChartTooltip\n                      active={active}\n                      categoryColors={categoryColors}\n                      customCategories={customCategories}\n                      label={label}\n                      payload={payload}\n                      valueFormatter={valueFormatter}\n                    />\n                  )\n                }\n                isAnimationActive={false}\n                wrapperStyle={{ outline: 'none' }}\n              />\n            ) : undefined}\n            {showLegend ? (\n              <Legend\n                content={({ payload }) =>\n                  ChartLegend(\n                    { payload: payload?.slice().reverse() },\n                    categoryColors,\n                    setLegendHeight,\n                    activeLegend,\n                    hasOnValueChange\n                      ? (clickedLegendItem: string) => onCategoryClick(clickedLegendItem)\n                      : undefined,\n                    enableLegendSlider,\n                    customCategories,\n                  )\n                }\n                height={legendHeight}\n                verticalAlign=\"top\"\n              />\n            ) : undefined}\n            {/* Render later categories first so earlier ones (e.g. A) paint on top */}\n            {[...categories].reverse().map((category) => {\n              const isInactive = Boolean(activeLegend && activeLegend !== category);\n              const isSecondary = dimSecondarySeries && category !== categories[0];\n              const seriesFillOpacity = isSecondary ? fillOpacity * secondaryOpacity : fillOpacity;\n              const seriesStrokeOpacity = isSecondary ? secondaryOpacity : 1;\n              const color = categoryColors.get(category) ?? cssVar.colorPrimary;\n              return (\n                <Radar\n                  animationDuration={animationDuration}\n                  dataKey={category}\n                  fill={color}\n                  fillOpacity={isInactive ? seriesFillOpacity * 0.3 : seriesFillOpacity}\n                  isAnimationActive={showAnimation}\n                  key={category}\n                  name={category}\n                  stroke={color}\n                  strokeOpacity={isInactive ? seriesStrokeOpacity * 0.3 : seriesStrokeOpacity}\n                  strokeWidth={2}\n                  style={{\n                    cursor: onValueChange ? 'pointer' : undefined,\n                  }}\n                />\n              );\n            })}\n          </ReChartsRadarChart>\n        ) : (\n          <NoData noDataText={noDataText} />\n        )}\n      </ResponsiveContainer>\n    </Flexbox>\n  );\n});\n\nRadarChart.displayName = 'RadarChart';\n\nexport default RadarChart;\n"],"mappings":"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"}