Membina Graf Garis Interaktif anda sendiri dalam ReactJS

Patricia Arquette
Lepaskan: 2024-10-31 18:14:30
asal
538 orang telah melayarinya

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;
Salin selepas log masuk

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} />
  );
};
Salin selepas log masuk

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} />
  );
};
Salin selepas log masuk

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

Salin selepas log masuk

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" />
  );
};
Salin selepas log masuk

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>
Salin selepas log masuk

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);
}, []);
Salin selepas log masuk

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 };
};
Salin selepas log masuk

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";
  }
};
Salin selepas log masuk

Akhir sekali, ini akan menjadi struktur komponen graf kami

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

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
/>
Salin selepas log masuk

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!

sumber:dev.to
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!