Erstellen wir zunächst eine einfache SVG-Komponente, die Breite und Höhe als Requisiten akzeptiert. Dies wird der Ausgangspunkt für unsere Grafik sein.
import React from "react"; const LineGraph = ({ height, width }) => { return <svg height={height} width={width}></svg>; }; export default LineGraph;
Jetzt fügen wir die X-Achse hinzu, die horizontal über das Diagramm verläuft. Wir verwenden die
const drawXAxis = () => { const middleY = height / 2; return ( <line x1={0} y1={middleY} x2={width} y2={middleY} stroke={lineColor} /> ); };
Wir verwenden eine andere
const drawYAxis = () => { const middleX = width / 2; return ( <line x1={middleX} y1={0} x2={middleX} y2={height} stroke={lineColor} /> ); };
Der wichtigste Teil eines Liniendiagramms ist die Linie, die verschiedene Punkte verbindet. Lassen Sie uns einige Beispielkoordinaten zeichnen und sie mithilfe einer SVG-Datei verbinden.
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" />; };
Wir können den Bereich unter der Linie mit einer Farbe füllen, um das Diagramm zu verbessern. Dies kann über ein zusätzliches Element erfolgen. Erwägen Sie die Verwendung von isFillArea, um diesen Bereich anzuzeigen/auszublenden.
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" /> ); };
Fügen wir einen Kreis hinzu, der der Bewegung des Cursors über den Diagrammpfad folgt.
Wir benötigen eine Referenz unserer SVG-Komponente, um auf den Begrenzungsrahmen des SVG-Elements zuzugreifen. Außerdem eine Referenz für unseren Tracking-Kreis, der zum Verfolgen des Cursors über dem Diagramm verwendet wird.
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>
Dann müssen wir unserem SVG-Element einen Ereignis-Listener hinzufügen. Dadurch werden alle unsere Cursorbewegungen über dem Diagramm abgehört.
useEffect(() => { const svgElement = svgRef.current; svgElement.addEventListener("mousemove", handleMouseMove); // clean up return () => svgElement.removeEventListener("mousemove", handleMouseMove); }, []);
Als nächstes benötigen wir eine Methode, um die Schnittkoordinate zwischen der Cursorposition und dem Pfad zu finden.
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 }; };
Cursorbewegungs-Tracker-Methode. Es verwendet die Methode getIntersectionPoint, um die aktuelle Schnittpunktkoordinate zu ermitteln.
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"; } };
Schließlich wäre dies die Struktur unserer Diagrammkomponente
return ( <svg ref={svgRef} height={height} width={width}> {drawPath()} {drawXAxis()} {drawYAxis()} {drawTrackingCircle()} {drawDataPointCircles()} </svg> );
So können wir unsere Graph-Komponente verwenden
<LineGraph width={300} height={400} coordinates={samplePoints} lineColor="#000" pathColor="#00008B" areaColor="#ADD8E6" dataPointColor="#008000" showFillArea showDataPointCircle />
Codesandbox-Link für die LineGraph-Demo
Blogfoto von Isaac Smith auf Unsplash
Danke fürs Lesen ❤
Das obige ist der detaillierte Inhalt vonErstellen Sie Ihr eigenes interaktives Liniendiagramm in ReactJS. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!