import React, { useEffect, useRef, useState } from 'react' import './indexgun.less' export default function GunttCharts(props: any) { const { dataSource, widthgezi=55, rowHeight = 40, ///数据行高 hourWidth = 80, ///数据行宽 startTime = 7, ///默认起始时间 小屏幕会生效 columns } = props const [offsetX, setOffsetX] = useState(0); const [offsetY, setOffsetY] = useState(0); const [translateX, setTranslateX] = useState(0); const [tooltipData, setTooltipData] = useState<any>(null); const [tooltipVisble, setTooltipVisble] = useState("none"); function getMonthDays(year: any) { const result = []; for (let month = 1; month <= 12; month++) { const daysInMonth = new Date(year, month, 0).getDate(); const monthInfo: any = { month: month, colors: [] }; for (let day = 1; day <= daysInMonth; day++) { const date = new Date(year, month - 1, day); const dayOfWeek = date.getDay(); if (dayOfWeek >= 1 && dayOfWeek <= 5) { monthInfo.colors.push('red'); } else { monthInfo.colors.push('black'); } } result.push(monthInfo); } return result; } const year = 2024; const yearInfo = getMonthDays(year); console.log("yearInfo", yearInfo); function getDaysInYear(year: any) { if ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0) { // 是闰年 return 366; } else { // 不是闰年 return 365; } } // 使用示例 console.log(getDaysInYear(year)); const onm ouseEnter = (e: any, value: any) => { setTooltipData(value); setTooltipVisble("block"); }; const onm ouseMove = (e: any) => { e.nativeEvent.stopImmediatePropagation(); const offset: any = ((e.clientX / document.body.clientWidth) * 100).toFixed(0); setTranslateX(offset); setOffsetX(e.clientX); setOffsetY(e.clientY); }; const onm ouseLeave = (e: any) => { setTooltipVisble("none"); }; const valueScrollRef: any = useRef(); const onScrollY = (e: any) => { valueScrollRef.current.scrollTop = e.target.scrollTop; }; const onScrollX = (e: any) => { timeScrollRef.current.scrollLeft = e.target.scrollLeft; }; const onWheel = (e: any) => { timeScrollRef.current.scrollLeft += e.deltaY; valueScrollRef.current.scrollLeft += e.deltaY; }; const timeScrollRef: any = useRef(); const timeInterval: any = (start:any) => { const t1 = "2024-09-10"; const sum = start.substring(5, 7) console.log("fdfdfdfdfd",sum); const interval = start.substring(8, 10) return interval*sum; }; const timeIntervalw =(start: any, end: any)=>{ const c = end.substring(8, 10)-start.substring(8, 10) return c } const timeIntervals=(dateString:any)=> { const date:any = new Date(dateString); const start:any = new Date(date.getFullYear(), 0, 0); const diff = date - start; const oneDay = 1000 * 60 * 60 * 24; const dayOfYear = Math.floor(diff / oneDay); return dayOfYear - 1; } const arrayLength = Array.from({ length: 365 }, (_, index) => index); console.log("new Array(getDaysInYear(year))", arrayLength); useEffect(() => { valueScrollRef.current.scrollLeft = hourWidth * startTime; }, []) return ( <div className='gun-wrap'> <div className='gun-left'> <div ref={timeScrollRef} style={{ display: "flex", height: "100px", width: 100 * Number(columns.lenght) + "px" }} > { columns?.map((i: any, v: any) => { return ( <div key={v} className="rowTitle" style={{ width: 100 }}> {i?.title || null} </div> ) }) } </div> { columns?.map((item: any, index: number) => { return ( <div key={index} className="desc_container" onScroll={onScrollY} style={{ width: 100 }} > {dataSource?.map((row: any, rowi: number) => ( <div key={rowi} className="row_desc_container" style={{ height: rowHeight, lineHeight: `${rowHeight}px` }} > { item?.render(row[item?.dataIndex]) || '--' } </div> ))} </div> ) }) } </div> <div className='gun-right' ref={valueScrollRef} onScroll={onScrollX} onWheel={onWheel}> { <div style={{ display: "flex" }}> { yearInfo?.map((a, b) => { return ( <div key={b} > <div className="header_container" ref={timeScrollRef} style={{ flex: "1", flexWrap: "nowrap" }} > <div style={{ textAlign: "center", width: widthgezi * a?.colors?.length, height: "50px", backgroundColor: "#f0f0f0", border: "1px solid #ccc", lineHeight: "50px" }}> {year}- {a?.month < 10 ? "0" + a?.month : a?.month} </div> <div className="time_header_container"> {a?.colors?.map((c: any, d: number) => { return ( <div key={d} className="time_header_item" style={{ color: c, width: hourWidth - 25 }}> {d < 9 ? "0" + (d + 1) : d + 1} </div> ) })} </div> </div></div> ) }) } </div> } {dataSource.map((row: any, index: number) => ( <div key={index} className="row_val_container" style={{ display: "flex", height: rowHeight, lineHeight: `${rowHeight}px`, width: getDaysInYear(year) * widthgezi }} > {arrayLength?.map((i: any, v: number) => { return ( <div key={v} style={{ width: widthgezi+"px", textAlign: "center", borderRight: "1px solid #ccc" }}> </div> ) })} <div onm ouseEnter={(e) => onm ouseEnter(e, row)} onm ouseLeave={onMouseLeave} onm ouseMove={onMouseMove} className="activity" style={{ width: (timeIntervalw(row.start, row.end) * widthgezi +widthgezi), left: timeIntervals(row.start) * widthgezi, backgroundColor: "#67C13A", height: rowHeight, }} > </div> </div> ))} </div> <div className="tooltip" style={{ left: offsetX, top: offsetY - 60, position: "fixed", display: tooltipVisble, transform: `translateX(-${translateX}%)` }} > <div className="title">{tooltipData ? tooltipData.name : ""}saaaaad</div> <div className="time"> {`${tooltipData ? tooltipData.start : ""} - ${tooltipData ? tooltipData.end : "" }`} </div> </div> </div> ) }
.gun-wrap { display: flex; overflow: hidden; } .gun-left { .rowTitle { box-sizing: border-box; background-color: #f0f0f0; border-right: solid 1px #e0e0e0; border-bottom: solid 1px #e0e0e0; text-align: center; line-height: 100px; } } .gun-right { vertical-align: top; position: relative; overflow-x: auto; overflow-y: hidden; padding-bottom: 0px; // flex: 1; } .desc_container { display: block; float: left; border-right: 1px solid #ccc; text-align: center; box-sizing: border-box; font-weight: bold; overflow-y: auto; .row_desc_container { display: block; } .row_desc_container:nth-child(even) { background-color: #e0e0e0; } .row_desc_container:nth-child(odd) { background-color: #f0f0f0; } .row_desc_container:first-child { border-top-left-radius: 2px; } .row_desc_container:last-child { border-bottom-left-radius: 2px; } } .header_container { .time_header_container { white-space: nowrap; font-weight: bold; .time_header_item { height: 50px; line-height: 50px; display: inline-block; box-sizing: border-box; background-color: #f0f0f0; border-right: solid 1px #e0e0e0; border-bottom: solid 1px #e0e0e0; text-align: center; vertical-align: middle; } } } .row_val_container { position: relative; .activity { box-sizing: border-box; position: absolute; border-radius: 2px; padding: 0 5px; top: 50%; transform: translateY(-50%); min-width: 1px; font-size: 14px; text-align: center; line-height: 50px; color: #fff; background-color: #67c13a; cursor: pointer; } } .row_val_container:nth-child(even) { background-color: #f0f0f0; } .row_val_container:nth-child(odd) { background-color: #e0e0e0; } .tooltip { z-index: 99999; border-radius: 2px; background-color: #fff; box-shadow: 1px 1px 3px 3px rgba(0, 0, 0, 0.3); overflow: hidden; white-space: pre; .title { background-color: #718fbd; color: #fff; padding: 2px 6px; text-align: center; font-weight: 500; } .time { font-size: 14px; padding: 2px 6px; text-align: center; border: 1px solid #718fbd; border-radius: 0px 0px 2px 2px; } } .tooltip::before { position: absolute; left: -12px; width: 0; height: 0; border: 6px solid transparent; border-right: 6px solid#fff; content: ''; }
import React from 'react' import GunttChart from '../GunttChart' import { Tooltip } from 'antd' import GunttCharts from '../gun' export default function CustomerNeed() { const columns = [ { title: '任务名称', dataIndex: 'name', render: (text: string) => ( <Tooltip placement="topLeft" title={text}> {text || '--'} </Tooltip> ) }, { title: '工序', dataIndex: 'gx', render: (text: string) => ( <Tooltip placement="topLeft" title={text}> {text || '--'} </Tooltip> ) }, { title: '开始', dataIndex: 'start', render: (text: string) => ( <Tooltip placement="topLeft" title={text}> {text || '--'} </Tooltip> ) }, { title: '结束', dataIndex: 'end', render: (text: string) => ( <Tooltip placement="topLeft" title={text}> {text || '--'} </Tooltip> ) } ] const dataSource = [ { start: "2024-01-03", end: "2024-02-04", title: "阅读会", gx: "sd", name: "sdf" }, { start: "2024-03-01", end: "2024-03-08", title: "茶话会", gx: "sd", name: "sdf" }, { start: "2024-04-01", end: "2024-04-9", title: "阅读会", gx: "sd", name: "sdf" }, { start: "2024-05-01", end: "2024-05-08", title: "茶话会", gx: "sd", name: "sdf" }, { start: "2024-06-01", end: "2024-06-08", title: "阅读会", gx: "sd", name: "sdf" }, { start: "2024-07-01", end: "2024-07-05", title: "茶话会", gx: "sd", name: "sdf" }, { start: "2024-08-01", end: "2024-08-08", title: "阅读会", gx: "sd", name: "sdf" }, { start: "2024-08-01", end: "2024-08-20", title: "茶话会", gx: "sd", name: "sdf" }, ] return ( <div> {/* <GunttChart columns={columns} dataSource={dataSource}></GunttChart> */} <GunttCharts columns={columns} dataSource={dataSource}></GunttCharts> </div> ) }
标签:2024,const,甘特图,react,start,border,any,row From: https://www.cnblogs.com/zjxzhj/p/18184415