首页 > 其他分享 >react甘特图

react甘特图

时间:2024-05-10 15:26:46浏览次数:20  
标签:2024 const 甘特图 react start border any row

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

相关文章

  • 探究:响应式编程(Reactive Programming)
    在当今软件开发领域,响应式编程(ReactiveProgramming)成为了一个备受关注的话题。它提供了一种新的编程范式,与传统的命令式编程有着显著的不同。本文将详细讲解什么是响应式编程,以及它与传统的命令式编程的不同之处。1.什么是响应式编程?响应式编程是一种编程范式,它基于数据流和变......
  • vite react 使用 svg 文件当作图标
    svg可以当做图标导入react里面,如果用img标签弄的话,无法控制图标颜色和字体大小,但是把他当组件导入的话,就可以这么控制了,比较方便,并且也方便webstorm预览首先安装vite-plugin-svgrpnpmaddvite-plugin-svgr-D然后使用修改vite.config.jsimport{defineConfi......
  • React的高阶组件详解
    接受一个或多个函数作为参数;返回一个新的函数;2使用场景(页面权限,某些页面是必须用户登录成功才能进行进入;如果用户没有登录成功,那么直接跳转到登录页面;)//定义一个高阶组件,用于鉴权的操作functionloginAuth(WrapperCpn){returnprops=>{//从本地存储中获取tok......
  • react项目中使用lottie动画
    一,引入lottie库点击查看代码npmi--savereact-lottie@types/react-lottie二,下载lottie的json文件去iconfont.cn中可以在库中下载lottie文件(注意版权问题)三,在项目中使用lottie点击查看代码import*asReactfrom"react";importLottiefrom"react-lottie";impo......
  • react中使用craco,针对路径转换,修改webpack别名路径配置
    1.0首先下载craco依赖包npminstall@craco/craco-D2.0在项目根目录下面新建craco.config.js文件,里面内容配置为constpath=require('path')module.exports={webpack:{alias:{'@':path.resolve(__dirname,'src')}......
  • React — 访问 Redux Store 的正确方法是什么?
    在组件中访问Store的最佳方法是使用connect()函数,该函数创建一个包裹现有组件的新组件。此模式称为高阶组件,通常是在React中扩展组件功能的首选方式。这允许您将状态和Action创建者映射到组件,并在Store更新时自动传递它们。使用connect的<FilterLink>组件:import{......
  • react + antd + js 简单Cron组件,支持国际化
    Cron.jsimportReact,{Fragment,useState,useCallback,useRef,useEffect}from'react';import{Select,TimePicker,Input}from'antd';constOption=Select.Option;constmwidth80={minWidth:80,marginRight:10};constwidt......
  • React文本溢出组件封装以及高亮提示
    React文本溢出组件封装以及高亮提示Abbr组件:使用场景:当我们需要设置支持最大行数时进行省略展示当我们需要设置支持设置超过多少字符进行省略展示当我们需要设置支持关键字高亮展示(有点问题,当关键字被裁剪成...之后,就无法高亮)当我们需要支持忽略大小写高亮当我们需要支持......
  • react 性能优化
    一纯组件1使用shouldComponentUpdate对先前的状态和props数据与下一个props或状态相同,如果两次的结果一直,那么就returnfalse使用纯净组件,pureComponentPureComponents负责shouldComponentUpdate——它对状态和props数据进行浅层比较(shallowcomparison),如果先前......
  • react里面bind与箭头函数
    bind由于在类中,采用的是严格模式,所以事件回调的时候,会丢失this指向,指向undefined,需要使用bind来给函数绑定上当前实例的this指向;箭头函数的this指向上下文,所以永久能拿到当前组件实例,this指向,我们可以完美的使用箭头函数来替代传统事件处理函数的回调箭头函数class......