Maison > Article > interface Web > Créer votre propre graphique linéaire interactif dans ReactJS
Tout d'abord, créons un composant SVG simple qui accepte la largeur et la hauteur comme accessoires. Ce sera le point de départ de notre graphique.
import React from "react"; const LineGraph = ({ height, width }) => { return <svg height={height} width={width}></svg>; }; export default LineGraph;
Maintenant, ajoutons l'axe X, qui s'étend horizontalement sur le graphique. Nous utiliserons la ligne
const drawXAxis = () => { const middleY = height / 2; return ( <line x1={0} y1={middleY} x2={width} y2={middleY} stroke={lineColor} /> ); };
Nous utiliserons une autre
const drawYAxis = () => { const middleX = width / 2; return ( <line x1={middleX} y1={0} x2={middleX} y2={height} stroke={lineColor} /> ); };
L'élément clé d'un graphique linéaire est la ligne reliant différents points. Traçons quelques exemples de coordonnées et connectons-les à l'aide d'un SVG.
const drawPath = () => { const pathData = coordinates .map((coordinate, index) => index === 0 ? `M ${coordinate.x} ${coordinate.y}` : `L ${coordinate.x} ${coordinate.y}` ) .join(" "); return <path d={pathData} stroke={pathColor} fill="none" />; };
Nous pouvons remplir la zone sous la ligne avec une couleur pour améliorer le graphique. Cela peut être fait en utilisant un élément supplémentaire. Considérez prop isFillArea pour afficher/masquer cette zone.
const drawPath = () => { const pathData = coordinates .map((coordinate, index) => index === 0 ? `M ${coordinate.x} ${coordinate.y}` : `L ${coordinate.x} ${coordinate.y}` ) .join(" "); const middleY = height / 2; const svgPath = showFillArea ? `${pathData} L ${width} ${middleY} L 0 ${middleY} Z` : pathData; const fillColor = showFillArea ? areaColor : "none"; return ( <path d={svgPath} fill={fillColor} stroke={pathColor} opacity="0.5" /> ); };
Ajoutons un cercle qui suit le mouvement du curseur sur le chemin du graphique.
Nous aurons besoin d'une référence de notre composant SVG pour accéder à la boîte englobante de l'élément SVG. Également une référence pour notre cercle de suivi qui sera utilisé pour suivre le curseur sur le graphique.
const svgRef = useRef(); const circleRef = useRef(); // ... const drawTrackingCircle = () => { return ( <circle ref={circleRef} r={6} fill="red" style={{ display: "none" }} // Initially hidden /> ); }; // ... <svg ref={svgRef} width={width} height={height}> // ... </svg>
Ensuite, nous devons ajouter un écouteur d'événement à notre élément SVG. Cela écoutera tous les mouvements de notre curseur sur le graphique.
useEffect(() => { const svgElement = svgRef.current; svgElement.addEventListener("mousemove", handleMouseMove); // clean up return () => svgElement.removeEventListener("mousemove", handleMouseMove); }, []);
Ensuite, nous avons besoin d'une méthode pour trouver la coordonnée d'intersection entre la position du curseur et le chemin.
const getIntersectionPoint = (cursorX) => { // Find the segment (p1, p2) where cursorX lies between two consecutive coordinates. const segment = coordinates.find((p1, i) => { // Get the next point const p2 = coordinates[i + 1]; // Check if cursorX falls between the two coordinates horizontally. return ( p2 && ((p1.x <= cursorX && p2.x >= cursorX) || (p1.x >= cursorX && p2.x <= cursorX)) ); }); // Return null if no valid segment is found. if (!segment) return null; // Destructure the two coordinates in the segment. const [p1, p2] = [segment, coordinates[coordinates.indexOf(segment) + 1]]; // Calculate 't' to determine the relative position between p1 and p2. const t = (cursorX - p1.x) / (p2.x - p1.x); // Interpolate the Y-coordinate using 't'. const y = p1.y + t * (p2.y - p1.y); return { x: cursorX, y }; };
Méthode de suivi des mouvements du curseur. Il utilise la méthode getIntersectionPoint pour trouver la coordonnée d'intersection actuelle.
const handleMouseMove = (event) => { // Get SVG position const svgRect = svgRef.current.getBoundingClientRect(); // Calculate cursor's X within the SVG const cursorX = event.clientX - svgRect.left; // Find the intersection point const intersectionPoint = getIntersectionPoint(cursorX); if (intersectionPoint) { // Move the intersection circle to the calculated point circleRef.current.setAttribute("cx", intersectionPoint.x); circleRef.current.setAttribute("cy", intersectionPoint.y); circleRef.current.style.display = "block"; } };
Enfin, ce serait la structure de notre composant graphique
return ( <svg ref={svgRef} height={height} width={width}> {drawPath()} {drawXAxis()} {drawYAxis()} {drawTrackingCircle()} {drawDataPointCircles()} </svg> );
Voici comment nous pouvons utiliser notre composant Graph
<LineGraph width={300} height={400} coordinates={samplePoints} lineColor="#000" pathColor="#00008B" areaColor="#ADD8E6" dataPointColor="#008000" showFillArea showDataPointCircle />
Lien Codesandbox pour la démo LineGraph
Photo du blog par Isaac Smith sur Unsplash
Merci d'avoir lu ❤
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!