/* * @Author: code4eat awesomedema@gmail.com * @Date: 2024-07-09 14:53:59 * @LastEditors: code4eat awesomedema@gmail.com * @LastEditTime: 2024-08-29 17:41:09 * @FilePath: /MediScreen/src/components/singleBarChartComponent/index.tsx * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ import React, { useRef, useEffect } from 'react'; interface BarChartProps { data: { name: string; value: number }[]; } const SingleBarChartComponent: React.FC = ({ data }) => { const canvasRef = useRef(null); useEffect(() => { const canvas = canvasRef.current; if (canvas) { const ctx = canvas.getContext('2d'); if (!ctx) return; const resizeCanvas = () => { const parent = canvas.parentElement; if (parent) { const ratio = window.devicePixelRatio || 1; canvas.width = parent.clientWidth * ratio; canvas.height = parent.clientHeight * ratio; ctx.scale(ratio, ratio); canvas.style.width = `${parent.clientWidth}px`; canvas.style.height = `${parent.clientHeight}px`; } drawChart(); // 在调整大小后重新绘制图表 }; const drawChart = () => { const width = canvas.width / (window.devicePixelRatio || 1); const height = canvas.height / (window.devicePixelRatio || 1); const paddingX = 0; const paddingY = 15; const barWidth = (width - paddingX * 2) / (data.length * 2); const maxBarHeight = height - paddingY * 2; const maxValue = Math.max(...data.map((item) => item.value)); ctx.clearRect(0, 0, width * (window.devicePixelRatio || 1), height * (window.devicePixelRatio || 1)); const baseFontSize = Math.min(width, height) / 25; ctx.font = `${baseFontSize}px Arial`; ctx.strokeStyle = '#ccc'; ctx.lineWidth = 0.5; ctx.globalAlpha = 0.2; const numLines = 5; for (let i = 0; i <= numLines; i++) { const y = paddingY + (i * maxBarHeight) / numLines; ctx.beginPath(); ctx.moveTo(paddingX, y); ctx.lineTo(width - paddingX, y); ctx.stroke(); } ctx.globalAlpha = 1.0; data.forEach((item, index) => { const barHeight = (item.value / maxValue) * maxBarHeight; const x = paddingX + index * barWidth * 2 + barWidth / 2; const y = height - paddingY - barHeight; const gradient = ctx.createLinearGradient(x, y, x, y + barHeight); gradient.addColorStop(0, 'rgba(128, 234, 255, 1)'); gradient.addColorStop(1, 'rgba(128, 234, 255, 0)'); ctx.fillStyle = gradient; ctx.fillRect(x, y, barWidth - 10, barHeight); ctx.fillStyle = gradient; ctx.beginPath(); ctx.moveTo(x, y + barHeight); ctx.arcTo(x, y, x + barWidth - 10, y, 4); ctx.arcTo(x + barWidth - 10, y, x + barWidth - 10, y + barHeight, 4); ctx.arcTo(x + barWidth - 10, y + barHeight, x, y + barHeight, 4); ctx.arcTo(x, y + barHeight, x, y, 4); ctx.fill(); ctx.fillStyle = '#ffffff'; ctx.textAlign = 'center'; ctx.fillText(item.value.toString(), x + (barWidth - 10) / 2, y - 10); ctx.fillText(item.name, x + (barWidth - 10) / 2, height - paddingY + baseFontSize * 1.5); }); }; resizeCanvas(); window.addEventListener('resize', resizeCanvas); return () => { window.removeEventListener('resize', resizeCanvas); }; } }, [data]); return ; }; export default SingleBarChartComponent;