ScatterPlot.tsx 2,69 ko
Newer Older
import React, { useState, useEffect, useMemo } from "react";
import { getDepartmentCorrelation, DepartmentCorrelationParams, TaxType } from "../../../api/stats";
import { DepartmentCorrelationPoint } from "../../../models/DepartmentCorrelation";
import { groupByCommune } from "./scatterplot.utils";
import "./ScatterPlot.css";
import { ScatterPlotControls } from "./ScatterPlotControls";
import { ScatterPlotChart, HoverPoint } from "./ScatterPlotChart"

const ScatterPlot: React.FC = () => {
    const [raw, setRaw] = useState<DepartmentCorrelationPoint[]>([]);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState<string | null>(null);

    const [selectedTax, setSelectedTax] = useState<TaxType>("tfpb");
    const [year, setYear] = useState<number>(2019);
    const [department, setDepartment] = useState<string>("73");
    const [hover, setHover] = useState<HoverPoint | null>(null);
    const [selectedCommune, setSelectedCommune] = useState<string | null>(null);

    useEffect(() => {
        let cancelled = false;

        async function load() {
            try {
            setLoading(true);
            setError(null);

            const params: DepartmentCorrelationParams = { tax: selectedTax, year, department };
            const res = await getDepartmentCorrelation(params);
            if (!cancelled) setRaw(res.member);
            } catch (e: any) {
            if (!cancelled) setError(e.message ?? "Erreur API");
            } finally {
            if (!cancelled) setLoading(false);
            }
        }

        load();
        return () => {
            cancelled = true;
        };
    }, [selectedTax, year, department]);

    const series = useMemo(() => groupByCommune(raw), [raw]);

    if (loading) return <p className="loading-message">Chargement…</p>;
    if (error) return <p className="error-message">Erreur : {error}</p>;
    if (raw.length === 0) return <p className="no-data-message">Aucune donnée.</p>;

    return (
        <div className="scatterplot-container">
          <ScatterPlotControls
            selectedTax={selectedTax}
            year={year}
            department={department}
            onTaxChange={(t) => {
              setSelectedTax(t);
            }}
            onYearChange={(y) => setYear(y)}
            onDepartmentChange={(y) => setSelectedCommune(y)}
          />

          <div className="chart-and-details">
            <ScatterPlotChart
              raw={raw}
              series={series}
              selectedCommune={selectedCommune}
              onHoverChange={setHover}
              onSelectCommune={(commune) => setSelectedCommune(commune)}
            />