92 lines
4.1 KiB
TypeScript
92 lines
4.1 KiB
TypeScript
// src/features/legislativas/nacionales/components/MapaProvincial.tsx
|
|
import axios from 'axios';
|
|
import { useEffect } from 'react';
|
|
import { useSuspenseQuery } from '@tanstack/react-query';
|
|
import { Geographies, Geography } from 'react-simple-maps';
|
|
import { geoCentroid } from 'd3-geo';
|
|
import { feature } from 'topojson-client';
|
|
import { API_BASE_URL, assetBaseUrl } from '../../../../apiService';
|
|
import type { ResultadoMapaDto, AmbitoGeography } from '../../../../types/types';
|
|
|
|
const DEFAULT_MAP_COLOR = '#E0E0E0';
|
|
const normalizarTexto = (texto: string = ''): string => texto.trim().toUpperCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
|
|
type PointTuple = [number, number];
|
|
|
|
interface MapaProvincialProps {
|
|
eleccionId: number;
|
|
categoriaId: number;
|
|
distritoId: string;
|
|
nombreProvincia: string;
|
|
nombreMunicipioSeleccionado: string | null;
|
|
nivel: 'provincia' | 'municipio';
|
|
onMunicipioSelect: (ambitoId: string, nombre: string) => void;
|
|
onCalculatedCenter: (center: PointTuple, zoom: number) => void;
|
|
}
|
|
|
|
export const MapaProvincial = ({ eleccionId, categoriaId, distritoId, nombreProvincia, nombreMunicipioSeleccionado, nivel, onMunicipioSelect, onCalculatedCenter }: MapaProvincialProps) => {
|
|
const { data: mapaData = [] } = useSuspenseQuery<ResultadoMapaDto[]>({
|
|
queryKey: ['mapaResultados', eleccionId, categoriaId, distritoId],
|
|
queryFn: async () => {
|
|
const url = `${API_BASE_URL}/elecciones/${eleccionId}/mapa-resultados?categoriaId=${categoriaId}&distritoId=${distritoId}`;
|
|
const response = await axios.get(url);
|
|
return response.data;
|
|
},
|
|
});
|
|
|
|
const { data: geoData } = useSuspenseQuery<any>({
|
|
queryKey: ['geoDataProvincial', nombreProvincia],
|
|
queryFn: async () => {
|
|
const nombreNormalizado = nombreProvincia.toLowerCase().replace(/ /g, '_');
|
|
const mapFile = `departamentos-${nombreNormalizado}.topojson`;
|
|
return axios.get(`${assetBaseUrl}/maps/${mapFile}`).then(res => res.data);
|
|
},
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (nivel === 'municipio' && geoData?.objects && nombreMunicipioSeleccionado) {
|
|
const geometries = geoData.objects[Object.keys(geoData.objects)[0]].geometries;
|
|
const municipioGeo = geometries.find((g: any) => normalizarTexto(g.properties.departamento) === normalizarTexto(nombreMunicipioSeleccionado));
|
|
if (municipioGeo) {
|
|
const municipioFeature = feature(geoData, municipioGeo);
|
|
const centroid = geoCentroid(municipioFeature);
|
|
if(nombreProvincia.toUpperCase() === 'CAPITAL FEDERAL'){
|
|
onCalculatedCenter(centroid as PointTuple, 180);
|
|
} else {
|
|
onCalculatedCenter(centroid as PointTuple, 40);
|
|
}
|
|
}
|
|
}
|
|
}, [nivel, nombreMunicipioSeleccionado, geoData, onCalculatedCenter]);
|
|
|
|
const resultadosPorNombre = new Map<string, ResultadoMapaDto>(mapaData.map(d => [normalizarTexto(d.ambitoNombre), d]));
|
|
const esCABA = normalizarTexto(nombreProvincia) === "CAPITAL FEDERAL";
|
|
|
|
return (
|
|
<Geographies geography={geoData}>
|
|
{({ geographies }: { geographies: AmbitoGeography[] }) => geographies.map((geo) => {
|
|
const resultado = resultadosPorNombre.get(normalizarTexto(geo.properties.departamento));
|
|
const esSeleccionado = nombreMunicipioSeleccionado ? normalizarTexto(geo.properties.departamento) === normalizarTexto(nombreMunicipioSeleccionado) : false;
|
|
|
|
const classNames = [
|
|
'rsm-geography',
|
|
'mapa-provincial-geography',
|
|
esSeleccionado ? 'selected' : '',
|
|
nombreMunicipioSeleccionado && !esSeleccionado ? 'rsm-geography-faded-municipality' : '',
|
|
esCABA ? 'caba-comuna-geography' : ''
|
|
].filter(Boolean).join(' ');
|
|
|
|
return (
|
|
<Geography
|
|
key={geo.rsmKey}
|
|
geography={geo}
|
|
className={classNames}
|
|
fill={resultado?.colorGanador || DEFAULT_MAP_COLOR}
|
|
onClick={resultado ? () => onMunicipioSelect(resultado.ambitoId.toString(), resultado.ambitoNombre) : undefined}
|
|
data-tooltip-id="mapa-tooltip"
|
|
data-tooltip-content={geo.properties.departamento}
|
|
/>
|
|
);
|
|
})}
|
|
</Geographies>
|
|
);
|
|
}; |