Ajout de la gestion des références pour le défilement fluide dans les composants graphiques et Clarrification du code

This commit is contained in:
Mathis 2025-04-04 11:47:17 +02:00
parent ffa19ba1ba
commit fa1135eaf9
7 changed files with 104 additions and 111 deletions

View File

@ -1,23 +1,21 @@
import React, {useRef} from "react"; import React from "react";
import { ChartLine } from "lucide-react"; import { ChartLine } from "lucide-react";
function BoutonGraphique({ TypeAff, setAffichage,graphCible}) {
const handleClick = (newAffichage) =>{ function BoutonGraphique({ type, setGraphStates, graphStates, graphCible }) {
setAffichage(newAffichage); const handleClick = () => {
if(graphCible.current){ setGraphStates((prev) => ({ ...prev, [type]: !prev[type] }));
graphCible.current.scrollIntoView({ behavior: "smooth" });
}
}; };
return !TypeAff ? ( return !graphStates[type] ? (
<button <button
className="bg-blue-200 py-2 my-2 px-4 rounded-full mr-2" className="bg-blue-200 py-2 my-2 px-4 rounded-full mr-2"
onClick={() => handleClick(true)} onClick={handleClick}
> >
<ChartLine className="text-indigo-600" size={24} /> <ChartLine className="text-indigo-600" size={24} />
</button> </button>
) : ( ) : (
<button <button
className="bg-blue-400 py-2 my-2 px-4 rounded-full mr-2" className="bg-blue-400 py-2 my-2 px-4 rounded-full mr-2"
onClick={() => handleClick(false)} onClick={handleClick}
> >
<ChartLine className="text-indigo-600" size={24} /> <ChartLine className="text-indigo-600" size={24} />
</button> </button>

View File

@ -3,8 +3,8 @@ import { Info } from "lucide-react";
function InfoObject({ object,defafficherModif }) { function InfoObject({ object,defafficherModif }) {
return ( return (
<div key={object.id} className="bg-white p-6 rounded-xl min-w-5xl"> <div key={object.id} className="bg-white p-6 rounded-xl min-w-5xl">
<div className="flex align-items gap-6"> <div className="flex align-items gap-6 mb-6">
<div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-1"> <div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-1">
<Info className="text-indigo-600" size={24} /> <Info className="text-indigo-600" size={24} />
</div> </div>

View File

@ -15,7 +15,7 @@ import { Wind } from "lucide-react";
import axios from "axios"; import axios from "axios";
import { API_BASE_URL } from "../config"; import { API_BASE_URL } from "../config";
function MeteoGraph({ object, categorie, Logo }) { function MeteoGraph({ object, categorie, Logo,reference}) {
const [rawData, setRawData] = useState([]); const [rawData, setRawData] = useState([]);
const identifiant = object.id; const identifiant = object.id;
useEffect(() => { useEffect(() => {
@ -23,7 +23,11 @@ function MeteoGraph({ object, categorie, Logo }) {
setRawData(response.data); setRawData(response.data);
}); });
}, [object]); }, [object]);
useEffect(() => {
if (reference?.current) {
reference.current.scrollIntoView({ behavior: "smooth" });
}
}, [reference]);
function getAvg() { function getAvg() {
let moyenne = 0; let moyenne = 0;
rawData.forEach((element) => { rawData.forEach((element) => {
@ -35,9 +39,11 @@ function MeteoGraph({ object, categorie, Logo }) {
} }
return ( return (
<div <div
ref={reference}
key={object.id} key={object.id}
className="bg-white mb-6 p-6 rounded-xl min-w-5xl" className="bg-white mb-6 p-6 rounded-xl min-w-5xl"
style={{ width: "100%", height: "400px" }} style={{ width: "100%", height: "400px" }}
> >
<div className="flex align-items gap-6"> <div className="flex align-items gap-6">
<div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4"> <div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4">

View File

@ -8,13 +8,9 @@ import AlertInactive from "./AlertInactive";
function MeteoInfos({ function MeteoInfos({
object, object,
defAffTempGraph, graphStates,
AffTempGraph, setGraphStates,
defAffPressionGraph, graphRefs
AffPressionGraph,
defAffHumiditeGraph,
AffHumiditeGraph,
graphCible
}) { }) {
const [rawData, setRawData] = useState([]); const [rawData, setRawData] = useState([]);
const [AffAlert,setAffAlert] = useState(false); const [AffAlert,setAffAlert] = useState(false);
@ -30,7 +26,6 @@ function MeteoInfos({
}, [object]); }, [object]);
const lastData = rawData.length > 0 ? rawData[rawData.length - 1] : null; const lastData = rawData.length > 0 ? rawData[rawData.length - 1] : null;
console.log(rawData.length);
return ( return (
<div key={object.id} className="bg-white p-6 rounded-xl min-w-5xl"> <div key={object.id} className="bg-white p-6 rounded-xl min-w-5xl">
{(AffAlert&&(object.status==="active")) && ( {(AffAlert&&(object.status==="active")) && (
@ -61,9 +56,10 @@ function MeteoInfos({
</div> </div>
</div> </div>
<BoutonGraphique <BoutonGraphique
TypeAff={AffTempGraph} type="temperature"
setAffichage={defAffTempGraph} graphStates={graphStates}
graphCible={graphCible} setGraphStates={setGraphStates}
graphCible={graphRefs.temperature}
/> />
</div> </div>
@ -86,9 +82,10 @@ function MeteoInfos({
</div> </div>
</div> </div>
<BoutonGraphique <BoutonGraphique
TypeAff={AffPressionGraph} type="pressure"
setAffichage={defAffPressionGraph} graphStates={graphStates}
graphCible={graphCible} setGraphStates={setGraphStates}
graphCible={graphRefs.pressure}
/> />
</div> </div>
</div> </div>
@ -110,8 +107,10 @@ function MeteoInfos({
</div> </div>
</div> </div>
<BoutonGraphique <BoutonGraphique
TypeAff={AffHumiditeGraph} type="humidity"
setAffichage={defAffHumiditeGraph} graphStates={graphStates}
setGraphStates={setGraphStates}
graphCible={graphRefs.humidity}
/> />
</div> </div>
</div> </div>

View File

@ -5,7 +5,7 @@ import { Wind } from "lucide-react";
import axios from "axios"; import axios from "axios";
import { API_BASE_URL } from "../config"; import { API_BASE_URL } from "../config";
function WindGraph({ object }) { function WindGraph({ object,reference }) {
const [rawData, setRawData] = useState([]); const [rawData, setRawData] = useState([]);
const identifiant = object.id; const identifiant = object.id;
useEffect(() => { useEffect(() => {
@ -27,8 +27,13 @@ function WindGraph({ object }) {
return null; // Si aucun point n'est survolé return null; // Si aucun point n'est survolé
}; };
useEffect(() => {
if (reference?.current) {
reference.current.scrollIntoView({ behavior: "smooth" });
}
}, [reference]);
return ( return (
<div key={object.id} className="bg-white mb-6 p-6 rounded-xl min-w-5xl" style={{width: "100%", height: "400px"}}> <div key={object.id} ref={reference} className="bg-white mb-6 p-6 rounded-xl min-w-5xl" style={{width: "100%", height: "400px"}}>
<div className="flex align-items gap-6"> <div className="flex align-items gap-6">
<div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4"> <div className="w-12 h-12 bg-indigo-100 rounded-lg flex items-center justify-center mb-4">
<Wind className="text-indigo-600" size={24} /> <Wind className="text-indigo-600" size={24} />

View File

@ -5,7 +5,7 @@ import axios from "axios";
import { API_BASE_URL } from "../config"; import { API_BASE_URL } from "../config";
import BoutonGraphique from "./BoutonGraphique"; import BoutonGraphique from "./BoutonGraphique";
function WindInfo({ object, defAffWindGraph, AffWindGraph }) { function WindInfo({ object, setGraphStates, graphStates, graphRefs, reference}) {
const [rawData, setRawData] = useState([]); const [rawData, setRawData] = useState([]);
const identifiant = object.id; const identifiant = object.id;
useEffect(() => { useEffect(() => {
@ -13,6 +13,11 @@ function WindInfo({ object, defAffWindGraph, AffWindGraph }) {
setRawData(response.data); setRawData(response.data);
}); });
}, [object]); }, [object]);
useEffect(() => {
if (reference?.current) {
reference.current.scrollIntoView({ behavior: "smooth" });
}
}, [reference]);
const lastData = rawData.length > 0 ? rawData[rawData.length - 1] : null; const lastData = rawData.length > 0 ? rawData[rawData.length - 1] : null;
@ -47,9 +52,11 @@ function WindInfo({ object, defAffWindGraph, AffWindGraph }) {
</h1> </h1>
</div> </div>
</div> </div>
<BoutonGraphique <BoutonGraphique
TypeAff={AffWindGraph} type="wind"
setAffichage={defAffWindGraph} graphStates={graphStates}
setGraphStates={setGraphStates}
graphCible={graphRefs.wind}
/> />
</div> </div>
</div> </div>

View File

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import { Thermometer, CircleGauge, Droplet } from "lucide-react"; import { Thermometer, CircleGauge, Droplet } from "lucide-react";
import { useEffect, useState, useRef} from "react"; import { useEffect, useState, useRef } from "react";
import axios from "axios"; import axios from "axios";
import { API_BASE_URL } from "../../config"; import { API_BASE_URL } from "../../config";
@ -14,31 +14,27 @@ import MeteoGraph from "../../components/MeteoGraph";
import BatterieInfo from "../../components/BatterieInfo"; import BatterieInfo from "../../components/BatterieInfo";
function Objet() { function Objet() {
const identifiant = new URLSearchParams(window.location.search).get("id"); const identifiant = new URLSearchParams(window.location.search).get("id");
const [searchQuery, setSearchQuery] = useState("");
const [activeFilter, setActiveFilter] = useState("all");
const [object, setObject] = useState({}); const [object, setObject] = useState({});
const [graphStates, setGraphStates] = useState({ const [graphStates, setGraphStates] = useState({
wind:false, wind: false,
temperature:false, temperature: false,
pressure:false, pressure: false,
humidity:false, humidity: false,
}) });
const [afficherModif, defafficherModif] = useState(false); const [afficherModif, defafficherModif] = useState(false);
const [AffWindGraph, defAffWindGraph] = useState(false); const graphRefs = {
const [AffTempGraph, defAffTempGraph] = useState(false); temperature: useRef(null),
const [AffPressionGraph, defAffPressionGraph] = useState(false); pressure: useRef(null),
const [AffHumiditeGraph, defAffHumideGraph] = useState(false); humidity: useRef(null),
const tempGraphRef = useRef(null); wind: useRef(null),
const pressureGraphRef = useRef(null); };
const humidityGraphRef = useRef(null);
const windGraphRef = useRef(null);
useEffect(() => { useEffect(() => {
axios.get(`${API_BASE_URL}/objet?id=${identifiant}`).then((response) => { axios.get(`${API_BASE_URL}/objet?id=${identifiant}`).then((response) => {
setObject(response.data[0]); setObject(response.data[0]);
}); });
}, [identifiant]); }, [identifiant]);
return ( return object && object.id ? (
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50"> <div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-50">
<div className=" max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12"> <div className=" max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div className="text-center mb-5"> <div className="text-center mb-5">
@ -52,68 +48,50 @@ function Objet() {
) : ( ) : (
<ModifObject object={object} defafficherModif={defafficherModif} /> <ModifObject object={object} defafficherModif={defafficherModif} />
)} )}
<WindInfo
{object && object.id ? ( object={object}
<WindInfo setGraphStates={setGraphStates}
object={object} graphStates={graphStates}
defAffWindGraph={defAffWindGraph} graphRefs={graphRefs}
AffWindGraph={AffWindGraph} />
/> <MeteoInfos
) : ( object={object}
<p>Chargement des données...</p> graphStates={graphStates}
)} setGraphStates={setGraphStates}
{object && object.id ? ( graphRefs={graphRefs}
<MeteoInfos />
object={object}
defAffTempGraph={defAffTempGraph}
AffTempGraph={AffTempGraph}
defAffPressionGraph={defAffPressionGraph}
AffPressionGraph={AffPressionGraph}
defAffHumiditeGraph={defAffHumideGraph}
AffHumiditeGraph={AffHumiditeGraph}
tempGraphRef={tempGraphRef}
pressureGraphRef={pressureGraphRef}
humidityGraphRef={humidityGraphRef}
/>
) : (
<p>Chargement des données...</p>
)}
<BatterieInfo object={object} /> <BatterieInfo object={object} />
</div> </div>
{AffWindGraph &&
(object && object.id ? ( {graphStates.wind && <WindGraph object={object} reference={graphRefs.wind} />}
<WindGraph object={object} /> {graphStates.temperature && (
) : ( <MeteoGraph
<p>Chargement des données...</p> object={object}
))} categorie={"temperature"}
{AffTempGraph && Logo={Thermometer}
(object && object.id ? ( reference={graphRefs.temperature}
<MeteoGraph />
object={object} )}
categorie={"temperature"} {graphStates.pressure && (
Logo={Thermometer} <MeteoGraph
/> object={object}
) : ( categorie={"pressure"}
<p>Chargement des données...</p> Logo={CircleGauge}
))} reference={graphRefs.pressure}
{AffPressionGraph && />
(object && object.id ? ( )}
<MeteoGraph {graphStates.humidity && (
object={object} <MeteoGraph
categorie={"pressure"} object={object}
Logo={CircleGauge} categorie={"humidity"}
/> Logo={Droplet}
) : ( reference={graphRefs.humidity}
<p>Chargement des données...</p> />
))} )}
{AffHumiditeGraph &&
(object && object.id ? (
<MeteoGraph object={object} categorie={"humidity"} Logo={Droplet} />
) : (
<p>Chargement des données...</p>
))}
</div> </div>
</div> </div>
) : (
<h1>Erreur de récupération de l'objet</h1>
); );
} }
export default Objet; export default Objet;