{"version":3,"file":"BiVariateMap-jImVk9OS.cjs","names":[],"sources":["../src/Components/Graphs/Maps/BiVariateMap/Graph.tsx","../src/Components/Graphs/Maps/BiVariateMap/index.tsx"],"sourcesContent":["import { cn } from '@undp/design-system-react/cn';\r\nimport { P } from '@undp/design-system-react/Typography';\r\nimport { geoPath } from 'd3-geo';\r\nimport { scaleThreshold } from 'd3-scale';\r\nimport isEqual from 'fast-deep-equal';\r\nimport type { FeatureCollection } from 'geojson';\r\nimport { AnimatePresence, motion, useInView } from 'motion/react';\r\nimport { type RefObject, useMemo, useRef, useState } from 'react';\r\nimport type { Topology } from 'topojson-specification';\r\nimport { CsvDownloadButton } from '@/Components/Actions/CsvDownloadButton';\r\nimport { ImageDownloadButton } from '@/Components/Actions/ImageDownloadButton';\r\nimport { DetailsModal } from '@/Components/Elements/DetailsModal';\r\nimport {\r\n  LegendCollapseButton,\r\n  LegendExpandButton,\r\n} from '@/Components/Elements/LegendExpandControls';\r\nimport { MapZoomButton } from '@/Components/Elements/MapZoomButton';\r\nimport { Tooltip } from '@/Components/Elements/Tooltip';\r\nimport { useMapProjection } from '@/hooks/useMapProjection';\r\nimport { useMapZoom } from '@/hooks/useMapZoom';\r\nimport type {\r\n  AnimateDataType,\r\n  BivariateMapDataType,\r\n  ClassNameObject,\r\n  CustomLayerDataType,\r\n  MapProjectionTypes,\r\n  NumberFormatOptions,\r\n  StyleObject,\r\n  ZoomInteractionTypes,\r\n} from '@/Types';\r\nimport { convertTopoJsonToGeoJson } from '@/Utils';\r\nimport { checkIfNullOrUndefined } from '@/Utils/checkIfNullOrUndefined';\r\nimport { numberFormattingFunction } from '@/Utils/numberFormattingFunction';\r\nimport AksaiChinStriped from '../shapeFile/aksaiChinStriped.json';\r\n\r\ninterface Props {\r\n  data: BivariateMapDataType[];\r\n  mapData: FeatureCollection;\r\n  mapBorderData?: FeatureCollection;\r\n  xDomain: number[];\r\n  yDomain: number[];\r\n  width: number;\r\n  height: number;\r\n  colors: string[][];\r\n  xColorLegendTitle: string;\r\n  yColorLegendTitle: string;\r\n  mapBorderWidth: number;\r\n  mapNoDataColor: string;\r\n  scale: number;\r\n  centerPoint?: [number, number];\r\n  mapBorderColor: string;\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  tooltip?: string | ((_d: any) => React.ReactNode);\r\n  zoomInteraction: ZoomInteractionTypes;\r\n  mapProjection: MapProjectionTypes;\r\n\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  onSeriesMouseOver?: (_d: any) => void;\r\n  zoomScaleExtend: [number, number];\r\n  zoomTranslateExtend?: [[number, number], [number, number]];\r\n  highlightedIds?: string[];\r\n\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  onSeriesMouseClick?: (_d: any) => void;\r\n  mapProperty: string;\r\n  resetSelectionOnDoubleClick: boolean;\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  detailsOnClick?: string | ((_d: any) => React.ReactNode);\r\n  showColorScale: boolean;\r\n  collapseColorScaleByDefault?: boolean;\r\n  styles?: StyleObject;\r\n  classNames?: ClassNameObject;\r\n  animate: AnimateDataType;\r\n  dimmedOpacity: number;\r\n  customLayers: CustomLayerDataType[];\r\n  zoomAndCenterByHighlightedIds: boolean;\r\n  projectionRotate: [number, number] | [number, number, number];\r\n  overlayMapData?: FeatureCollection;\r\n  overlayMapBorderColor?: string;\r\n  overlayMapBorderWidth?: number;\r\n  xNumberDisplayOptions?: Omit<NumberFormatOptions, 'suffix' | 'prefix'>;\r\n  yNumberDisplayOptions?: Omit<NumberFormatOptions, 'suffix' | 'prefix'>;\r\n  graphDownload?: RefObject<HTMLDivElement | null>;\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  dataDownload: any;\r\n  showUNBorder: boolean;\r\n  showAksaiChinAsStriped: boolean;\r\n  isDisputedAreasInteractive: boolean;\r\n}\r\n\r\nexport function Graph(props: Props) {\r\n  const {\r\n    data,\r\n    xDomain,\r\n    mapData,\r\n    xColorLegendTitle,\r\n    yDomain,\r\n    yColorLegendTitle,\r\n    width,\r\n    height,\r\n    colors,\r\n    scale,\r\n    centerPoint,\r\n    mapBorderWidth,\r\n    mapNoDataColor,\r\n    mapBorderColor,\r\n    tooltip,\r\n    onSeriesMouseOver,\r\n    zoomScaleExtend,\r\n    zoomTranslateExtend,\r\n    highlightedIds,\r\n    onSeriesMouseClick,\r\n    mapProperty,\r\n    resetSelectionOnDoubleClick,\r\n    detailsOnClick,\r\n    showColorScale,\r\n    styles,\r\n    classNames,\r\n    mapProjection,\r\n    zoomInteraction,\r\n    animate,\r\n    dimmedOpacity,\r\n    customLayers,\r\n    collapseColorScaleByDefault,\r\n    zoomAndCenterByHighlightedIds,\r\n    projectionRotate,\r\n    overlayMapData,\r\n    overlayMapBorderColor,\r\n    overlayMapBorderWidth,\r\n    xNumberDisplayOptions,\r\n    yNumberDisplayOptions,\r\n    graphDownload,\r\n    dataDownload,\r\n    mapBorderData,\r\n    showUNBorder,\r\n    showAksaiChinAsStriped,\r\n    isDisputedAreasInteractive,\r\n  } = props;\r\n\r\n  const aksaiChinStripedGeoJson = useMemo(\r\n    () => convertTopoJsonToGeoJson(AksaiChinStriped as unknown as Topology, 'stripes'),\r\n    [],\r\n  );\r\n  const [showLegend, setShowLegend] = useState(\r\n    collapseColorScaleByDefault === undefined ? !(width < 680) : !collapseColorScaleByDefault,\r\n  );\r\n  const [selectedColor, setSelectedColor] = useState<string | undefined>(undefined);\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  const [mouseClickData, setMouseClickData] = useState<any>(undefined);\r\n  // biome-ignore lint/suspicious/noExplicitAny: undefined data type\r\n  const [mouseOverData, setMouseOverData] = useState<any>(undefined);\r\n  const [eventX, setEventX] = useState<number | undefined>(undefined);\r\n  const [eventY, setEventY] = useState<number | undefined>(undefined);\r\n  const mapSvg = useRef<SVGSVGElement>(null);\r\n  const mapG = useRef<SVGGElement>(null);\r\n\r\n  const { handleZoom } = useMapZoom({\r\n    mapSvg,\r\n    mapG,\r\n    width,\r\n    height,\r\n    zoomInteraction,\r\n    zoomScaleExtend,\r\n    zoomTranslateExtend,\r\n  });\r\n  const { projection } = useMapProjection({\r\n    mapData,\r\n    mapProperty,\r\n    zoomAndCenterByHighlightedIds,\r\n    highlightedIds: highlightedIds || [],\r\n    width,\r\n    height,\r\n    mapProjection,\r\n    scale,\r\n    centerPoint,\r\n    projectionRotate,\r\n  });\r\n  const isInView = useInView(mapSvg, {\r\n    once: animate.once,\r\n    amount: animate.amount,\r\n  });\r\n\r\n  const pathGenerator = geoPath().projection(projection);\r\n  const xRange = Array.from({ length: xDomain.length }, (_, i) => i);\r\n\r\n  const yRange = Array.from({ length: yDomain.length }, (_, i) => i);\r\n  const xScale = scaleThreshold<number, number>().domain(xDomain).range(xRange);\r\n  const yScale = scaleThreshold<number, number>().domain(yDomain).range(yRange);\r\n\r\n  return (\r\n    <>\r\n      <div className='relative'>\r\n        <motion.svg\r\n          viewBox={`0 0 ${width} ${height}`}\r\n          width={`${width}px`}\r\n          height={`${height}px`}\r\n          ref={mapSvg}\r\n          direction='ltr'\r\n        >\r\n          <g ref={mapG}>\r\n            {customLayers.filter((d) => d.position === 'before').map((d) => d.layer)}\r\n            {mapData.features.map((d, i: number) => {\r\n              if (!d.properties?.[mapProperty]) return null;\r\n              const path = pathGenerator(d);\r\n              if (!path) return null;\r\n              return (\r\n                <motion.g\r\n                  // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                  key={i}\r\n                  opacity={\r\n                    selectedColor\r\n                      ? dimmedOpacity\r\n                      : highlightedIds\r\n                        ? highlightedIds.indexOf(d.properties[mapProperty]) !== -1\r\n                          ? d.properties?.iso3cd?.[0] !== 'x' || isDisputedAreasInteractive\r\n                            ? 1\r\n                            : dimmedOpacity\r\n                          : dimmedOpacity\r\n                        : 1\r\n                  }\r\n                >\r\n                  <path\r\n                    d={path}\r\n                    style={{\r\n                      fill: mapNoDataColor,\r\n                      vectorEffect: 'non-scaling-stroke',\r\n                    }}\r\n                  />\r\n                </motion.g>\r\n              );\r\n            })}\r\n            <AnimatePresence>\r\n              {data.map((d) => {\r\n                const features = mapData.features.filter(\r\n                  (el) => d.id === el.properties?.[mapProperty],\r\n                );\r\n                if (features.length === 0) return null;\r\n                const xColorCoord = !checkIfNullOrUndefined(d.x)\r\n                  ? xScale(d.x as number)\r\n                  : undefined;\r\n                const yColorCoord = !checkIfNullOrUndefined(d.y)\r\n                  ? yScale(d.y as number)\r\n                  : undefined;\r\n                const color =\r\n                  xColorCoord !== undefined && yColorCoord !== undefined\r\n                    ? colors[yColorCoord][xColorCoord]\r\n                    : mapNoDataColor;\r\n\r\n                return (\r\n                  <motion.g\r\n                    className='undp-map-shapes'\r\n                    key={d.id}\r\n                    variants={{\r\n                      initial: { opacity: 0 },\r\n                      whileInView: {\r\n                        opacity: 1,\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                    onMouseEnter={(event) => {\r\n                      setMouseOverData(d);\r\n                      setEventY(event.clientY);\r\n                      setEventX(event.clientX);\r\n                      onSeriesMouseOver?.(d);\r\n                    }}\r\n                    onMouseMove={(event) => {\r\n                      setMouseOverData(d);\r\n                      setEventY(event.clientY);\r\n                      setEventX(event.clientX);\r\n                    }}\r\n                    onClick={() => {\r\n                      if (onSeriesMouseClick || detailsOnClick) {\r\n                        if (isEqual(mouseClickData, d) && resetSelectionOnDoubleClick) {\r\n                          setMouseClickData(undefined);\r\n                          onSeriesMouseClick?.(undefined);\r\n                        } else {\r\n                          setMouseClickData(d);\r\n                          onSeriesMouseClick?.(d);\r\n                        }\r\n                      }\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                  >\r\n                    {features.map((feature, i) => {\r\n                      const path = pathGenerator(feature);\r\n                      if (!path) return null;\r\n                      return (\r\n                        <motion.path\r\n                          key={`${d.id}-${\r\n                            // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                            i\r\n                          }`}\r\n                          d={path}\r\n                          variants={{\r\n                            initial: { fill: color, opacity: 0 },\r\n                            whileInView: {\r\n                              fill: color,\r\n                              opacity: selectedColor\r\n                                ? selectedColor === color\r\n                                  ? 1\r\n                                  : dimmedOpacity\r\n                                : mouseOverData\r\n                                  ? mouseOverData.id === d.id\r\n                                    ? 1\r\n                                    : dimmedOpacity\r\n                                  : highlightedIds\r\n                                    ? highlightedIds.indexOf(d.id) !== -1\r\n                                      ? feature.properties?.iso3cd?.[0] !== 'x' ||\r\n                                        isDisputedAreasInteractive\r\n                                        ? 1\r\n                                        : dimmedOpacity\r\n                                      : dimmedOpacity\r\n                                    : 1,\r\n                              pointerEvents:\r\n                                feature.properties?.iso3cd?.[0] === 'x' &&\r\n                                !isDisputedAreasInteractive\r\n                                  ? 'none'\r\n                                  : 'auto',\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                      );\r\n                    })}\r\n                  </motion.g>\r\n                );\r\n              })}\r\n              {showAksaiChinAsStriped &&\r\n                aksaiChinStripedGeoJson?.features.map((d, i: number) => {\r\n                  const path = pathGenerator(d);\r\n                  const dataForCHN = data.find((el) => el.id === 'CHN');\r\n                  const xColorCoord = !checkIfNullOrUndefined(dataForCHN?.x)\r\n                    ? xScale(dataForCHN?.x as number)\r\n                    : undefined;\r\n                  const yColorCoord = !checkIfNullOrUndefined(dataForCHN?.y)\r\n                    ? yScale(dataForCHN?.y as number)\r\n                    : undefined;\r\n                  const color =\r\n                    xColorCoord !== undefined && yColorCoord !== undefined\r\n                      ? colors[yColorCoord][xColorCoord]\r\n                      : mapNoDataColor;\r\n                  if (!path) return null;\r\n                  return (\r\n                    <motion.g\r\n                      // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                      key={`aksai-chin-stripped-${i}`}\r\n                      variants={{\r\n                        initial: { opacity: 0 },\r\n                        whileInView: {\r\n                          opacity: selectedColor || highlightedIds?.length ? dimmedOpacity : 1,\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                      <motion.path\r\n                        d={path}\r\n                        // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                        key={`aksai-chin-stripped-${i}`}\r\n                        variants={{\r\n                          initial: { fill: color, opacity: 0 },\r\n                          whileInView: {\r\n                            fill: color,\r\n                            opacity: 1,\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                    </motion.g>\r\n                  );\r\n                })}\r\n            </AnimatePresence>\r\n            {showUNBorder &&\r\n              (mapBorderData || mapData)?.features.map((d, i: number) => {\r\n                if (!d.properties?.[mapBorderData ? 'iso3cd' : mapProperty]) return null;\r\n                const path = pathGenerator(d);\r\n                if (!path || d.properties?.bdytyp === 99) return null;\r\n                return (\r\n                  <motion.g\r\n                    // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                    key={i}\r\n                  >\r\n                    <path\r\n                      d={path}\r\n                      style={{\r\n                        stroke: mapBorderColor,\r\n                        strokeWidth:\r\n                          d.properties?.bdytyp === 3 || d.properties?.bdytyp === 4\r\n                            ? Math.max(1, mapBorderWidth)\r\n                            : mapBorderWidth,\r\n                        fill: 'none',\r\n                        vectorEffect: 'non-scaling-stroke',\r\n                        strokeDasharray:\r\n                          d.properties?.bdytyp === 3\r\n                            ? '3 3'\r\n                            : d.properties?.bdytyp === 4\r\n                              ? '2 2'\r\n                              : undefined,\r\n                      }}\r\n                    />\r\n                  </motion.g>\r\n                );\r\n              })}\r\n            {overlayMapData?.features.map((d, i: number) => {\r\n              const path = pathGenerator(d);\r\n              if (!path) return null;\r\n              return (\r\n                // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                <g key={i}>\r\n                  <path\r\n                    d={path}\r\n                    style={{\r\n                      stroke: overlayMapBorderColor || mapBorderColor,\r\n                      strokeWidth: overlayMapBorderWidth || mapBorderWidth + 1,\r\n                      fill: 'none',\r\n                      pointerEvents: 'none',\r\n                      vectorEffect: 'non-scaling-stroke',\r\n                    }}\r\n                  />\r\n                </g>\r\n              );\r\n            })}\r\n            {customLayers.filter((d) => d.position === 'after').map((d) => d.layer)}\r\n          </g>\r\n        </motion.svg>\r\n        {showColorScale === false ? null : (\r\n          <div className={cn('absolute left-4 bottom-4 map-color-legend', classNames?.colorLegend)}>\r\n            {showLegend ? (\r\n              <>\r\n                <LegendCollapseButton setExpanded={setShowLegend} />\r\n                <div className='color-legend-box p-2 bg-surface-sm/70' style={{ width: '175px' }}>\r\n                  <div className='flex gap-1 items-center'>\r\n                    <svg width='136px' viewBox='0 0 136 136' className='shrink-0'>\r\n                      <g>\r\n                        {colors.map((d, i) => (\r\n                          // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                          <g key={i} transform={`translate(0,${100 - i * 25})`}>\r\n                            {d.map((el, j) => (\r\n                              // biome-ignore lint/a11y/noStaticElementInteractions: interaction for color legend\r\n                              <rect\r\n                                // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                                key={j}\r\n                                y={1}\r\n                                x={j * 25 + 1}\r\n                                fill={el}\r\n                                width={23}\r\n                                height={23}\r\n                                strokeWidth={selectedColor === el ? 2 : 0.25}\r\n                                style={{ cursor: 'pointer' }}\r\n                                onMouseOver={() => {\r\n                                  setSelectedColor(el);\r\n                                }}\r\n                                onFocus={() => {\r\n                                  setSelectedColor(el);\r\n                                }}\r\n                                onMouseLeave={() => {\r\n                                  setSelectedColor(undefined);\r\n                                }}\r\n                              />\r\n                            ))}\r\n                          </g>\r\n                        ))}\r\n                        <g transform='translate(0,125)'>\r\n                          {xDomain.map((el, j) => (\r\n                            // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                            <text key={j} y={10} x={(j + 1) * 25} fontSize={10} textAnchor='middle'>\r\n                              {typeof el === 'string' || el < 1\r\n                                ? el\r\n                                : numberFormattingFunction(\r\n                                    el,\r\n                                    undefined,\r\n                                    xNumberDisplayOptions?.precision ?? 2,\r\n                                    undefined,\r\n                                    undefined,\r\n                                    xNumberDisplayOptions?.locale || 'en',\r\n                                    xNumberDisplayOptions?.padZeros || 'none',\r\n                                  )}\r\n                            </text>\r\n                          ))}\r\n                        </g>\r\n                        {yDomain.map((el, j) => (\r\n                          <g\r\n                            // biome-ignore lint/suspicious/noArrayIndexKey: index is the unique identifier\r\n                            key={j}\r\n                            transform={`translate(${\r\n                              Math.max(Math.min(xDomain.length + 1, 5), 4) * 25 + 10\r\n                            },${100 - j * 25})`}\r\n                          >\r\n                            <text\r\n                              x={0}\r\n                              transform='rotate(-90)'\r\n                              y={0}\r\n                              fontSize={10}\r\n                              textAnchor='middle'\r\n                            >\r\n                              {typeof el === 'string' || el < 1\r\n                                ? el\r\n                                : numberFormattingFunction(\r\n                                    el,\r\n                                    undefined,\r\n                                    yNumberDisplayOptions?.precision ?? 2,\r\n                                    undefined,\r\n                                    undefined,\r\n                                    yNumberDisplayOptions?.locale || 'en',\r\n                                    yNumberDisplayOptions?.padZeros || 'none',\r\n                                  )}\r\n                            </text>\r\n                          </g>\r\n                        ))}\r\n                      </g>\r\n                    </svg>\r\n                    <P\r\n                      marginBottom='none'\r\n                      size='xs'\r\n                      className='leading-normal text-center shrink-0'\r\n                      style={{\r\n                        display: '-webkit-box',\r\n                        WebkitLineClamp: '1',\r\n                        WebkitBoxOrient: 'vertical',\r\n                        overflow: 'hidden',\r\n                        writingMode: 'vertical-rl',\r\n                        height: '8.5rem',\r\n                        transform: 'rotate(180deg)',\r\n                      }}\r\n                    >\r\n                      {yColorLegendTitle}\r\n                    </P>\r\n                  </div>\r\n                  <P\r\n                    marginBottom='none'\r\n                    size='xs'\r\n                    className='mt-1 leading-normal text-center'\r\n                    style={{\r\n                      display: '-webkit-box',\r\n                      WebkitLineClamp: '1',\r\n                      width: '8.5rem',\r\n                      WebkitBoxOrient: 'vertical',\r\n                      overflow: 'hidden',\r\n                    }}\r\n                  >\r\n                    {xColorLegendTitle}\r\n                  </P>\r\n                </div>\r\n              </>\r\n            ) : (\r\n              <LegendExpandButton setExpanded={setShowLegend} />\r\n            )}\r\n          </div>\r\n        )}\r\n        {zoomInteraction === 'button' && <MapZoomButton handleZoom={handleZoom} />}\r\n        {(graphDownload || dataDownload) && (\r\n          <div className='absolute right-4 top-4 flex flex-col image-download-button gap-2'>\r\n            {graphDownload && (\r\n              <ImageDownloadButton nodeID={graphDownload} buttonSmall className='p-1' />\r\n            )}\r\n            {dataDownload && dataDownload.length > 0 && (\r\n              <CsvDownloadButton\r\n                csvData={dataDownload}\r\n                buttonSmall\r\n                headers={Object.keys(dataDownload[0]).map((d) => ({\r\n                  label: d,\r\n                  key: d,\r\n                }))}\r\n                className='p-1'\r\n              />\r\n            )}\r\n          </div>\r\n        )}\r\n      </div>\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 { Spinner } from '@undp/design-system-react/Spinner';\r\nimport type { FeatureCollection } from 'geojson';\r\nimport { useRef } from 'react';\r\nimport type { Topology } from 'topojson-specification';\r\nimport { Colors } from '@/Components/ColorPalette';\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 { useMapShapeData } from '@/hooks/useMapShapeData';\r\nimport { useTimeline } from '@/hooks/useTimeline';\r\nimport type {\r\n  AnimateDataType,\r\n  BivariateMapDataType,\r\n  ClassNameObject,\r\n  CustomLayerDataType,\r\n  Languages,\r\n  MapOverlayDataType,\r\n  MapProjectionTypes,\r\n  NumberFormatOptions,\r\n  SourcesDataType,\r\n  StyleObject,\r\n  TimelineDataType,\r\n  ZoomInteractionTypes,\r\n} from '@/Types';\r\nimport { getJenks } from '@/Utils/getJenks';\r\nimport { Graph } from './Graph';\r\n\r\ninterface Props {\r\n  // Data\r\n  /** Array of data objects. */\r\n  data: BivariateMapDataType[];\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  /** Colors for the choropleth map. Array must be 5x5 */\r\n  colors?: string[][];\r\n  /** Title for the first color legend */\r\n  xColorLegendTitle?: string;\r\n  /** Title for the second color legend */\r\n  yColorLegendTitle?: string;\r\n  /** Domain of x-colors for the map */\r\n  xDomain?: number[];\r\n  /** Domain of y-colors for the map */\r\n  yDomain?: number[];\r\n  /** Color for the areas where data is no available */\r\n  mapNoDataColor?: 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\r\n  // Graph Parameters\r\n  /** Map data as an object in geoJson format or a url for geoJson */\r\n  mapData?: FeatureCollection | Topology | string;\r\n  /** Detail if any other map needs to be overlayed over the main map */\r\n  mapOverlay?: MapOverlayDataType;\r\n  /** Defines if the coordinates in the map data should be rewinded or not. Try to change this is the visualization shows countries as holes instead of shapes. */\r\n  rewindCoordinatesInMapData?: boolean;\r\n  /** Scaling factor for the map. Multiplies the scale number to scale. */\r\n  scale?: number;\r\n  /** Center point of the map */\r\n  centerPoint?: [number, number];\r\n  /** Controls the rotation of the map projection, in degrees, applied before rendering. Useful for shifting the antimeridian to focus the map on different regions */\r\n  projectionRotate?: [number, number] | [number, number, number];\r\n  /** Defines the zoom mode for the map */\r\n  zoomInteraction?: ZoomInteractionTypes;\r\n  /** Stroke width of the regions in the map */\r\n  mapBorderWidth?: number;\r\n  /** Stroke color of the regions in the map */\r\n  mapBorderColor?: string;\r\n  /** Toggle if the UN border are shown. */\r\n  showUNBorder?: boolean;\r\n  /** Toggle if the coastal border is shown. Only applicable if default world map is used */\r\n  showCostalBorder?: boolean;\r\n  /** Toggle if the map is a world map */\r\n  isWorldMap?: boolean;\r\n  /** Toggle if the disputed areas are interactive. The way it works is it check for a property name `iso3cd` in map shape data if it starts with 'x' then the area is considered disputed. */\r\n  isDisputedAreasInteractive?: boolean;\r\n  /** Map projection type */\r\n  mapProjection?: MapProjectionTypes;\r\n  /** Toggle if the map is centered and zoomed to the highlighted ids. */\r\n  zoomAndCenterByHighlightedIds?: boolean;\r\n  /** Extend of the allowed zoom in the map */\r\n  zoomScaleExtend?: [number, number];\r\n  /** Extend of the allowed panning in the map */\r\n  zoomTranslateExtend?: [[number, number], [number, number]];\r\n  /** Countries or regions to be highlighted */\r\n  highlightedIds?: string[];\r\n  /** Defines the opacity of the non-highlighted data */\r\n  dimmedOpacity?: number;\r\n  /** Toggles if the graph animates in when loaded.  */\r\n  animate?: boolean | AnimateDataType;\r\n  /** Property in the property object in mapData geoJson object is used to match to the id in the data object */\r\n  mapProperty?: string;\r\n  /** Toggle visibility of color scale. */\r\n  showColorScale?: boolean;\r\n  /** Toggle if color scale is collapsed by default. */\r\n  collapseColorScaleByDefault?: boolean;\r\n  /** Show Aksai Chin as striped */\r\n  showAksaiChinAsStriped?: boolean;\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  /** Configuration options for controlling number formatting, localization, precision, and zero padding. */\r\n  xNumberDisplayOptions?: Omit<NumberFormatOptions, 'suffix' | 'prefix'>;\r\n  /** Configuration options for controlling number formatting, localization, precision, and zero padding. */\r\n  yNumberDisplayOptions?: Omit<NumberFormatOptions, 'suffix' | 'prefix'>;\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 BiVariateChoroplethMap(props: Props) {\r\n  const {\r\n    data,\r\n    graphTitle,\r\n    mapData,\r\n    colors = Colors.light.bivariateColors.colors05x05,\r\n    sources,\r\n    graphDescription,\r\n    height,\r\n    width,\r\n    footNote = 'The designations employed and the presentation of material on this map do not imply the expression of any opinion whatsoever on the part of the Secretariat of the United Nations or UNDP concerning the legal status of any country, territory, city or area or its authorities, or concerning the delimitation of its frontiers or boundaries.',\r\n    xDomain,\r\n    yDomain,\r\n    xColorLegendTitle = 'X Color key',\r\n    yColorLegendTitle = 'Y Color key',\r\n    tooltip,\r\n    scale = 0.95,\r\n    centerPoint,\r\n    padding,\r\n    mapBorderWidth = 0.5,\r\n    mapNoDataColor = Colors.light.graphNoData,\r\n    backgroundColor = false,\r\n    mapBorderColor = Colors.light.grays['gray-500'],\r\n    relativeHeight,\r\n    onSeriesMouseOver,\r\n    isWorldMap = true,\r\n    zoomScaleExtend = [0.8, 6],\r\n    zoomTranslateExtend,\r\n    graphID,\r\n    showColorScale = true,\r\n    highlightedIds,\r\n    onSeriesMouseClick,\r\n    mapProperty = 'isoclr3',\r\n    graphDownload = false,\r\n    dataDownload = false,\r\n    language = 'en',\r\n    minHeight = 0,\r\n    theme = 'light',\r\n    ariaLabel,\r\n    resetSelectionOnDoubleClick = true,\r\n    detailsOnClick,\r\n    styles,\r\n    classNames,\r\n    mapProjection,\r\n    zoomInteraction = 'button',\r\n    animate = false,\r\n    dimmedOpacity = 0.3,\r\n    customLayers = [],\r\n    timeline = { enabled: false, autoplay: false, showOnlyActiveDate: true },\r\n    collapseColorScaleByDefault,\r\n    zoomAndCenterByHighlightedIds = false,\r\n    projectionRotate = [-10, 0],\r\n    rewindCoordinatesInMapData = true,\r\n    mapOverlay,\r\n    xNumberDisplayOptions,\r\n    yNumberDisplayOptions,\r\n    showCostalBorder = false,\r\n    showUNBorder,\r\n    showAksaiChinAsStriped = true,\r\n    isDisputedAreasInteractive = false,\r\n  } = props;\r\n  const { graphDiv, svgWidth, svgHeight } = useElementSize<HTMLDivElement>();\r\n  const { uniqDatesSorted, index, setIndex, play, setPlay, markObj, activeDate } = useTimeline(\r\n    data,\r\n    timeline,\r\n  );\r\n  const { mapShape, mapBorderShape, overlayMapShape } = useMapShapeData(\r\n    mapData,\r\n    mapOverlay?.mapData,\r\n    rewindCoordinatesInMapData,\r\n    showCostalBorder,\r\n    showUNBorder,\r\n  );\r\n  const graphParentDiv = useRef<HTMLDivElement>(null);\r\n\r\n  if (xDomain && yDomain)\r\n    if (xDomain.length !== colors[0].length - 1 || yDomain.length !== colors.length - 1) {\r\n      console.error(\"the xDomain and yDomain array length don't match to the color array length\");\r\n      return null;\r\n    }\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 ? (\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        />\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      <GraphArea ref={graphDiv}>\r\n        {svgWidth && svgHeight && mapShape && (mapBorderShape || !mapData) ? (\r\n          <Graph\r\n            data={data.filter((d) => (timeline.enabled ? `${d.date}` === activeDate : d))}\r\n            mapData={mapShape}\r\n            mapBorderData={\r\n              mapBorderShape\r\n                ? {\r\n                    ...mapBorderShape,\r\n                    features: mapBorderShape.features.filter(\r\n                      (el) => el.properties?.iso3cd !== 'ATA',\r\n                    ),\r\n                  }\r\n                : mapBorderShape\r\n            }\r\n            xDomain={\r\n              xDomain ||\r\n              getJenks(\r\n                data.map((d) => d.x as number | null | undefined),\r\n                colors[0].length,\r\n              )\r\n            }\r\n            yDomain={\r\n              yDomain ||\r\n              getJenks(\r\n                data.map((d) => d.y as number | null | undefined),\r\n                colors.length,\r\n              )\r\n            }\r\n            width={svgWidth}\r\n            height={svgHeight}\r\n            scale={scale}\r\n            centerPoint={centerPoint}\r\n            colors={colors}\r\n            xColorLegendTitle={xColorLegendTitle}\r\n            yColorLegendTitle={yColorLegendTitle}\r\n            mapBorderWidth={mapBorderWidth}\r\n            mapNoDataColor={mapNoDataColor}\r\n            mapBorderColor={mapBorderColor}\r\n            tooltip={tooltip}\r\n            onSeriesMouseOver={onSeriesMouseOver}\r\n            zoomScaleExtend={zoomScaleExtend}\r\n            zoomTranslateExtend={zoomTranslateExtend}\r\n            onSeriesMouseClick={onSeriesMouseClick}\r\n            mapProperty={!mapData && !mapProperty ? 'isoclr3' : mapProperty}\r\n            highlightedIds={highlightedIds}\r\n            resetSelectionOnDoubleClick={resetSelectionOnDoubleClick}\r\n            styles={styles}\r\n            showColorScale={showColorScale}\r\n            classNames={classNames}\r\n            mapProjection={mapProjection || (isWorldMap ? 'naturalEarth' : 'mercator')}\r\n            detailsOnClick={detailsOnClick}\r\n            zoomInteraction={zoomInteraction}\r\n            overlayMapData={overlayMapShape}\r\n            overlayMapBorderColor={mapOverlay?.mapBorderColor}\r\n            overlayMapBorderWidth={mapOverlay?.mapBorderWidth}\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            dimmedOpacity={dimmedOpacity}\r\n            customLayers={customLayers}\r\n            collapseColorScaleByDefault={collapseColorScaleByDefault}\r\n            zoomAndCenterByHighlightedIds={zoomAndCenterByHighlightedIds}\r\n            projectionRotate={projectionRotate}\r\n            xNumberDisplayOptions={xNumberDisplayOptions}\r\n            yNumberDisplayOptions={yNumberDisplayOptions}\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            showUNBorder={showUNBorder ?? true}\r\n            showAksaiChinAsStriped={showAksaiChinAsStriped}\r\n            isDisputedAreasInteractive={isDisputedAreasInteractive}\r\n          />\r\n        ) : (\r\n          <div\r\n            style={{\r\n              height: `${Math.max(\r\n                minHeight,\r\n                height ||\r\n                  (relativeHeight\r\n                    ? minHeight\r\n                      ? (width || svgWidth) * relativeHeight > minHeight\r\n                        ? (width || svgWidth) * relativeHeight\r\n                        : minHeight\r\n                      : (width || svgWidth) * relativeHeight\r\n                    : svgHeight),\r\n              )}px`,\r\n            }}\r\n            className='flex items-center justify-center'\r\n          >\r\n            <Spinner aria-label='Loading graph' />\r\n          </div>\r\n        )}\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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"}