{"version":3,"file":"DumbbellChart-8XbSV4XT.cjs","names":[],"sources":["../src/Components/Graphs/DumbbellChart/Graph.tsx","../src/Components/Graphs/DumbbellChart/index.tsx"],"sourcesContent":["import { cn } from '@undp/design-system-react/cn';\r\nimport { scaleBand, scaleLinear } from 'd3-scale';\r\nimport isEqual from 'fast-deep-equal';\r\nimport { AnimatePresence, motion, useInView } from 'motion/react';\r\nimport { useMemo, useRef, useState } from 'react';\r\nimport { Axis } from '@/Components/Elements/Axes/Axis';\r\nimport { AxisTitle } from '@/Components/Elements/Axes/AxisTitle';\r\nimport { XAxesLabels } from '@/Components/Elements/Axes/XAxesLabels';\r\nimport { XTicksAndGridLines } from '@/Components/Elements/Axes/XTicksAndGridLines';\r\nimport { YAxesLabels } from '@/Components/Elements/Axes/YAxesLabels';\r\nimport { YTicksAndGridLines } from '@/Components/Elements/Axes/YTicksAndGridLines';\r\nimport { DetailsModal } from '@/Components/Elements/DetailsModal';\r\nimport { RefLineX, RefLineY } from '@/Components/Elements/ReferenceLine';\r\nimport { Tooltip } from '@/Components/Elements/Tooltip';\r\nimport type {\r\n  AnimateDataType,\r\n  ClassNameObject,\r\n  CustomLayerDataType,\r\n  DumbbellChartDataType,\r\n  PadZerosTypes,\r\n  ReferenceDataType,\r\n  StyleObject,\r\n} from '@/Types';\r\nimport { checkIfNullOrUndefined } from '@/Utils/checkIfNullOrUndefined';\r\nimport { getGraphDimensions } from '@/Utils/getGraphDimensions';\r\nimport { numberFormattingFunction } from '@/Utils/numberFormattingFunction';\r\n\r\ninterface Props {\r\n  data: DumbbellChartDataType[];\r\n  dotColors: string[];\r\n  barPadding: number;\r\n  showTicks: boolean;\r\n  leftMargin?: number;\r\n  rightMargin?: number;\r\n  topMargin?: number;\r\n  bottomMargin?: number;\r\n  truncateBy: number;\r\n  width: number;\r\n  height: number;\r\n  radius: number;\r\n  showLabels: boolean;\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  tooltip?: string | ((_d: any) => React.ReactNode);\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  onSeriesMouseOver?: (_d: any) => void;\r\n  maxValue: number;\r\n  minValue: number;\r\n  suffix: string;\r\n  prefix: string;\r\n  showValues: boolean;\r\n  selectedColor?: string;\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  onSeriesMouseClick?: (_d: any) => void;\r\n  arrowConnector: boolean;\r\n  connectorStrokeWidth: number;\r\n  maxBarThickness?: number;\r\n  minBarThickness?: number;\r\n  resetSelectionOnDoubleClick: boolean;\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  detailsOnClick?: string | ((_d: any) => React.ReactNode);\r\n  axisTitle?: string;\r\n  noOfTicks: number;\r\n  valueColor?: string;\r\n  labelOrder?: (string | number)[];\r\n  styles?: StyleObject;\r\n  classNames?: ClassNameObject;\r\n  refValues?: ReferenceDataType[];\r\n  animate: AnimateDataType;\r\n  precision: number;\r\n  customLayers: CustomLayerDataType[];\r\n  highlightedDataPoints?: (string | number)[];\r\n  dimmedOpacity: number;\r\n  rtl: boolean;\r\n  hideAxisLine: boolean;\r\n  locale: string;\r\n  padZeros: PadZerosTypes;\r\n  repositionOverlappingLabels: boolean;\r\n}\r\n\r\nexport function VerticalGraph(props: Props) {\r\n  const {\r\n    data,\r\n    leftMargin = 20,\r\n    rightMargin = 20,\r\n    topMargin = 20,\r\n    bottomMargin = 25,\r\n    dotColors,\r\n    barPadding,\r\n    showTicks,\r\n    truncateBy,\r\n    width,\r\n    height,\r\n    radius,\r\n    showLabels,\r\n    tooltip,\r\n    onSeriesMouseOver,\r\n    maxValue,\r\n    minValue,\r\n    onSeriesMouseClick,\r\n    showValues,\r\n    suffix,\r\n    prefix,\r\n    selectedColor,\r\n    arrowConnector,\r\n    connectorStrokeWidth,\r\n    maxBarThickness,\r\n    minBarThickness,\r\n    resetSelectionOnDoubleClick,\r\n    detailsOnClick,\r\n    axisTitle,\r\n    noOfTicks,\r\n    valueColor,\r\n    styles,\r\n    classNames,\r\n    labelOrder,\r\n    refValues,\r\n    animate,\r\n    precision,\r\n    customLayers,\r\n    highlightedDataPoints,\r\n    dimmedOpacity,\r\n    hideAxisLine,\r\n    locale,\r\n    padZeros,\r\n  } = props;\r\n  const svgRef = useRef(null);\r\n  const isInView = useInView(svgRef, {\r\n    once: animate.once,\r\n    amount: animate.amount,\r\n  });\r\n  const margin = {\r\n    top: topMargin,\r\n    bottom: bottomMargin,\r\n    left: axisTitle ? leftMargin + 30 : leftMargin,\r\n    right: rightMargin,\r\n  };\r\n  const { graphHeight, graphWidth } = getGraphDimensions({ width, height }, margin);\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  const [mouseOverData, setMouseOverData] = useState<any>(undefined);\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  const [mouseClickData, setMouseClickData] = useState<any>(undefined);\r\n  const [eventX, setEventX] = useState<number | undefined>(undefined);\r\n  const [eventY, setEventY] = useState<number | undefined>(undefined);\r\n\r\n  const dataWithId = useMemo(() => {\r\n    const idSet = new Set<string | number>();\r\n\r\n    const dataWithIdWithoutMissingIds = data.map((d, i) => {\r\n      const id = labelOrder ? d.label : `${i}`;\r\n      idSet.add(id);\r\n      return { ...d, id };\r\n    });\r\n\r\n    const missingIds = labelOrder ? labelOrder.filter((id) => !idSet.has(id)) : [];\r\n\r\n    return [\r\n      ...dataWithIdWithoutMissingIds,\r\n      ...missingIds.map((id) => ({\r\n        id,\r\n        label: id,\r\n        x: Array(data[0].x.length).fill(null),\r\n      })),\r\n    ];\r\n  }, [data, labelOrder]);\r\n\r\n  const barOrder = useMemo(() => {\r\n    return labelOrder ?? dataWithId.map((d) => `${d.id}`);\r\n  }, [labelOrder, dataWithId]);\r\n\r\n  const y = scaleLinear().domain([minValue, maxValue]).range([graphHeight, 0]).nice();\r\n  const x = scaleBand<string | number>()\r\n    .domain(barOrder)\r\n    .range([\r\n      0,\r\n      minBarThickness\r\n        ? Math.max(graphWidth, minBarThickness * dataWithId.length)\r\n        : maxBarThickness\r\n          ? Math.min(graphWidth, maxBarThickness * dataWithId.length)\r\n          : graphWidth,\r\n    ])\r\n    .paddingInner(barPadding);\r\n  const yTicks = y.ticks(noOfTicks);\r\n\r\n  return (\r\n    <>\r\n      <motion.svg\r\n        width={`${width}px`}\r\n        height={`${height}px`}\r\n        viewBox={`0 0 ${width} ${height}`}\r\n        direction='ltr'\r\n        ref={svgRef}\r\n      >\r\n        {arrowConnector ? (\r\n          <defs>\r\n            <marker\r\n              id='arrow'\r\n              viewBox='0 0 10 10'\r\n              refX='10'\r\n              refY='5'\r\n              markerWidth='6'\r\n              markerHeight='6'\r\n              orient='auto-start-reverse'\r\n            >\r\n              <path d='M 0 0 L 10 5 L 0 10 z' className='fill-surface-3xl' />\r\n            </marker>\r\n          </defs>\r\n        ) : null}\r\n        <g transform={`translate(${margin.left},${margin.top})`}>\r\n          <Axis\r\n            hideAxisLine={hideAxisLine}\r\n            y1={y(minValue < 0 ? 0 : minValue)}\r\n            y2={y(minValue < 0 ? 0 : minValue)}\r\n            x1={0 - leftMargin}\r\n            x2={graphWidth + margin.right}\r\n            label={\r\n              showTicks\r\n                ? numberFormattingFunction(\r\n                    minValue < 0 ? 0 : minValue,\r\n                    undefined,\r\n                    precision,\r\n                    prefix,\r\n                    suffix,\r\n                    locale,\r\n                    padZeros,\r\n                  )\r\n                : undefined\r\n            }\r\n            labelPos={{\r\n              x: 0 - leftMargin,\r\n              dx: 0,\r\n              dy: maxValue < 0 ? '1em' : -5,\r\n              y: y(minValue < 0 ? 0 : minValue),\r\n            }}\r\n            classNames={{\r\n              axis: classNames?.xAxis?.axis,\r\n              label: classNames?.yAxis?.labels,\r\n            }}\r\n            styles={{ axis: styles?.xAxis?.axis, label: styles?.yAxis?.labels }}\r\n          />\r\n          {showTicks ? (\r\n            <YTicksAndGridLines\r\n              values={yTicks.filter((d) => d !== 0)}\r\n              y={yTicks.filter((d) => d !== 0).map((d) => y(d))}\r\n              x1={0 - leftMargin}\r\n              x2={graphWidth + margin.right}\r\n              styles={{\r\n                gridLines: styles?.yAxis?.gridLines,\r\n                labels: styles?.yAxis?.labels,\r\n              }}\r\n              classNames={{\r\n                gridLines: classNames?.yAxis?.gridLines,\r\n                labels: classNames?.yAxis?.labels,\r\n              }}\r\n              suffix={suffix}\r\n              prefix={prefix}\r\n              labelType='secondary'\r\n              showGridLines\r\n              labelPos='vertical'\r\n              precision={precision}\r\n              locale={locale}\r\n              padZeros={padZeros}\r\n            />\r\n          ) : null}\r\n          <AxisTitle\r\n            x={0 - leftMargin - 15}\r\n            y={graphHeight / 2}\r\n            style={styles?.yAxis?.title}\r\n            className={classNames?.yAxis?.title}\r\n            text={axisTitle}\r\n            rotate90\r\n          />\r\n          {customLayers.filter((d) => d.position === 'before').map((d) => d.layer)}\r\n          <AnimatePresence>\r\n            {dataWithId.map((d) => (\r\n              <motion.g\r\n                className='undp-viz-g-with-hover'\r\n                key={d.label}\r\n                variants={{\r\n                  initial: {\r\n                    x: (x(`${d.id}`) as number) + x.bandwidth() / 2,\r\n                    y: 0,\r\n                    opacity: highlightedDataPoints\r\n                      ? highlightedDataPoints.indexOf(d.label) !== -1\r\n                        ? 0.85\r\n                        : dimmedOpacity\r\n                      : 0.85,\r\n                  },\r\n                  whileInView: {\r\n                    x: (x(`${d.id}`) as number) + x.bandwidth() / 2,\r\n                    y: 0,\r\n                    opacity: highlightedDataPoints\r\n                      ? highlightedDataPoints.indexOf(d.label) !== -1\r\n                        ? 0.85\r\n                        : dimmedOpacity\r\n                      : 0.85,\r\n                    transition: { duration: animate.duration },\r\n                  },\r\n                }}\r\n                initial='initial'\r\n                animate={isInView ? 'whileInView' : 'initial'}\r\n                exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n              >\r\n                {showLabels ? (\r\n                  <XAxesLabels\r\n                    value={\r\n                      `${d.label}`.length < truncateBy\r\n                        ? `${d.label}`\r\n                        : `${`${d.label}`.substring(0, truncateBy)}...`\r\n                    }\r\n                    y={graphHeight + 5}\r\n                    x={0 - x.bandwidth() / 2}\r\n                    width={x.bandwidth()}\r\n                    height={margin.bottom}\r\n                    style={styles?.xAxis?.labels}\r\n                    className={classNames?.xAxis?.labels}\r\n                    alignment='top'\r\n                    animate={animate}\r\n                    isInView={isInView}\r\n                  />\r\n                ) : null}\r\n                <motion.line\r\n                  x1={0}\r\n                  x2={0}\r\n                  style={{\r\n                    strokeWidth: connectorStrokeWidth,\r\n                    ...(styles?.dataConnectors || {}),\r\n                    opacity: selectedColor ? 0.3 : 1,\r\n                  }}\r\n                  className={cn('stroke-surface-3xl', classNames?.dataConnectors)}\r\n                  markerEnd={\r\n                    arrowConnector &&\r\n                    d.x.indexOf(Math.min(...d.x.filter((el) => el !== null))) === 0\r\n                      ? 'url(#arrow)'\r\n                      : ''\r\n                  }\r\n                  markerStart={\r\n                    arrowConnector &&\r\n                    d.x.indexOf(Math.min(...d.x.filter((el) => el !== null))) === d.x.length - 1\r\n                      ? 'url(#arrow)'\r\n                      : ''\r\n                  }\r\n                  exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n                  variants={{\r\n                    initial: {\r\n                      y1: 0,\r\n                      y2: 0,\r\n                    },\r\n                    whileInView: {\r\n                      y1: y(Math.min(...d.x.filter((el) => el !== null))) + radius,\r\n                      y2: y(Math.max(...d.x.filter((el) => el !== null))) - radius,\r\n                      transition: { duration: animate.duration },\r\n                    },\r\n                  }}\r\n                  initial='initial'\r\n                  animate={isInView ? 'whileInView' : 'initial'}\r\n                />\r\n                {d.x.map((el, j) => (\r\n                  <motion.g\r\n                    // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                    key={j}\r\n                    onMouseEnter={(event) => {\r\n                      setMouseOverData({ ...d, xIndex: j });\r\n                      setEventY(event.clientY);\r\n                      setEventX(event.clientX);\r\n                      onSeriesMouseOver?.({ ...d, xIndex: j });\r\n                    }}\r\n                    onClick={() => {\r\n                      if (onSeriesMouseClick || detailsOnClick) {\r\n                        if (\r\n                          isEqual(mouseClickData, { ...d, xIndex: j }) &&\r\n                          resetSelectionOnDoubleClick\r\n                        ) {\r\n                          setMouseClickData(undefined);\r\n                          onSeriesMouseClick?.(undefined);\r\n                        } else {\r\n                          setMouseClickData({ ...d, xIndex: j });\r\n                          if (onSeriesMouseClick) onSeriesMouseClick({ ...d, xIndex: j });\r\n                        }\r\n                      }\r\n                    }}\r\n                    onMouseMove={(event) => {\r\n                      setMouseOverData({ ...d, xIndex: j });\r\n                      setEventY(event.clientY);\r\n                      setEventX(event.clientX);\r\n                    }}\r\n                    onMouseLeave={() => {\r\n                      setMouseOverData(undefined);\r\n                      setEventX(undefined);\r\n                      setEventY(undefined);\r\n                      onSeriesMouseOver?.(undefined);\r\n                    }}\r\n                    exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n                    variants={{\r\n                      initial: {\r\n                        opacity: selectedColor ? (dotColors[j] === selectedColor ? 1 : 0.3) : 1,\r\n                      },\r\n                      whileInView: {\r\n                        opacity: selectedColor ? (dotColors[j] === selectedColor ? 1 : 0.3) : 1,\r\n                        transition: { duration: animate.duration },\r\n                      },\r\n                    }}\r\n                    initial='initial'\r\n                    animate={isInView ? 'whileInView' : 'initial'}\r\n                  >\r\n                    {checkIfNullOrUndefined(el) ? null : (\r\n                      <>\r\n                        <motion.circle\r\n                          cx={0}\r\n                          r={radius}\r\n                          style={{\r\n                            fill: dotColors[j],\r\n                            fillOpacity: 0.85,\r\n                            stroke: dotColors[j],\r\n                            strokeWidth: 1,\r\n                          }}\r\n                          exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n                          variants={{\r\n                            initial: { cy: y(0), opacity: 0 },\r\n                            whileInView: {\r\n                              cy: y(el || 0),\r\n                              opacity: checkIfNullOrUndefined(el) ? 0 : 1,\r\n                              transition: { duration: animate.duration },\r\n                            },\r\n                          }}\r\n                          initial='initial'\r\n                          animate={isInView ? 'whileInView' : 'initial'}\r\n                        />\r\n                        {showValues ? (\r\n                          <motion.text\r\n                            x={0}\r\n                            style={{\r\n                              textAnchor: 'start',\r\n                              ...(styles?.graphObjectValues || {}),\r\n                            }}\r\n                            className={cn(\r\n                              'graph-value text-sm font-bold',\r\n                              classNames?.graphObjectValues,\r\n                            )}\r\n                            dx={radius + 3}\r\n                            dy='0.33em'\r\n                            exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n                            variants={{\r\n                              initial: { y: y(0), opacity: 0, fill: valueColor || dotColors[j] },\r\n                              whileInView: {\r\n                                y: y(el || 0),\r\n                                fill: valueColor || dotColors[j],\r\n                                opacity: checkIfNullOrUndefined(el) ? 0 : 1,\r\n                                transition: { duration: animate.duration },\r\n                              },\r\n                            }}\r\n                            initial='initial'\r\n                            animate={isInView ? 'whileInView' : 'initial'}\r\n                          >\r\n                            {numberFormattingFunction(\r\n                              el,\r\n                              undefined,\r\n                              precision,\r\n                              prefix,\r\n                              suffix,\r\n                              locale,\r\n                              padZeros,\r\n                            )}\r\n                          </motion.text>\r\n                        ) : null}\r\n                      </>\r\n                    )}\r\n                  </motion.g>\r\n                ))}\r\n              </motion.g>\r\n            ))}\r\n            {refValues?.map((el) => (\r\n              <RefLineY\r\n                key={el.text}\r\n                text={el.text}\r\n                color={el.color}\r\n                y={y(el.value as number)}\r\n                x1={0 - leftMargin}\r\n                x2={graphWidth + margin.right}\r\n                classNames={el.classNames}\r\n                styles={el.styles}\r\n                animate={animate}\r\n                isInView={isInView}\r\n              />\r\n            ))}\r\n          </AnimatePresence>\r\n          {customLayers.filter((d) => d.position === 'after').map((d) => d.layer)}\r\n        </g>\r\n      </motion.svg>\r\n      {mouseOverData && tooltip && eventX && eventY ? (\r\n        <Tooltip\r\n          data={mouseOverData}\r\n          body={tooltip}\r\n          xPos={eventX}\r\n          yPos={eventY}\r\n          backgroundStyle={styles?.tooltip}\r\n          className={classNames?.tooltip}\r\n        />\r\n      ) : null}\r\n      {detailsOnClick && mouseClickData !== undefined ? (\r\n        <DetailsModal\r\n          body={detailsOnClick}\r\n          data={mouseClickData}\r\n          setData={setMouseClickData}\r\n          className={classNames?.modal}\r\n        />\r\n      ) : null}\r\n    </>\r\n  );\r\n}\r\n\r\nexport function HorizontalGraph(props: Props) {\r\n  const {\r\n    data,\r\n    leftMargin = 100,\r\n    rightMargin = 40,\r\n    topMargin = 20,\r\n    bottomMargin = 10,\r\n    dotColors,\r\n    suffix,\r\n    prefix,\r\n    barPadding,\r\n    showValues,\r\n    showTicks,\r\n    truncateBy,\r\n    width,\r\n    height,\r\n    radius,\r\n    showLabels,\r\n    tooltip,\r\n    onSeriesMouseOver,\r\n    maxValue,\r\n    minValue,\r\n    onSeriesMouseClick,\r\n    selectedColor,\r\n    arrowConnector,\r\n    connectorStrokeWidth,\r\n    maxBarThickness,\r\n    minBarThickness,\r\n    resetSelectionOnDoubleClick,\r\n    detailsOnClick,\r\n    axisTitle,\r\n    noOfTicks,\r\n    valueColor,\r\n    styles,\r\n    classNames,\r\n    labelOrder,\r\n    refValues,\r\n    rtl,\r\n    animate,\r\n    precision,\r\n    customLayers,\r\n    highlightedDataPoints,\r\n    dimmedOpacity,\r\n    locale,\r\n    padZeros,\r\n    repositionOverlappingLabels,\r\n  } = props;\r\n  const svgRef = useRef(null);\r\n  const isInView = useInView(svgRef, {\r\n    once: animate.once,\r\n    amount: animate.amount,\r\n  });\r\n  const margin = {\r\n    top: axisTitle ? topMargin + 25 : topMargin,\r\n    bottom: bottomMargin,\r\n    left: leftMargin,\r\n    right: rightMargin,\r\n  };\r\n  const { graphHeight, graphWidth } = getGraphDimensions({ width, height }, margin);\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  const [mouseOverData, setMouseOverData] = useState<any>(undefined);\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  const [mouseClickData, setMouseClickData] = useState<any>(undefined);\r\n  const [eventX, setEventX] = useState<number | undefined>(undefined);\r\n  const [eventY, setEventY] = useState<number | undefined>(undefined);\r\n\r\n  const dataWithId = useMemo(() => {\r\n    const idSet = new Set<string | number>();\r\n\r\n    const dataWithIdWithoutMissingIds = data.map((d, i) => {\r\n      const id = labelOrder ? d.label : `${i}`;\r\n      idSet.add(id);\r\n      return { ...d, id };\r\n    });\r\n\r\n    const missingIds = labelOrder ? labelOrder.filter((id) => !idSet.has(id)) : [];\r\n\r\n    return [\r\n      ...dataWithIdWithoutMissingIds,\r\n      ...missingIds.map((id) => ({\r\n        id,\r\n        label: id,\r\n        x: Array(data[0].x.length).fill(null),\r\n      })),\r\n    ];\r\n  }, [data, labelOrder]);\r\n\r\n  const barOrder = useMemo(() => {\r\n    return labelOrder ?? dataWithId.map((d) => `${d.id}`);\r\n  }, [labelOrder, dataWithId]);\r\n\r\n  const x = scaleLinear().domain([minValue, maxValue]).range([0, graphWidth]).nice();\r\n  const y = scaleBand<string | number>()\r\n    .domain(barOrder)\r\n    .range([\r\n      0,\r\n      minBarThickness\r\n        ? Math.max(graphHeight, minBarThickness * dataWithId.length)\r\n        : maxBarThickness\r\n          ? Math.min(graphHeight, maxBarThickness * dataWithId.length)\r\n          : graphHeight,\r\n    ])\r\n    .paddingInner(barPadding);\r\n  const xTicks = x.ticks(noOfTicks);\r\n\r\n  return (\r\n    <>\r\n      <motion.svg\r\n        width={`${width}px`}\r\n        height={`${height}px`}\r\n        viewBox={`0 0 ${width} ${height}`}\r\n        direction='ltr'\r\n        ref={svgRef}\r\n      >\r\n        {arrowConnector ? (\r\n          <defs>\r\n            <marker\r\n              id='arrow'\r\n              viewBox='0 0 10 10'\r\n              refX='10'\r\n              refY='5'\r\n              markerWidth='6'\r\n              markerHeight='6'\r\n              orient='auto-start-reverse'\r\n            >\r\n              <path d='M 0 0 L 10 5 L 0 10 z' className='fill-surface-3xl' />\r\n            </marker>\r\n          </defs>\r\n        ) : null}\r\n        <g transform={`translate(${margin.left},${margin.top})`}>\r\n          {showTicks ? (\r\n            <XTicksAndGridLines\r\n              values={xTicks.filter((_d, i) => i !== 0)}\r\n              x={xTicks.filter((_d, i) => i !== 0).map((d) => x(d))}\r\n              y1={0 - topMargin}\r\n              y2={graphHeight + margin.bottom}\r\n              styles={{\r\n                gridLines: styles?.xAxis?.gridLines,\r\n                labels: styles?.xAxis?.labels,\r\n              }}\r\n              classNames={{\r\n                gridLines: classNames?.xAxis?.gridLines,\r\n                labels: classNames?.xAxis?.labels,\r\n              }}\r\n              suffix={suffix}\r\n              prefix={prefix}\r\n              labelType='secondary'\r\n              showGridLines\r\n              precision={precision}\r\n              locale={locale}\r\n              padZeros={padZeros}\r\n            />\r\n          ) : null}\r\n          <AxisTitle\r\n            x={graphWidth / 2}\r\n            y={0 - margin.top + 15}\r\n            style={styles?.xAxis?.title}\r\n            className={classNames?.xAxis?.title}\r\n            text={axisTitle}\r\n          />\r\n          <YTicksAndGridLines\r\n            y={dataWithId.map((d) => (y(`${d.id}`) as number) + y.bandwidth() / 2)}\r\n            x1={0}\r\n            x2={graphWidth}\r\n            styles={{ gridLines: styles?.yAxis?.gridLines }}\r\n            classNames={{ gridLines: classNames?.yAxis?.gridLines }}\r\n            labelType='secondary'\r\n            showGridLines\r\n            labelPos='vertical'\r\n            precision={precision}\r\n            locale={locale}\r\n            padZeros={padZeros}\r\n          />\r\n          {customLayers.filter((d) => d.position === 'before').map((d) => d.layer)}\r\n          <AnimatePresence>\r\n            {dataWithId.map((d) => (\r\n              <motion.g\r\n                className='undp-viz-g-with-hover'\r\n                key={d.label}\r\n                variants={{\r\n                  initial: {\r\n                    x: 0,\r\n                    y: (y(`${d.id}`) as number) + y.bandwidth() / 2,\r\n                    opacity: highlightedDataPoints\r\n                      ? highlightedDataPoints.indexOf(d.label) !== -1\r\n                        ? 0.85\r\n                        : dimmedOpacity\r\n                      : 0.85,\r\n                  },\r\n                  whileInView: {\r\n                    x: 0,\r\n                    y: (y(`${d.id}`) as number) + y.bandwidth() / 2,\r\n                    opacity: highlightedDataPoints\r\n                      ? highlightedDataPoints.indexOf(d.label) !== -1\r\n                        ? 0.85\r\n                        : dimmedOpacity\r\n                      : 0.85,\r\n                    transition: { duration: animate.duration },\r\n                  },\r\n                }}\r\n                initial='initial'\r\n                animate={isInView ? 'whileInView' : 'initial'}\r\n                exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n              >\r\n                {showLabels ? (\r\n                  <YAxesLabels\r\n                    value={\r\n                      `${d.label}`.length < truncateBy\r\n                        ? `${d.label}`\r\n                        : `${`${d.label}`.substring(0, truncateBy)}...`\r\n                    }\r\n                    y={0 - y.bandwidth() / 2}\r\n                    x={0 - margin.left}\r\n                    width={margin.left}\r\n                    height={y.bandwidth()}\r\n                    alignment='right'\r\n                    style={styles?.yAxis?.labels}\r\n                    className={classNames?.yAxis?.labels}\r\n                    animate={animate}\r\n                    isInView={isInView}\r\n                  />\r\n                ) : null}\r\n                <motion.line\r\n                  y1={0}\r\n                  y2={0}\r\n                  style={{\r\n                    strokeWidth: connectorStrokeWidth,\r\n                    ...(styles?.dataConnectors || {}),\r\n                    opacity: selectedColor ? 0.3 : 1,\r\n                  }}\r\n                  className={cn('stroke-surface-3xl', classNames?.dataConnectors)}\r\n                  markerEnd={\r\n                    arrowConnector &&\r\n                    d.x.indexOf(Math.min(...d.x.filter((el) => el !== null)) as number) === 0\r\n                      ? 'url(#arrow)'\r\n                      : ''\r\n                  }\r\n                  markerStart={\r\n                    arrowConnector &&\r\n                    d.x.indexOf(Math.min(...d.x.filter((el) => el !== null)) as number) ===\r\n                      d.x.length - 1\r\n                      ? 'url(#arrow)'\r\n                      : ''\r\n                  }\r\n                  exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n                  variants={{\r\n                    initial: {\r\n                      x1: 0,\r\n                      x2: 0,\r\n                    },\r\n                    whileInView: {\r\n                      x1: x(Math.min(...d.x.filter((el) => el !== null))) + radius,\r\n                      x2: x(Math.max(...d.x.filter((el) => el !== null)) as number) - radius,\r\n                      transition: { duration: animate.duration },\r\n                    },\r\n                  }}\r\n                  initial='initial'\r\n                  animate={isInView ? 'whileInView' : 'initial'}\r\n                />\r\n                {d.x.map((el, j) => {\r\n                  const sortedX = [...d.x]\r\n                    .filter((el) => !checkIfNullOrUndefined(el))\r\n                    .sort((a, b) => a - b);\r\n                  const sortedIndex = sortedX.indexOf(el);\r\n\r\n                  const isLabelPositionTop =\r\n                    sortedIndex === 0 || !repositionOverlappingLabels || checkIfNullOrUndefined(el)\r\n                      ? true\r\n                      : x(el) - x(sortedX[sortedIndex - 1]) > 30;\r\n                  return (\r\n                    <motion.g\r\n                      // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                      key={j}\r\n                      onMouseEnter={(event) => {\r\n                        setMouseOverData({ ...d, xIndex: j });\r\n                        setEventY(event.clientY);\r\n                        setEventX(event.clientX);\r\n                        onSeriesMouseOver?.({ ...d, xIndex: j });\r\n                      }}\r\n                      onClick={() => {\r\n                        if (onSeriesMouseClick || detailsOnClick) {\r\n                          if (\r\n                            isEqual(mouseClickData, { ...d, xIndex: j }) &&\r\n                            resetSelectionOnDoubleClick\r\n                          ) {\r\n                            setMouseClickData(undefined);\r\n                            onSeriesMouseClick?.(undefined);\r\n                          } else {\r\n                            setMouseClickData({ ...d, xIndex: j });\r\n                            if (onSeriesMouseClick) onSeriesMouseClick({ ...d, xIndex: j });\r\n                          }\r\n                        }\r\n                      }}\r\n                      onMouseMove={(event) => {\r\n                        setMouseOverData({ ...d, xIndex: j });\r\n                        setEventY(event.clientY);\r\n                        setEventX(event.clientX);\r\n                      }}\r\n                      onMouseLeave={() => {\r\n                        setMouseOverData(undefined);\r\n                        setEventX(undefined);\r\n                        setEventY(undefined);\r\n                        onSeriesMouseOver?.(undefined);\r\n                      }}\r\n                      exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n                      variants={{\r\n                        initial: {\r\n                          opacity: selectedColor ? (dotColors[j] === selectedColor ? 1 : 0.3) : 1,\r\n                        },\r\n                        whileInView: {\r\n                          opacity: selectedColor ? (dotColors[j] === selectedColor ? 1 : 0.3) : 1,\r\n                          transition: { duration: animate.duration },\r\n                        },\r\n                      }}\r\n                      initial='initial'\r\n                      animate={isInView ? 'whileInView' : 'initial'}\r\n                    >\r\n                      {checkIfNullOrUndefined(el) ? null : (\r\n                        <>\r\n                          <motion.circle\r\n                            cy={0}\r\n                            r={radius}\r\n                            style={{\r\n                              fill: dotColors[j],\r\n                              fillOpacity: 0.85,\r\n                              stroke: dotColors[j],\r\n                              strokeWidth: 1,\r\n                              opacity: checkIfNullOrUndefined(el) ? 0 : 1,\r\n                            }}\r\n                            exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n                            variants={{\r\n                              initial: { cx: x(0), opacity: 0 },\r\n                              whileInView: {\r\n                                cx: x(el || 0),\r\n                                opacity: checkIfNullOrUndefined(el) ? 0 : 1,\r\n                                transition: { duration: animate.duration },\r\n                              },\r\n                            }}\r\n                            initial='initial'\r\n                            animate={isInView ? 'whileInView' : 'initial'}\r\n                          />\r\n                          {showValues ? (\r\n                            <motion.text\r\n                              y={0}\r\n                              style={{\r\n                                textAnchor: 'middle',\r\n                                ...(styles?.graphObjectValues || {}),\r\n                              }}\r\n                              dx={0}\r\n                              className={cn(\r\n                                'graph-value text-sm font-bold',\r\n                                classNames?.graphObjectValues,\r\n                              )}\r\n                              exit={{ opacity: 0, transition: { duration: animate.duration } }}\r\n                              variants={{\r\n                                initial: {\r\n                                  x: x(0),\r\n                                  dy: 0 - radius - 3,\r\n                                  opacity: 0,\r\n                                  fill: valueColor || dotColors[j],\r\n                                },\r\n                                whileInView: {\r\n                                  x: x(el || 0),\r\n                                  fill: valueColor || dotColors[j],\r\n                                  opacity: checkIfNullOrUndefined(el) ? 0 : 1,\r\n                                  dy: isLabelPositionTop ? 0 - radius - 3 : radius + 12,\r\n                                  transition: { duration: animate.duration },\r\n                                },\r\n                              }}\r\n                              initial='initial'\r\n                              animate={isInView ? 'whileInView' : 'initial'}\r\n                            >\r\n                              {numberFormattingFunction(\r\n                                el,\r\n                                undefined,\r\n                                precision,\r\n                                prefix,\r\n                                suffix,\r\n                                locale,\r\n                                padZeros,\r\n                              )}\r\n                            </motion.text>\r\n                          ) : null}\r\n                        </>\r\n                      )}\r\n                    </motion.g>\r\n                  );\r\n                })}\r\n              </motion.g>\r\n            ))}\r\n            {refValues?.map((el) => (\r\n              <RefLineX\r\n                key={el.text}\r\n                text={el.text}\r\n                color={el.color}\r\n                x={x(el.value as number)}\r\n                y1={0 - margin.top}\r\n                y2={graphHeight + margin.bottom}\r\n                textSide={x(el.value as number) > graphWidth * 0.75 || rtl ? 'left' : 'right'}\r\n                classNames={el.classNames}\r\n                styles={el.styles}\r\n                animate={animate}\r\n                isInView={isInView}\r\n              />\r\n            ))}\r\n          </AnimatePresence>\r\n          {customLayers.filter((d) => d.position === 'after').map((d) => d.layer)}\r\n        </g>\r\n      </motion.svg>\r\n      {mouseOverData && tooltip && eventX && eventY ? (\r\n        <Tooltip\r\n          data={mouseOverData}\r\n          body={tooltip}\r\n          xPos={eventX}\r\n          yPos={eventY}\r\n          backgroundStyle={styles?.tooltip}\r\n          className={classNames?.tooltip}\r\n        />\r\n      ) : null}\r\n      {detailsOnClick && mouseClickData !== undefined ? (\r\n        <DetailsModal\r\n          body={detailsOnClick}\r\n          data={mouseClickData}\r\n          setData={setMouseClickData}\r\n          className={classNames?.modal}\r\n        />\r\n      ) : null}\r\n    </>\r\n  );\r\n}\r\n","import orderBy from 'lodash.orderby';\r\nimport { useRef, useState } from 'react';\r\nimport { Colors } from '@/Components/ColorPalette';\r\nimport { ColorLegendWithMouseOver } from '@/Components/Elements/ColorLegendWithMouseOver';\r\nimport { EmptyState } from '@/Components/Elements/EmptyState';\r\nimport { GraphArea, GraphContainer } from '@/Components/Elements/GraphContainer';\r\nimport { GraphFooter } from '@/Components/Elements/GraphFooter';\r\nimport { GraphHeader } from '@/Components/Elements/GraphHeader';\r\nimport { Timeline } from '@/Components/Elements/Timeline';\r\nimport { useElementSize } from '@/hooks/useElementSize';\r\nimport { useTimeline } from '@/hooks/useTimeline';\r\nimport type {\r\n  AnimateDataType,\r\n  ClassNameObject,\r\n  CustomLayerDataType,\r\n  DumbbellChartDataType,\r\n  Languages,\r\n  NumberFormatOptions,\r\n  ReferenceDataType,\r\n  SourcesDataType,\r\n  StyleObject,\r\n  TimelineDataType,\r\n} from '@/Types';\r\nimport { checkIfNullOrUndefined } from '@/Utils/checkIfNullOrUndefined';\r\nimport { ensureCompleteDataForDumbbellChart } from '@/Utils/ensureCompleteData';\r\nimport { HorizontalGraph, VerticalGraph } from './Graph';\r\n\r\ninterface Props {\r\n  // Data\r\n  /** Array of data objects */\r\n  data: DumbbellChartDataType[];\r\n\r\n  /** Orientation of the graph */\r\n  orientation?: 'vertical' | 'horizontal';\r\n\r\n  // Titles, Labels, and Sources\r\n  /** Title of the graph */\r\n  graphTitle?: string | React.ReactNode;\r\n  /** Description of the graph */\r\n  graphDescription?: string | React.ReactNode;\r\n  /** Footnote for the graph */\r\n  footNote?: string | React.ReactNode;\r\n  /** Source data for the graph */\r\n  sources?: SourcesDataType[];\r\n  /** Accessibility label */\r\n  ariaLabel?: string;\r\n\r\n  // Colors and Styling\r\n  /** Array of colors for the circle */\r\n  colors?: string[];\r\n  /** Domain of colors for the graph */\r\n  colorDomain: string[];\r\n  /** Title for the color legend */\r\n  colorLegendTitle?: string;\r\n  /** Color of value labels */\r\n  valueColor?: string;\r\n  /** Background color of the graph */\r\n  backgroundColor?: string | boolean;\r\n  /** Custom styles for the graph. Each object should be a valid React CSS style object. */\r\n  styles?: StyleObject;\r\n  /** Custom class names */\r\n  classNames?: ClassNameObject;\r\n\r\n  // Size and Spacing\r\n  /** Width of the graph */\r\n  width?: number;\r\n  /** Height of the graph */\r\n  height?: number;\r\n  /** Minimum height of the graph */\r\n  minHeight?: number;\r\n  /** Relative height scaling factor. This overwrites the height props */\r\n  relativeHeight?: number;\r\n  /** Padding around the graph. Defaults to 0 if no backgroundColor is mentioned else defaults to 1rem */\r\n  padding?: string;\r\n  /** Left margin of the graph */\r\n  leftMargin?: number;\r\n  /** Right margin of the graph */\r\n  rightMargin?: number;\r\n  /** Top margin of the graph */\r\n  topMargin?: number;\r\n  /** Bottom margin of the graph */\r\n  bottomMargin?: number;\r\n  /** Padding between bars */\r\n  barPadding?: number;\r\n  /** Maximum thickness of bars */\r\n  maxBarThickness?: number;\r\n  /** Minimum thickness of bars */\r\n  minBarThickness?: number;\r\n  /** Maximum number of bars shown in the graph */\r\n  maxNumberOfBars?: number;\r\n  /** Radius of the dots */\r\n  radius?: number;\r\n\r\n  // Values and Ticks\r\n  /** Maximum value for the chart */\r\n  maxValue?: number;\r\n  /** Minimum value for the chart */\r\n  minValue?: number;\r\n  /** Truncate labels by specified length */\r\n  truncateBy?: number;\r\n  /** Reference values for comparison */\r\n  refValues?: ReferenceDataType[];\r\n  /** Number of ticks on the axis */\r\n  noOfTicks?: number;\r\n\r\n  // Graph Parameters\r\n  /** Toggle visibility of labels */\r\n  showLabels?: boolean;\r\n  /** Toggle visibility of values */\r\n  showValues?: boolean;\r\n  /** Custom order for labels */\r\n  labelOrder?: (string | number)[];\r\n  /** Toggle visibility of axis ticks */\r\n  showTicks?: boolean;\r\n  /** Toggle visibility of axis line for the  main axis. Only applicable to vertical charts. */\r\n  hideAxisLine?: boolean;\r\n  /** Toggle visibility of color scale. This is only applicable if the data props hae color parameter */\r\n  showColorScale?: boolean;\r\n  /** Toggle if the is a arrow head at the end of the connector */\r\n  arrowConnector?: boolean;\r\n  /** Toggle if the labels are repositioned to avoid overlapping. Only applicable to horizontal dumbbell charts. */\r\n  repositionOverlappingLabels?: boolean;\r\n  /** Data points to highlight. Use the label value from data to highlight the data point */\r\n  highlightedDataPoints?: (string | number)[];\r\n  /** Defines the opacity of the non-highlighted data */\r\n  dimmedOpacity?: number;\r\n  /** Stroke width of the connector */\r\n  connectorStrokeWidth?: number;\r\n  /** Title for the  axis */\r\n  axisTitle?: string;\r\n  /** Sorting order for data. If this is a number then data is sorted by value at that index x array in the data props. If this is diff then data is sorted by the difference of the last and first element in the x array in the data props. This is overwritten by labelOrder prop */\r\n  sortParameter?: number | 'diff';\r\n  /** Sorting order for data. This is overwritten by labelOrder prop. */\r\n  sortData?: 'asc' | 'desc';\r\n  /** Toggles if data points which have all the values as undefined or null are filtered out.  */\r\n  filterNA?: boolean;\r\n  /** Toggles if the graph animates in when loaded.  */\r\n  animate?: boolean | AnimateDataType;\r\n  /** Configuration options for controlling number formatting, localization, prefixes/suffixes, precision, and zero padding. */\r\n  numberDisplayOptions?: NumberFormatOptions;\r\n  /** Optional SVG <g> element or function that renders custom content behind or in front of the graph. */\r\n  customLayers?: CustomLayerDataType[];\r\n  /** Configures playback and slider controls for animating the chart over time. The data must have a key date for it to work properly. */\r\n  timeline?: TimelineDataType;\r\n  /** Enable graph download option as png */\r\n  graphDownload?: boolean;\r\n  /** Enable data download option as a csv */\r\n  dataDownload?: boolean;\r\n  /** Reset selection on double-click. Only applicable when used in a dashboard context with filters. */\r\n  resetSelectionOnDoubleClick?: boolean;\r\n\r\n  // Interactions and Callbacks\r\n  /** Tooltip content. If the type is string then this uses the [handlebar](../?path=/docs/misc-handlebars-templates-and-custom-helpers--docs) template to display the data */\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  tooltip?: string | ((_d: any) => React.ReactNode);\r\n  /** Details displayed on the modal when user clicks of a data point. If the type is string then this uses the [handlebar](../?path=/docs/misc-handlebars-templates-and-custom-helpers--docs) template to display the data */\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  detailsOnClick?: string | ((_d: any) => React.ReactNode);\r\n  /** Callback for mouse over event */\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  onSeriesMouseOver?: (_d: any) => void;\r\n  /** Callback for mouse click event */\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  onSeriesMouseClick?: (_d: any) => void;\r\n\r\n  // Configuration and Options\r\n  /** Language setting  */\r\n  language?: Languages;\r\n  /** Color theme */\r\n  theme?: 'light' | 'dark';\r\n  /** Unique ID for the graph */\r\n  graphID?: string;\r\n}\r\n\r\nexport function DumbbellChart(props: Props) {\r\n  const {\r\n    data,\r\n    graphTitle,\r\n    colors = Colors.light.categoricalColors.colors,\r\n    sources,\r\n    graphDescription,\r\n    barPadding = 0.25,\r\n    showTicks = true,\r\n    leftMargin,\r\n    rightMargin,\r\n    topMargin,\r\n    bottomMargin,\r\n    truncateBy = 999,\r\n    height,\r\n    width,\r\n    footNote,\r\n    colorDomain,\r\n    colorLegendTitle,\r\n    padding,\r\n    backgroundColor = true,\r\n    radius = 3,\r\n    tooltip,\r\n    showLabels = true,\r\n    relativeHeight,\r\n    onSeriesMouseOver,\r\n    graphID,\r\n    maxValue,\r\n    minValue,\r\n    onSeriesMouseClick,\r\n    graphDownload = false,\r\n    dataDownload = false,\r\n    showValues = true,\r\n    sortParameter,\r\n    arrowConnector = false,\r\n    connectorStrokeWidth = 2,\r\n    language = 'en',\r\n    minHeight = 0,\r\n    theme = 'light',\r\n    maxBarThickness,\r\n    maxNumberOfBars,\r\n    minBarThickness,\r\n    ariaLabel,\r\n    resetSelectionOnDoubleClick = true,\r\n    detailsOnClick,\r\n    axisTitle,\r\n    noOfTicks = 5,\r\n    valueColor,\r\n    orientation = 'vertical',\r\n    styles,\r\n    classNames,\r\n    labelOrder,\r\n    refValues,\r\n    filterNA = true,\r\n    animate = false,\r\n    showColorScale = true,\r\n    customLayers = [],\r\n    highlightedDataPoints,\r\n    dimmedOpacity = 0.3,\r\n    timeline = { enabled: false, autoplay: false, showOnlyActiveDate: true },\r\n    sortData,\r\n    hideAxisLine = false,\r\n    numberDisplayOptions,\r\n    repositionOverlappingLabels = false,\r\n  } = props;\r\n\r\n  const { graphDiv, svgWidth, svgHeight } = useElementSize<HTMLDivElement>();\r\n  const { uniqDatesSorted, index, setIndex, play, setPlay, markObj, activeDate, dateFormat } =\r\n    useTimeline(data, timeline);\r\n  const [selectedColor, setSelectedColor] = useState<string | undefined>(undefined);\r\n  const graphParentDiv = useRef<HTMLDivElement>(null);\r\n  const Comp = orientation === 'horizontal' ? HorizontalGraph : VerticalGraph;\r\n  return (\r\n    <GraphContainer\r\n      className={classNames?.graphContainer}\r\n      style={styles?.graphContainer}\r\n      id={graphID}\r\n      ref={graphParentDiv}\r\n      aria-label={ariaLabel}\r\n      backgroundColor={backgroundColor}\r\n      theme={theme}\r\n      language={language}\r\n      minHeight={minHeight}\r\n      width={width}\r\n      height={height}\r\n      relativeHeight={relativeHeight}\r\n      padding={padding}\r\n    >\r\n      {graphTitle || graphDescription || graphDownload || dataDownload ? (\r\n        <GraphHeader\r\n          styles={{\r\n            title: styles?.title,\r\n            description: styles?.description,\r\n          }}\r\n          classNames={{\r\n            title: classNames?.title,\r\n            description: classNames?.description,\r\n          }}\r\n          graphTitle={graphTitle}\r\n          graphDescription={graphDescription}\r\n          width={width}\r\n          graphDownload={graphDownload ? graphParentDiv : undefined}\r\n          dataDownload={\r\n            dataDownload\r\n              ? data.map((d) => d.data).filter((d) => d !== undefined).length > 0\r\n                ? data.map((d) => d.data).filter((d) => d !== undefined)\r\n                : data.filter((d) => d !== undefined)\r\n              : null\r\n          }\r\n        />\r\n      ) : null}\r\n      {timeline.enabled && uniqDatesSorted.length > 0 && markObj ? (\r\n        <Timeline\r\n          play={play}\r\n          setPlay={setPlay}\r\n          uniqDatesSorted={uniqDatesSorted}\r\n          markObj={markObj}\r\n          index={index}\r\n          setIndex={setIndex}\r\n          color={timeline.color}\r\n        />\r\n      ) : null}\r\n      {showColorScale && data.length > 0 ? (\r\n        <ColorLegendWithMouseOver\r\n          width={width}\r\n          colorDomain={colorDomain}\r\n          colors={colors}\r\n          colorLegendTitle={colorLegendTitle}\r\n          setSelectedColor={setSelectedColor}\r\n          showNAColor={false}\r\n          className={classNames?.colorLegend}\r\n        />\r\n      ) : null}\r\n      <GraphArea ref={graphDiv}>\r\n        {data.length === 0 && <EmptyState />}\r\n        {svgWidth && svgHeight && data.length > 0 ? (\r\n          <Comp\r\n            hideAxisLine={hideAxisLine}\r\n            data={\r\n              sortParameter !== undefined\r\n                ? sortParameter === 'diff'\r\n                  ? orderBy(\r\n                      ensureCompleteDataForDumbbellChart(data, dateFormat)\r\n                        .filter((d) => (timeline.enabled ? `${d.date}` === activeDate : d))\r\n                        .filter((d) => (filterNA ? !d.x.every((item) => item == null) : d)),\r\n                      (d) =>\r\n                        checkIfNullOrUndefined(d.x[d.x.length - 1]) ||\r\n                        checkIfNullOrUndefined(d.x[0])\r\n                          ? -Infinity\r\n                          : (d.x[d.x.length - 1] as number) - (d.x[0] as number),\r\n                      [sortData || 'asc'],\r\n                    ).filter((_d, i) => (maxNumberOfBars ? i < maxNumberOfBars : true))\r\n                  : orderBy(\r\n                      ensureCompleteDataForDumbbellChart(data, dateFormat)\r\n                        .filter((d) => (timeline.enabled ? `${d.date}` === activeDate : d))\r\n                        .filter((d) => (filterNA ? !d.x.every((item) => item == null) : d)),\r\n                      (d) =>\r\n                        checkIfNullOrUndefined(d.x[sortParameter]) ? -Infinity : d.x[sortParameter],\r\n                      [sortData || 'asc'],\r\n                    ).filter((_d, i) => (maxNumberOfBars ? i < maxNumberOfBars : true))\r\n                : ensureCompleteDataForDumbbellChart(data, dateFormat)\r\n                    .filter((d) => (timeline.enabled ? `${d.date}` === activeDate : d))\r\n                    .filter((d) => (filterNA ? !d.x.every((item) => item == null) : d))\r\n                    .filter((_d, i) => (maxNumberOfBars ? i < maxNumberOfBars : true))\r\n            }\r\n            dotColors={colors}\r\n            width={svgWidth}\r\n            height={svgHeight}\r\n            radius={radius}\r\n            barPadding={barPadding}\r\n            showTicks={showTicks}\r\n            leftMargin={leftMargin}\r\n            rightMargin={rightMargin}\r\n            topMargin={topMargin}\r\n            bottomMargin={bottomMargin}\r\n            truncateBy={truncateBy}\r\n            showLabels={showLabels}\r\n            showValues={showValues}\r\n            tooltip={tooltip}\r\n            onSeriesMouseOver={onSeriesMouseOver}\r\n            maxValue={\r\n              !checkIfNullOrUndefined(maxValue)\r\n                ? (maxValue as number)\r\n                : Math.max(...data.map((d) => Math.max(...d.x.filter((el) => el !== null)))) < 0\r\n                  ? 0\r\n                  : Math.max(...data.map((d) => Math.max(...d.x.filter((el) => el !== null))))\r\n            }\r\n            minValue={\r\n              !checkIfNullOrUndefined(minValue)\r\n                ? (minValue as number)\r\n                : Math.min(...data.map((d) => Math.min(...d.x.filter((el) => el !== null)))) > 0\r\n                  ? 0\r\n                  : Math.min(...data.map((d) => Math.min(...d.x.filter((el) => el !== null))))\r\n            }\r\n            onSeriesMouseClick={onSeriesMouseClick}\r\n            selectedColor={selectedColor}\r\n            arrowConnector={arrowConnector}\r\n            connectorStrokeWidth={connectorStrokeWidth}\r\n            maxBarThickness={maxBarThickness}\r\n            minBarThickness={minBarThickness}\r\n            resetSelectionOnDoubleClick={resetSelectionOnDoubleClick}\r\n            detailsOnClick={detailsOnClick}\r\n            axisTitle={axisTitle}\r\n            noOfTicks={noOfTicks}\r\n            valueColor={valueColor}\r\n            styles={styles}\r\n            classNames={classNames}\r\n            labelOrder={labelOrder}\r\n            refValues={refValues}\r\n            animate={\r\n              animate === true\r\n                ? { duration: 0.5, once: true, amount: 0.5 }\r\n                : animate || { duration: 0, once: true, amount: 0 }\r\n            }\r\n            customLayers={customLayers}\r\n            highlightedDataPoints={highlightedDataPoints}\r\n            dimmedOpacity={dimmedOpacity}\r\n            rtl={language === 'ar' || language === 'he'}\r\n            locale={numberDisplayOptions?.locale || 'en'}\r\n            padZeros={numberDisplayOptions?.padZeros || 'none'}\r\n            suffix={numberDisplayOptions?.suffix || ''}\r\n            prefix={numberDisplayOptions?.prefix || ''}\r\n            precision={numberDisplayOptions?.precision ?? 2}\r\n            repositionOverlappingLabels={repositionOverlappingLabels}\r\n          />\r\n        ) : null}\r\n      </GraphArea>\r\n      {sources || footNote ? (\r\n        <GraphFooter\r\n          styles={{ footnote: styles?.footnote, source: styles?.source }}\r\n          classNames={{\r\n            footnote: classNames?.footnote,\r\n            source: classNames?.source,\r\n          }}\r\n          sources={sources}\r\n          footNote={footNote}\r\n          width={width}\r\n        />\r\n      ) : null}\r\n    </GraphContainer>\r\n  );\r\n}\r\n"],"mappings":"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"}