import * as d3 from "d3" import React, {FC, LegacyRef, useEffect, useRef} from "react" import {rainfall, rainfallGraphData} from "../../types"; const RainfallGraph: FC = ({width, height, data, start_date, end_date}) => { const svgRef = useRef(null) useEffect(() => { renderSVG() }, [width, height, data]) const renderSVG = () => { const margin = {top: 10, right: 30, bottom: 30, left: 20} const gWidth = width - margin.left - margin.right const gHeight = height - margin.top - margin.bottom d3.select(svgRef.current).selectAll("*").remove() const svg = d3.select(svgRef.current) .attr('width', gWidth + margin.left + margin.right) .attr('height', gHeight + margin.top + margin.bottom) .attr('class', 'relative') .append('g') .attr('transform', "translate(" + margin.left + "," + margin.top + ")") console.log(data) const yMax = data.reduce((result, item) => item.value > result ? item.value : result, 0) const y = d3.scaleLinear() .domain([0, yMax + 10]) .range([gHeight, 0]) const x = d3.scaleUtc() .domain([(new Date(start_date)), (new Date()).setDate((new Date(end_date)).getDate())]) .range([margin.left, width - margin.right]) const yAxis = svg.append('g') .attr('transform', `translate(${margin.left},0)`) .call(d3.axisLeft(y).ticks(height / 80)) .call(g => g.select('.domain').remove()) .call(g => g.append('text') .attr('x', -margin.left) .attr('y', 10) .attr('fill', 'currentColor') .attr('text-anchor', 'start') ) svg.append("g") .attr("transform", "translate(0," + gHeight + ")") .call(d3.axisBottom(x) .ticks(8) .tickFormat( // @ts-ignore d3.timeFormat("%d/%m/%Y") ) , 0) if (data.length === 0) { // no values text const titleBox = svg.append("g") .attr("x", (width)) .attr("y", height) titleBox.append("text") .attr("x", (width / 2)) .attr("y", height / 2) .attr("text-anchor", "middle") .style("font-size", "20px") .text('Aucune Donnée') } else { yAxis.call(g => g.selectAll(".tick line").clone() .attr("x2", width - margin.left - margin.right) .attr("stroke-opacity", 0.1)) } const diffDays = Math.round(Math.abs(((new Date(start_date)).getTime() - (new Date(end_date)).getTime()) / (24 * 60 * 60 * 1000))) + 1 const dayWidth = (width - 44) / diffDays svg.selectAll(".bar") .data(data) .enter() .append("rect") .attr("class", "bar") .attr("fill", "steelblue") .attr("x", d => x(new Date(d.start)) + 1.5) .attr("y", d => y(d.value)) .attr("width", d => (dayWidth * d.days - 3)) .attr("height", d => height - margin.bottom - 10 - y(d.value)) .append('title') .text(d => `${d.label} : ${d.value}`) } return } export default RainfallGraph interface RainfallGraphProps { width: number, height: number, data: rainfallGraphData[], start_date: string, end_date: string, }