bar_chart.tsx 6,53 ko
Newer Older
Thibault Fouchet's avatar
Thibault Fouchet a validé
import React, {useState, useEffect, useRef} from "react";
import * as d3 from "d3";

const BarChart = () => {
  const [data, setData] = useState<{ date: string; value: number }[]>([]);
  const [filterType, setFilterType] = useState("year");
  const [startDate, setStartDate] = useState("");
  const [endDate, setEndDate] = useState("");
  const chartRef = useRef<SVGSVGElement>(null);


  const fetchData = async () => {
    const result = [
      { date: "2018-01-01", value: 21050 },
      { date: "2018-02-01", value: 21050 },
      { date: "2018-03-01", value: 21050 },
      { date: "2018-04-01", value: 21050 },
      { date: "2018-05-01", value: 21050 },
      { date: "2018-06-01", value: 21050 },
      { date: "2018-07-01", value: 21050 },
      { date: "2018-08-01", value: 21050 },
      { date: "2018-09-01", value: 21050 },
      { date: "2018-10-01", value: 21050 },
      { date: "2018-11-01", value: 21050 },
      { date: "2018-12-01", value: 21050 },
      { date: "2019-01-01", value: 28203 },
      { date: "2019-02-01", value: 21050 },
      { date: "2019-03-01", value: 21050 },
      { date: "2019-04-01", value: 21050 },
      { date: "2019-05-01", value: 21050 },
      { date: "2019-06-01", value: 21050 },
      { date: "2019-07-01", value: 21050 },
      { date: "2019-08-01", value: 21050 },
      { date: "2019-09-01", value: 21050 },
      { date: "2019-10-01", value: 21050 },
      { date: "2019-11-01", value: 21050 },
      { date: "2019-12-01", value: 21050 },
      { date: "2020-01-01", value: 27420 },
      { date: "2020-02-01", value: 27420 },
      { date: "2020-03-01", value: 27420 },
      { date: "2020-04-01", value: 27420 },
      { date: "2020-05-01", value: 21050 },
      { date: "2020-06-01", value: 21050 },
      { date: "2020-07-01", value: 21050 },
      { date: "2020-08-01", value: 21050 },
      { date: "2020-09-01", value: 21050 },
      { date: "2020-10-01", value: 21050 },
      { date: "2020-11-01", value: 21050 },
      { date: "2020-12-01", value: 21050 },
      { date: "2021-01-01", value: 24128 },
      { date: "2021-02-01", value: 24128 },
      { date: "2021-03-01", value: 24128 },
      { date: "2021-04-01", value: 24128 },
      { date: "2021-05-01", value: 24128 },
      { date: "2021-06-01", value: 24128 },
      { date: "2021-07-01", value: 24128 },
      { date: "2021-08-01", value: 24128 },
      { date: "2021-09-01", value: 24128 },
      { date: "2021-10-01", value: 24128 },
      { date: "2021-11-01", value: 24128 },
      { date: "2021-12-01", value: 24128 },
      { date: "2022-01-01", value: 38806 },
      { date: "2022-02-01", value: 38806 },
      { date: "2022-03-01", value: 38806 },
      { date: "2022-04-01", value: 38806 },
      { date: "2022-05-01", value: 38806 },
      { date: "2022-06-01", value: 38806 },
      { date: "2022-07-01", value: 38806 },
      { date: "2022-08-01", value: 38806 },
      { date: "2022-09-01", value: 38806 },
      { date: "2022-10-01", value: 38806 },
      { date: "2022-11-01", value: 38806 },
      { date: "2022-12-01", value: 38806 },
      { date: "2023-01-01", value: 12999 },
      { date: "2023-02-01", value: 12999 },
      { date: "2023-03-01", value: 12999 },
      { date: "2023-04-01", value: 12999 },
      { date: "2023-05-01", value: 12999 },
      { date: "2023-06-01", value: 12999 },
      { date: "2023-07-01", value: 12999 },
      { date: "2023-08-01", value: 12999 },
      { date: "2023-09-01", value: 12999 },
      { date: "2023-10-01", value: 12999 },
      { date: "2023-11-01", value: 12999 },
      { date: "2023-12-01", value: 12999 },
    ];
    console.log("Fetching data:", result);
    setData(result);
  };
  useEffect(() => {
    fetchData();
  }, []);

  useEffect(() => {
    const filteredData = data.filter((entry) => {
      const entryDate = new Date(entry.date);

      if (filterType === "year") {
        const startYear = new Date(`${startDate}T00:00:00`).getFullYear();
        const endYear = new Date(`${endDate}T23:59:59`).getFullYear();
        const entryYear = entryDate.getFullYear();

        const isInRange = entryYear >= startYear && entryYear <= endYear;
        return isInRange;
      } else if (filterType === "month") {
        const isInRange = entryDate >= new Date(`${startDate}T00:00:00`) && entryDate <= new Date(`${endDate}T23:59:59`);
        return isInRange;
      }

      return false;
    });

    const svg = d3.select(chartRef.current);
    svg.selectAll("*").remove();

    const margin = { top: 20, right: 20, bottom: 60, left: 40 };
    const width = 800 - margin.left - margin.right;
    const height = 400 - margin.top - margin.bottom;

    const x = d3.scaleBand()
      .domain(filteredData.map((d) => d.date))
      .range([0, width])
      .padding(0.1);

    const y = d3.scaleLinear()
      .domain([0, d3.max(filteredData, (d) => d.value) || 0])
      .range([height, 0]);

    const xAxis = d3.axisBottom(x)
      .tickFormat((d) => d)
      .tickSizeOuter(0);
    const yAxis = d3.axisLeft(y);

    svg.append("g")
      .attr("transform", `translate(${margin.left},${height + margin.top})`)
      .call(xAxis)
      .selectAll("text")
      .style("text-anchor", "end")
      .attr("dx", "-.8em")
      .attr("dy", ".15em")
      .attr("transform", "rotate(-45)");

    svg.append("g")
      .attr("transform", `translate(${margin.left},${margin.top})`)
      .call(yAxis);

    svg.selectAll("rect")
      .data(filteredData)
      .enter().append("rect")
      .attr("x", (d) => x(d.date) + margin.left)
      .attr("width", x.bandwidth())
      .attr("y", (d) => y(d.value) + margin.top)
      .attr("height", (d) => height - y(d.value))
      .attr("fill", "steelblue");

  }, [data, filterType, startDate, endDate]);


  const applyChanges = async () => {
    console.log("Applying changes");
    await fetchData();
  };

  return (
    <div>
      <div>
        <label>
          Affichage par :
          <select value={filterType} onChange={(e) => setFilterType(e.target.value)}>
            <option value="year">Année</option>
            <option value="month">Mois</option>
          </select>
        </label>
      </div>
      <div>
        <label>
          Date de début :
          <input type="date" value={startDate} onChange={(e) => setStartDate(e.target.value)} />
        </label>
        <label>
          Date de fin :
          <input type="date" value={endDate} onChange={(e) => setEndDate(e.target.value)} />
        </label>
      </div>
      <button onClick={applyChanges}>Appliquer les changements</button>
      <svg id="chart" width={800} height={400} ref={chartRef}></svg>
    </div>
  );
};

export default BarChart;