{ kembali"/> { kembali">

Rumah  >  Artikel  >  hujung hadapan web  >  Membina Graf Garis Interaktif anda sendiri dalam ReactJS

Membina Graf Garis Interaktif anda sendiri dalam ReactJS

Patricia Arquette
Patricia Arquetteasal
2024-10-31 18:14:30538semak imbas

Building your own Interactive Line Graph in ReactJS

Komponen SVG Asas

Mula-mula, mari buat komponen SVG mudah yang menerima lebar dan tinggi sebagai prop. Ini akan menjadi titik permulaan untuk graf kami.

import React from "react";

const LineGraph = ({ height, width }) => {
  return <svg height={height} width={width}></svg>;
};

export default LineGraph;

Menambah Paksi-X

Sekarang, mari tambah paksi-X, yang berjalan secara mendatar merentasi graf. Kami akan menggunakan elemen untuk ini.

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

  return (
    <line x1={0} y1={middleY} x2={width} y2={middleY} stroke={lineColor} />
  );
};

Menambah Y-Axis

Kami akan menggunakan elemen untuk melukis paksi-Y, yang akan berjalan secara menegak melalui tengah graf.

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

  return (
    <line x1={middleX} y1={0} x2={middleX} y2={height} stroke={lineColor} />
  );
};

Memplot koordinat sebagai laluan garisan

Bahagian utama graf garis ialah garis yang menghubungkan titik yang berbeza. Mari kita plot beberapa koordinat sampel dan sambungkannya menggunakan 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" />;
  };

Pilihan untuk mengisi kawasan di bawah garisan

Kita boleh mengisi kawasan di bawah garisan dengan warna untuk meningkatkan graf. Ini boleh dilakukan menggunakan elemen tambahan. Pertimbangkan prop isFillArea untuk menunjukkan/menyembunyikan kawasan ini.

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

Menjejak kursor

Mari tambahkan bulatan yang mengikuti pergerakan kursor merentasi laluan graf.

Kami memerlukan rujukan komponen SVG kami untuk mengakses kotak sempadan elemen SVG. Juga rujukan untuk bulatan penjejakan kami yang akan digunakan untuk menjejak kursor di atas graf.

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>

Kemudian, kami perlu menambah pendengar acara pada elemen SVG kami. Ini akan mendengar semua pergerakan kursor kami di atas graf.

useEffect(() => {
  const svgElement = svgRef.current;
  svgElement.addEventListener("mousemove", handleMouseMove);

  // clean up
  return () => svgElement.removeEventListener("mousemove", handleMouseMove);
}, []);

Seterusnya, kita memerlukan kaedah untuk mencari koordinat persimpangan antara kedudukan kursor dan laluan.

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

Kaedah penjejak pergerakan kursor. Ia menggunakan kaedah getIntersectionPoint untuk mencari koordinat persimpangan semasa.

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

Akhir sekali, ini akan menjadi struktur komponen graf kami

return (
  <svg ref={svgRef} height={height} width={width}>
    {drawPath()}
    {drawXAxis()}
    {drawYAxis()}
    {drawTrackingCircle()}
    {drawDataPointCircles()}
  </svg>
);

Ini adalah cara kami boleh menggunakan komponen Graf kami

<LineGraph
  width={300}
  height={400}
  coordinates={samplePoints}
  lineColor="#000"
  pathColor="#00008B"
  areaColor="#ADD8E6"
  dataPointColor="#008000"
  showFillArea
  showDataPointCircle
/>

Pautan kotak kod untuk tunjuk cara LineGraph

Foto Blog oleh Isaac Smith di Unsplash

Terima kasih kerana membaca ❤

Atas ialah kandungan terperinci Membina Graf Garis Interaktif anda sendiri dalam ReactJS. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn