Maison > interface Web > js tutoriel > le corps du texte

Créer votre propre graphique linéaire interactif dans ReactJS

Patricia Arquette
Libérer: 2024-10-31 18:14:30
original
536 Les gens l'ont consulté

Building your own Interactive Line Graph in ReactJS

Composant SVG de base

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;
Copier après la connexion

Ajout de l'axe X

Maintenant, ajoutons l'axe X, qui s'étend horizontalement sur le graphique. Nous utiliserons la ligne élément pour cela.

const drawXAxis = () => {
  const middleY = height / 2;

  return (
    <line x1={0} y1={middleY} x2={width} y2={middleY} stroke={lineColor} />
  );
};
Copier après la connexion

Ajout de l'axe Y

Nous utiliserons une autre élément pour dessiner l'axe Y, qui passera verticalement par le centre du graphique.

const drawYAxis = () => {
  const middleX = width / 2;

  return (
    <line x1={middleX} y1={0} x2={middleX} y2={height} stroke={lineColor} />
  );
};
Copier après la connexion

Tracer des coordonnées sous forme de chemin de ligne

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" />;
  };

Copier après la connexion

Option pour remplir la zone sous la ligne

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" />
  );
};
Copier après la connexion

Suivi du curseur

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>
Copier après la connexion

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);
}, []);
Copier après la connexion

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 };
};
Copier après la connexion

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";
  }
};
Copier après la connexion

Enfin, ce serait la structure de notre composant graphique

return (
  <svg ref={svgRef} height={height} width={width}>
    {drawPath()}
    {drawXAxis()}
    {drawYAxis()}
    {drawTrackingCircle()}
    {drawDataPointCircles()}
  </svg>
);
Copier après la connexion

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
/>
Copier après la connexion

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!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!