当前位置:   article > 正文

vue2实现甘特图_基于vue的开源甘特图控件

基于vue的开源甘特图控件

Vue2使用DHTMLX Gantt

甘特图

成品展示

gantt安装与使用

vue2版---部分功能收费

  1. 安装gantt

    1. npm install dhtmlx-gantt -save
    2. 复制代码
  2. 引入---组件

    1. `引入`
    2. <template>
    3. <div ref="gantt" class="container" />
    4. </template>
    5. <script>
    6.  import { gantt } from 'dhtmlx-gantt'
    7. </script>
    8. 复制代码
  3. 使用

    使用需要很多配置项,在原生版进行详情介绍,vue版只做基本使用

    功能(收费)文档链接简要说明
    动态加载Dynamic loading能通过接口更新甘特数据,gantt支持的接口方法
    时间刻度隐藏Ability to hide time units on the time scale右边视图刻度可以不显示某时间内容
    工作时间精度Assigning Calendar to Project精确工作时间到小时或小数点天数
    自动调度Auto scheduling使甘特图能够根据任务之间的关系自动安排任务,自动调度时间
    页面多个甘特图Enterprise and Ultimate licenses)单个页面创建多个甘特图
    关键任务计算Critical path calculation关键任务不可延迟,项目标红,计算项目可预算时间
    水平拖拽多个任务Decimal units for tasks durations可以同时修改多个任务的时间
    项目,里程碑,任务类型Projects and Milestones task types区别显示图标,里程碑(菱形图案)---原生版可用
    将项目拆分子任务Projects and Milestones task types项目收缩显示子任务 -----原生版可用
    分组任务Tasks grouping细化数据分类,不做汇总分区基本用不上

    以上内容只是部分收费内容,并非全部收费内容

原生版---推荐使用

引入

  1. `页面部分` ----#节点高度要给,gantt不根据内容撑开
  2. <div style="min-height:calc(78vh - 50px - 5px );width: 100%;overflow: hidden;" ref="gantt">
  3. </div>
  4. `引入部分`
  5. import {
  6.  gantt
  7. } from '@/assets/js/dhtmlx';
  8. import "@/assets/css/dhtmlxgantt.css";
  9. 复制代码
  1. css文件地址 examples/dhtmlx_gantt/dhtmlxgantt.css · 残星落影/博客 - 码云 - 开源中国 (gitee.com)
  2. js文件地址 examples/dhtmlx_gantt/dhtmlx · 残星落影/博客 - 码云 - 开源中国 (gitee.com)

使用

gantt加载数据格式

  1. `定义数据格式`
  2. data(){
  3. return {
  4.    tasks: {
  5.            data: [],//数据
  6.            links: [],//关联项目数据
  7.         },
  8.   }
  9. }
  10. `甘特数据载入`
  11. gantt.parse(this.tasks);//parse方法加载数据
  12. gantt.render();//建议每一次修改配置项调用一次render方法
  13. 复制代码

tasks.data数据格式

  1. data=[
  2. {
  3.    id: 1,//必填
  4.    text: "标题",//必填
  5.    type: "task",// 项目类型 task任务 project项目 milestone里程碑  
  6.    start_date: "2023/3/15",
  7.    duration: 5,//任务持续时间
  8.    parent: 11,//存在这个属性说明此数据为子任务数据,父任务id为11
  9.    progress: 0.3,//项目任务滑块的进度
  10.    open: true,//是否展开显示
  11. ....
  12. },
  13. {
  14.    id: 2,
  15.    text: "标题2",
  16.    start_date: "2023/3/15",
  17.    duration: 5,
  18.    progress: 0,
  19.    open: true
  20. ....
  21. },
  22. ]
  23. # data中有些数据可以直接被读取,其余数据都可以定义在左侧表格columns数据显示
  24. `甘特可直接读取属性
  25. type parent progress open ...
  26. `
  27. 复制代码

tasks.links数据格式

  1. links=[
  2. {
  3. id:'111',//数据id
  4.    source:'1'
  5.    target:'2'
  6.    type:'0'
  7. },//
  8. {
  9.    id:'222'
  10.    source:'2'
  11.    target:'1'
  12.    type:'1'
  13. },//数据说明 滑块任务2 的头部 指向滑块任务1的头部
  14. ]
  15. #字段解释
  16. 格式 id:数据id  
  17. source:开始链接的项目id  ----为tasks.data中数据的id
  18.    target:要链接项目的id  ----为tasks.data中数据的id
  19. type: 0--进行-开始  `尾部链接头部`  
  20. 1--开始-开始 `头部链接头部`
  21. 2--进行-进行 `尾部链接尾部`
  22. 3--开始-进行 `头部链接尾部`
  23. 复制代码

图例

配置项

  • 基础config

    1. gantt.config.branch_loading = true; // 启用动态加载
    2. gantt.config.xml_date = "%Y-%m-%d"; //日期格式化
    3. gantt.config.order_branch = true;
    4. gantt.config.order_branch_free = true;
    5. gantt.config.autofit = true;//左侧是否自适应
    6. gantt.config.drag_links = true;//连线
    7. gantt.config.readonly = false;  //只读
    8. gantt.config.smart_scales = true;
    9. gantt.config.date_scale = "%m月%d日"; //右侧显示列名
    10. gantt.config.layout = {//拖拽布局
    11.        css: "gantt_container",
    12.        rows: [
    13.         {
    14.            cols: [
    15.             { view: "grid", id: "grid", scrollX: "scrollHor", scrollY: "scrollVer" },
    16.             { resizer: true, width: 1 },
    17.             { view: "timeline", id: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
    18.             { view: "scrollbar", scroll: "y", id: "scrollVer" }
    19.           ]
    20.         },
    21.         { view: "scrollbar", scroll: "x", id: "scrollHor", height: 20 }
    22.       ]
    23.     };
    24. gantt.config.start_on_monday = true;//是否从周一显示起始时间---右侧条形图
    25. gantt.config.work_time = true;//显示工作时间
    26. gantt.config.fit_tasks = true;   //自动调整图表坐标轴区间用于适配task的长度
    27. 复制代码
  • local---本地汉化

    说明

    (1)直接引入dhtmlx甘特实现的图表操作描述全是英文的,所以要对现有的属性数据显示要进行汉化文字代替

    (2)汉化分三种

    日期汉化属性汉化自定义属性汉化
    gantt.locale.dategantt.locale.labelsgantt.locale.labels
    1. //汉化
    2.      gantt.locale = {
    3.        date: {
    4.          month_full: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
    5.          month_short: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
    6.          day_full: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
    7.          day_short: ["日", "一", "二", "三", "四", "五", "六"]
    8.       },
    9.        labels: {
    10.          dhx_cal_today_button: "今天",
    11.          day_tab: "日",
    12.          week_tab: "周",
    13.          month_tab: "月",
    14.          new_event: "新建日程",
    15.          icon_save: "保存",
    16.          icon_cancel: "关闭",
    17.          icon_details: "详细",
    18.          icon_edit: "编辑",
    19.          icon_delete: "删除",
    20.          confirm_closing: "请确认是否撤销修改!", //Your changes will be lost, are your sure?
    21.          confirm_deleting: "是否删除计划?",
    22.          section_description: "描述:",
    23.          section_time: "时间范围:",
    24.          section_type: "类型:",
    25.          section_text: "计划名称:",
    26.          section_test: "测试:",
    27.          #自定义属性汉化----->
    28.          section_projectClass: "项目类型:",
    29.          taskProjectType_0: "项目任务",
    30.          taskProjectType_1: "普通任务",
    31.          section_head: "负责人:",
    32.          section_priority: '优先级:',
    33.          taskProgress: '任务状态',
    34.          taskProgress_0: "未开始",
    35.          taskProgress_1: "进行中",
    36.          taskProgress_2: "已完成",
    37.          taskProgress_3: "已延期",
    38.          taskProgress_4: "搁置中",
    39.          #<-----自定义属性汉化结束
    40.          section_template: 'Details',
    41.          /* grid columns */
    42.          column_text: "计划名称",
    43.          column_start_date: "开始时间",
    44.          column_duration: "持续时间",
    45.          column_add: "",
    46.          column_priority: "难度",
    47.          /* link confirmation */
    48.          link: "关联",
    49.          confirm_link_deleting: "将被删除",
    50.          link_start: " (开始)",
    51.          link_end: " (结束)",
    52.          type_task: "任务",
    53.          type_project: "项目",
    54.          type_milestone: "里程碑",
    55.          minutes: "分钟",
    56.          hours: "小时",
    57.          days: "天",
    58.          weeks: "周",
    59.          months: "月",
    60.          years: "年"
    61.       }
    62.     }
    63. 复制代码

    (4)图例注释

  • 表格(左)配置

    属性说明
    name在tasks.data中定义的属性数据,add为例外,add为新增数据项触发gantt新增弹窗,显示为一个加号
    label标记描述
    align文字格式
    resize布尔值,可以拉伸内容宽度
    width宽度,可写max _width min_width
    height高度, 可写max _height min_height
    editor将表格内容设置为可编辑状态,官网描述
    template自定义渲染内容
    1.  //左侧显示列名
    2.      gantt.config.columns = [
    3.        //{ name: "add", width: 44 }
    4.       { name: "text", min_width:100,max_width:200, label:"任务", align: "left",resize: true,  tree: true, editor: { type: 'text', map_to: 'text' } },
    5.       { name: "id", label: "", hide: true },
    6.       { name: "start_date", label: "开始时间", width: 120, resize: true, align: "left" },
    7.       {
    8.          name: "head", width: 110, height: 40, label: "负责人",resize: true, align: "left",
    9.          // editor: {
    10.          //   map_to: "head_id", type: "select", options: gantt.serverList("staff"),
    11.          // },
    12.          #这里的template渲染的是任务头像跟名称,this.genttDealById 是在methods定义的方法根据id获取名称,gantt.serverList()是甘特图获取数据集分发
    13.          template: (item) => {
    14.            if (this.ganttDealById(gantt.serverList('staff'), item.head_id)) {
    15.              return `<span class='userIcon' style='background-color:${item.color ? item.color : "#6666"}'>${this.ganttDealById(gantt.serverList('staff'), item.head_id).slice(0, 1)}</span>${this.ganttDealById(gantt.serverList('staff'), item.head_id)}`
    16.           }
    17.         }
    18.       },
    19.        // { name: "end_date", label: "结束时间", align: "center" },
    20.       {
    21.          name: "taskProgress", label: "任务状态", align: "center", width: 130,editor: {
    22.            type: "select", map_to: "taskProgress", options: [
    23.              #这里的labels.taskProgress_0属性是自定义汉化属性描述
    24.             { key: "0", label: gantt.locale.labels.taskProgress_0 },
    25.             { key: "1", label: gantt.locale.labels.taskProgress_1 },
    26.             { key: "2", label: gantt.locale.labels.taskProgress_2 },
    27.             { key: "3", label: gantt.locale.labels.taskProgress_3 },
    28.             { key: "4", label: gantt.locale.labels.taskProgress_4 },
    29.           ],
    30.         },
    31.            #obj形参是单个的tasks.data中的数据
    32.          template: function (obj) {
    33.            let re = '';
    34.            switch (obj.taskProgress) {
    35.              case "0":
    36.                #这里的样式类名只能通过css读取,写在less scss无法读取
    37.                re = `<div class='taskProgress color_bg_1' >未开始</div>`
    38.                break;
    39.              case "1":
    40.                re = `<div class='taskProgress color_bg_2' >进行中</div>`
    41.                break;
    42.              case "2":
    43.                re = `<div class='taskProgress color_bg_3' >已完成</div>`
    44.                break;
    45.              case "3":
    46.                re = `<div class='taskProgress color_bg_4'>已延期</div>`
    47.                break;
    48.              case "4":
    49.                re = `<div class='taskProgress color_bg_5' >搁置中</div>`
    50.                break;
    51.           }
    52.            return re
    53.         }
    54.       },
    55.     ];
    56. 复制代码
  • 弹窗表单----见汉化图例

    1.  //弹出层
    2.      gantt.config.lightbox.sections = [       { name: "text", height: 70, map_to: "text", type: "textarea", focus: true, width: "*" },       {          name: "time", height: 40, map_to: "auto", type: "duration",          time_format: ["%Y", "%m", "%d"],
    3.       },
    4.       {
    5.          name: "projectClass", height: 30, map_to: "proTemplate", type: "template",
    6.        
    7.       },
    8.       {
    9.          name: "head", height: 22, map_to: "head_id", type: "select", options: gantt.serverList('staff',[]),
    10.       },
    11.       { name: "description", height: 70, map_to: "description", type: "textarea" },
    12.       {
    13.          name: "priority", height: 40, map_to: "priority", type: "radio", options: gantt.serverList("priority")
    14.       },
    15.     ];
    16. 复制代码
  • gantt功能插件挂载

    1. gantt.plugins({
    2.        click_drag: true,
    3.        drag_timeline: true,// 拖动图
    4.        marker: true,// 时间标记
    5.        fullscreen: true,// 全屏
    6.        tooltip: true,// 鼠标经过时信息
    7.        undo: true // 允许撤销
    8.     })
    9. 复制代码

    收费的甘特图功能一般在这放开

常用事件

事件参数说明 (参数:id:数据id,item:当个数据对象,mode:拖拽模式,e:事件event)
onGanttReady在 dhtmlx甘特图初始化完成后触发,但甘特图尚未在页面上呈现
onBeforeLightboxid打开弹窗之前修改
onAfterTaskAddid, item在用户将任务添加到甘特图后触发
onAfterTaskUpdateid, item在用户将修改甘特图任务后触发
onAfterTaskDeleteid, item在用户删除甘特图任务后触发
onAfterTaskDragid, mode, e在用户完成拖动并释放鼠标按钮后触发,移动滑块
onAfterLinkDeleteid, item删除连接任务的联系
onAfterLinkUpdateid, item修改连接项目关系
onBeforeLinkAddid, item新增连接项目关系
onLightboxSaveid, item弹窗新增修改

甘特图常用API方法

方法用例说明
gantt.serverList(‘数据集名称’,'数据集')gantt,serverList("数据集名称") 返回的数据集在甘特实例定义数据集,方便在甘特配置修改是调用
gantt.updateCollection('数据集名称',更新数据)gantt.updateCollection("staff", staffArr);更新数据集数据
gantt.render()更新gantt配置
gantt.clearAll()清空gantt配置
gantt.detachEvent(’事件名)重点因为切换页面甘特不会销毁,调用销毁后阻止事件反复调用
gantt.scrollTo(x,y)定位今日线功能需要,定位到某个位置
gantt.init()gantt.init(this.$refs.gantt);gantt初始化挂载节点
gantt.parse()gantt.parse({ data: [],links: [] })gantt挂载数据
gantt.getTask()gantt.getTask(id)gantt获取单个数据

甘特图功能

今日线与定位

  1.  // 今日线
  2. createTodayLine() {
  3.      var dateToStr = gantt.date.date_to_str("%Y年%M%d日");
  4.      var markerId = gantt.addMarker({
  5.        id: 'markerLine',
  6.        start_date: new Date(),
  7.        css: "today",
  8.        text: "今日",
  9.        title: dateToStr(new Date())
  10.     });
  11.      gantt.updateMarker(markerId);
  12.   }
  13. //定位到今日线
  14. changeToday() {
  15.      this.$nextTick(() => {
  16.        let ganTT = document.getElementsByClassName('gantt_marker today')
  17.        gantt.scrollTo(ganTT[0].offsetLeft-300, null);
  18.     })
  19. },
  20. 复制代码

全屏(类F11)

  1. // 是否全屏
  2. changeFull() {
  3.   gantt.ext.fullscreen.toggle();
  4. },
  5. 复制代码

搜索功能

  1. //
  2. <a-input allowClear v-model="searchTitle" placeholder="请输入任务名称"></a-input>
  3. <a-button icon="search" type="primary" @click="searchDataClick">搜索</a-button>
  4. //点击按钮搜索
  5. #methods
  6. // 搜索判断数据
  7.    hasSubstr(parentId,type){
  8.      let task = gantt.getTask(parentId);
  9.      if(type=='tilte'){
  10.        if(task.text.toLowerCase().indexOf(this.searchTitle) !== -1)
  11.          return true;
  12.     }
  13.      // }  
  14.   },
  15.    searchDataClick(){
  16.      if(this.searchTitle ){
  17.        this.ganttEvent.onBeforeTaskDisplay=gantt.attachEvent("onBeforeTaskDisplay", (id, task)=>{
  18.          if (this.hasSubstr(id,'tilte') ){ return true;}
  19.            return false;
  20.         });
  21.          gantt.refreshData()
  22.          gantt.render()
  23.     }else{
  24.        this.ganttEvent.onBeforeTaskDisplay=gantt.attachEvent("onBeforeTaskDisplay", (id, task)=>{
  25.         return true
  26.       })
  27.        gantt.refreshData()
  28.        gantt.render()
  29.     }
  30.   },
  31. 复制代码

日期切换

  1. // 切换 年 季 月 周 日视图
  2.    ganttChangeDateView(type) {
  3.      switch (type) {
  4.        case 'y':
  5.          gantt.config.scale_unit = "year";
  6.          gantt.config.step = 1;
  7.          gantt.config.subscales = null;
  8.          gantt.config.date_scale = "%Y年";
  9.          gantt.templates.date_scale = null;
  10.          break;
  11.        case 'm':
  12.          gantt.config.scale_unit = 'month';
  13.          gantt.config.step = 1;
  14.          gantt.config.date_scale = "%m月";
  15.          gantt.templates.date_scale = null;
  16.        
  17.          break;
  18.        case 'w':
  19.          gantt.config.scale_unit = 'week';
  20.          gantt.config.step = 1;
  21.          gantt.config.date_scale = "第%w周";
  22.          gantt.templates.date_scale = null;
  23.      
  24.          break;
  25.        case 'd':
  26.          gantt.config.scale_unit = 'day';
  27.          gantt.config.step = 1;
  28.          gantt.config.date_scale = "%m月%d日";
  29.          gantt.templates.date_scale = null;
  30.          gantt.config.subscales = null;
  31.          
  32.          break;
  33.     }
  34.      gantt.render();
  35.   },
  36. 复制代码

图例

完整代码

  1. <template>
  2.  <div style="height: 100%; width: 100%">
  3.    <a-layout>
  4.      <div class="content">
  5.        <div style="margin: -5px 0px 5px;display: flex;justify-content: space-between;">
  6.            <a-input allowClear v-model="searchTitle" placeholder="请输入任务名称"></a-input>
  7.            <a-button icon="search" type="primary" @click="searchDataClick">搜索</a-button>
  8.        </div>
  9.        <!-- 中间 内容 -->
  10.        <div class="centerContent">
  11.          <!-- 甘特图 -->
  12.          <div class="selectDate">
  13.            <a-button @click="changeToday"></a-button>
  14.            <!-- 日期切换 -->
  15.            <a-select  default-value="d" style="width: 55px;margin-left: 5px;" @change="ganttChangeDateView">
  16.              <a-select-option value="y"></a-select-option>
  17.              <a-select-option value="m"></a-select-option>
  18.              <a-select-option value="w"></a-select-option>
  19.              <a-select-option value="d"></a-select-option>
  20.            </a-select>
  21.            <a-button style="margin-left: 5px;" @click="changeFull"><a-icon type="fullscreen" /></a-button>
  22.          </div>
  23.          <div class="rightGatt" style="min-height:calc(78vh - 50px - 5px );width: 100%;overflow: hidden;" ref="gantt">
  24.          </div>
  25.        </div>
  26.      </div>
  27.    </a-layout>
  28.  </div>
  29. </template>
  30. <script>
  31. import {
  32.  gantt
  33. } from '@/assets/js/dhtmlx';
  34. import "@/assets/css/dhtmlxgantt.css";
  35. import { util } from "@/components/utils/util.js"
  36. import moment from 'moment'
  37. export default {
  38.  name: "ganttChart",
  39.  data() {
  40.    return {
  41.      moment,
  42.      timer: null,//定时
  43.      item: {},//单行数据
  44.      searchTitle: "",//搜索标题
  45.      tasks: {
  46.        data: [],//数据
  47.        links: [],//关联项目数据
  48.     },
  49.      savetasks: {
  50.        data: [],
  51.        links: []
  52.     },//暂存空数据
  53.      ganttServerStaff:[],//设置gantt成员数据
  54.      selectStaff: [],//下拉成员
  55.      staff: [],//成员
  56.      ganttEvent: {//销毁事件
  57.     },
  58.      urls: {
  59.        staff: "",//项目成员
  60.        tasklinks: '',//gantt数据
  61.        linksEdit: '',//修改和新增连接
  62.        linksDelete: '',//删除连接
  63.        addTask: '',//新增项目PUT
  64.        editTask: '',//编辑项目put请求 tid
  65.        deleteTask: '',//删除项目delete tid
  66.     }
  67.   }
  68. },
  69.  watch: {
  70.    searchTitle(newVal,oldVal){
  71.      this.searchTitle = newVal;
  72.   }
  73. },
  74.  mounted() {
  75.    this.axios.get(this.urls.staff, {
  76.        params: { projectId:  this.$store.state.project_data.id },
  77.     }).then(res => {
  78.        let staffArr = [];
  79.        res.data.code = 200 && res.data.result.forEach((item, index) => {
  80.          staffArr[index] = {};
  81.          staffArr[index].key = item.id;
  82.          staffArr[index].label = item.realname;
  83.       })
  84.        this.selectStaff = res.data.result;
  85.        // 补充gantt数据
  86.        this.ganttServerStaff=staffArr;
  87.      
  88.     })
  89.    this.$nextTick(()=>{
  90.      this.ganttChangeEvent();//交互事件
  91.      this.initGantt();//初始化
  92.      
  93.      this.createTodayLine();//今日线
  94.      this.ganttServerList();//服务数据
  95.   })
  96.    this.onQuery();//查询数据
  97.    this.ganttChangeDateView("d");//默认日格式
  98. },
  99.  methods: {
  100.    /*
  101.     甘特图
  102.     */
  103.    // 初始化gantt
  104.    initGantt() {
  105.      // 清空之前的配置
  106.      // gantt.clearAll();
  107.  
  108.      // 启用动态加载
  109.      gantt.config.branch_loading = true
  110.      //日期格式化
  111.      gantt.config.xml_date = "%Y-%m-%d";
  112.      gantt.config.order_branch = true;
  113.      gantt.config.order_branch_free = true;
  114.      //左侧是否自适应
  115.      gantt.config.autofit = true;
  116.      gantt.config.drag_links = true;//连线
  117.      gantt.config.readonly = false;  //只读
  118.      gantt.config.date_scale = "%m月%d日"; //右侧显示列名
  119.      gantt.config.layout = {//拖拽布局
  120.        css: "gantt_container",
  121.        rows: [
  122.         {
  123.            cols: [
  124.             { view: "grid", id: "grid", scrollX: "scrollHor", scrollY: "scrollVer" },
  125.             { resizer: true, width: 1 },
  126.             { view: "timeline", id: "timeline", scrollX: "scrollHor", scrollY: "scrollVer" },
  127.             { view: "scrollbar", scroll: "y", id: "scrollVer" }
  128.           ]
  129.         },
  130.         { view: "scrollbar", scroll: "x", id: "scrollHor", height: 20 }
  131.       ]
  132.     };
  133.      gantt.config.start_on_monday = true;
  134.      gantt.config.work_time = true;
  135.      gantt.config.fit_tasks = true;   //自动调整图表坐标轴区间用于适配task的长度
  136.    
  137.      //汉化
  138.      gantt.locale = {
  139.        date: {
  140.          month_full: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"],
  141.          month_short: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
  142.          day_full: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
  143.          day_short: ["日", "一", "二", "三", "四", "五", "六"]
  144.       },
  145.        labels: {
  146.          dhx_cal_today_button: "今天",
  147.          day_tab: "日",
  148.          week_tab: "周",
  149.          month_tab: "月",
  150.          new_event: "新建日程",
  151.          icon_save: "保存",
  152.          icon_cancel: "关闭",
  153.          icon_details: "详细",
  154.          icon_edit: "编辑",
  155.          icon_delete: "删除",
  156.          confirm_closing: "请确认是否撤销修改!", //Your changes will be lost, are your sure?
  157.          confirm_deleting: "是否删除计划?",
  158.          section_description: "描述:",
  159.          section_time: "时间范围:",
  160.          section_type: "类型:",
  161.          section_text: "计划名称:",
  162.          section_test: "测试:",
  163.          section_projectClass: "项目类型:",
  164.          taskProjectType_0: "项目任务",
  165.          taskProjectType_1: "普通任务",
  166.          section_head: "负责人:",
  167.          section_priority: '优先级:',
  168.          taskProgress: '任务状态',
  169.          taskProgress_0: "未开始",
  170.          taskProgress_1: "进行中",
  171.          taskProgress_2: "已完成",
  172.          taskProgress_3: "已延期",
  173.          taskProgress_4: "搁置中",
  174.          section_template: 'Details',
  175.          /* grid columns */
  176.          column_text: "计划名称",
  177.          column_start_date: "开始时间",
  178.          column_duration: "持续时间",
  179.          column_add: "",
  180.          column_priority: "难度",
  181.          /* link confirmation */
  182.          link: "关联",
  183.          confirm_link_deleting: "将被删除",
  184.          message_ok:'确定',
  185.          message_cancel:'取消',
  186.          link_start: " (开始)",
  187.          link_end: " (结束)",
  188.          type_task: "任务",
  189.          type_project: "项目",
  190.          type_milestone: "里程碑",
  191.          minutes: "分钟",
  192.          hours: "小时",
  193.          days: "天",
  194.          weeks: "周",
  195.          months: "月",
  196.          years: "年"
  197.       }
  198.     }
  199.      gantt.serverList("priority", [
  200.       { key: 0, label: "最高" },
  201.       { key: 1, label: "较高" },
  202.       { key: 2, label: "普通" },
  203.       { key: 3, label: "较低" },
  204.       { key: 4, label: "最低" },
  205.     ]);
  206.      //左侧显示列名
  207.      gantt.config.columns = [
  208.       { name: "text", min_width:100,max_width:200, label:"任务", align: "left",resize: true,  tree: true, editor: { type: 'text', map_to: 'text' } },
  209.       { name: "id", label: "", hide: true },
  210.       { name: "start_date", label: "开始时间", width: 120, resize: true, align: "left" },
  211.       {
  212.          name: "head", min_width: 100, height: 40, label: "负责人",resize: true, align: "left",
  213.          // editor: {
  214.          //   map_to: "head_id", type: "select", options: gantt.serverList("staff"),
  215.          // },
  216.          template: (item) => {
  217.            if (this.ganttDealById(gantt.serverList('staff'), item.head_id)) {
  218.              return `<span class='userIcon' style='background-color:${item.color ? item.color : "#6666"}'>${this.ganttDealById(gantt.serverList('staff'), item.head_id).slice(0, 1)}</span>${this.ganttDealById(gantt.serverList('staff'), item.head_id)}`
  219.           }
  220.         }
  221.       },
  222.        // { name: "end_date", label: "结束时间", align: "center" },
  223.       {
  224.          name: "taskProgress", label: "任务状态", align: "center", min_width: 110,editor: {
  225.            type: "select", map_to: "taskProgress", options: [
  226.             { key: "0", label: gantt.locale.labels.taskProgress_0 },
  227.             { key: "1", label: gantt.locale.labels.taskProgress_1 },
  228.             { key: "2", label: gantt.locale.labels.taskProgress_2 },
  229.             { key: "3", label: gantt.locale.labels.taskProgress_3 },
  230.             { key: "4", label: gantt.locale.labels.taskProgress_4 },
  231.           ],
  232.         },
  233.          template: function (obj) {
  234.            let re = '';
  235.            switch (obj.taskProgress) {
  236.              case "0":
  237.                re = `<div class='taskProgress color_bg_1' >未开始</div>`
  238.                break;
  239.              case "1":
  240.                re = `<div class='taskProgress color_bg_2' >进行中</div>`
  241.                break;
  242.              case "2":
  243.                re = `<div class='taskProgress color_bg_3' >已完成</div>`
  244.                break;
  245.              case "3":
  246.                re = `<div class='taskProgress color_bg_4'>已延期</div>`
  247.                break;
  248.              case "4":
  249.                re = `<div class='taskProgress color_bg_5' >搁置中</div>`
  250.                break;
  251.           }
  252.            return re
  253.         }
  254.       },
  255.     ];
  256.      //弹出层
  257.      gantt.config.lightbox.sections = [
  258.       { name: "text", height: 70, map_to: "text", type: "textarea", focus: true, width: "*" },
  259.       {
  260.          name: "time", height: 40, map_to: "auto", type: "duration",
  261.          time_format: ["%Y", "%m", "%d"],
  262.       },
  263.       {
  264.          name: "projectClass", height: 30, map_to: "proTemplate", type: "template",
  265.        
  266.       },
  267.       {
  268.          name: "head", height: 22, map_to: "head_id", type: "select", options: gantt.serverList('staff',[]),
  269.       },
  270.       { name: "description", height: 70, map_to: "description", type: "textarea" },
  271.       {
  272.          name: "priority", height: 40, map_to: "priority", type: "radio", options: gantt.serverList("priority")
  273.       },
  274.     ];
  275.      gantt.config.smart_scales = true;
  276.      gantt.plugins({
  277.        click_drag: true,
  278.        drag_timeline: true,// 拖动图
  279.        marker: true,// 时间标记
  280.        fullscreen: true,// 全屏
  281.        tooltip: true,// 鼠标经过时信息
  282.        undo: true // 允许撤销
  283.     })
  284.      gantt.init(this.$refs.gantt);
  285.    
  286.   },
  287.  
  288.  
  289.    // gantt数据服务列表
  290.    ganttServerList() {
  291.      this.getProjectStaff();//获取项目成员
  292.      // 项目难度
  293.      gantt.serverList("priority", [
  294.       { key: 0, label: "最高" },
  295.       { key: 1, label: "较高" },
  296.       { key: 2, label: "普通" },
  297.       { key: 3, label: "较低" },
  298.       { key: 4, label: "最低" },
  299.     ]);
  300.  
  301.   },
  302.    // gantt交互事件注册
  303.    ganttChangeEvent() {
  304.      // gantt渲染
  305.      this.ganttEvent.onGanttReady= gantt.attachEvent("onGanttReady", ()=>{
  306.        
  307.          //弹窗标题 日期范围
  308.          gantt.templates.task_time = function (start, end, task) {
  309.            return "周期:" + moment(start).format('YYYY-MM-DD') + " 至 " + moment(end).format('YYYY-MM-DD');
  310.         };
  311.          // 浮窗
  312.          gantt.templates.tooltip_text = (start, end, task) => {
  313.            return "<b>项目名称:</b> " + task.text + "<br><b>负责人:</b>" + task.head + "<br/><b>开始时间:</b> "
  314.              + moment(start).format('YYYY-MM-DD')
  315.              + "<br/><b>结束时间:</b> "
  316.              + moment(new Date(end).valueOf() - 1000*60*60*24 ).format('YYYY-MM-DD');
  317.         }
  318.          //弹窗标题 计划名称
  319.          gantt.templates.task_text = function (start, end, task) {
  320.            return task.text;
  321.         };
  322.          gantt.templates.timeline_cell_class = function (task, date) {
  323.            if (!gantt.isWorkTime({ task: task, date: date })) {
  324.              return "weekend";
  325.           } else {
  326.              return 'weekday'
  327.           }
  328.         };
  329.          gantt.templates.task_end_date = (date)=>{
  330.            return gantt.templates.task_date(this.moment(new Date(date.valueOf() - 1000*60*60*24)).format("YYYY-MM-DD"));
  331.         };
  332.          gantt.templates.grid_date_format = (date, column)=>{
  333.            if(column === "end_date"){
  334.                return this.moment(new Date(date.valueOf() - 1000*60*60*24)).format("YYYY-MM-DD");
  335.           }else{
  336.                return this.moment(date).format("YYYY-MM-DD");
  337.           }
  338.         }
  339.     });
  340.      // 修改默认弹窗
  341.      gantt.attachEvent("onBeforeLightbox", (id)=> {
  342.        var task = gantt.getTask(id);
  343.        task.proTemplate = `${gantt.locale.labels.taskProjectType_0}`
  344.        return true;
  345.     });
  346.      //添加后触发
  347.      this.ganttEvent.onAfterTaskAdd = gantt.attachEvent("onAfterTaskAdd", (id, item) => {
  348.        clearTimeout(this.timer)
  349.        this.timer = setTimeout(() => {
  350.          this.dealProject("add",item)
  351.       }, 500)
  352.     });
  353.      // 修改任务
  354.      this.ganttEvent.onAfterTaskUpdate = gantt.attachEvent("onAfterTaskUpdate", (id, data) => {
  355.        clearTimeout(this.timer)
  356.        this.timer = setTimeout(() => {
  357.          this.dealProject("edit", data);
  358.          gantt.render()
  359.       }, 500)
  360.     });
  361.      // 删除项目
  362.      this.ganttEvent.onAfterTaskDelete = gantt.attachEvent("onAfterTaskDelete", (id, data) => {
  363.        clearTimeout(this.timer)
  364.        this.timer = setTimeout(() => {
  365.  
  366.          this.dealProject("delete", data);
  367.          gantt.render();
  368.       }, 500)
  369.     });
  370.      // 移动项目
  371.      this.ganttEvent.onAfterTaskDrag = gantt.attachEvent("onAfterTaskDrag", (id, mode, e) => {
  372.        clearTimeout(this.timer)
  373.        this.timer = setTimeout(() => {
  374.          var task = gantt.getTask(id);
  375.          this.dealProject("edit", task);
  376.          gantt.render()
  377.       }, 500)
  378.     });
  379.      // 用户完成拖动并释放鼠标
  380.      this.ganttEvent.onAfterTaskChanged = gantt.attachEvent("onAfterTaskChanged", (id, mode, task) => {
  381.        clearTimeout(this.timer)
  382.        this.timer = setTimeout(() => {
  383.          gantt.render();
  384.       }, 500)
  385.     });
  386.      // 删除连接项目关系
  387.      this.ganttEvent.onAfterLinkDelete = gantt.attachEvent("onAfterLinkDelete", (id, item) => {
  388.        clearTimeout(this.timer)
  389.        this.timer = setTimeout(() => {
  390.      
  391.          let param = Object.assign({}, { projectId:this.$store.state.project_data.id }, item)
  392.          this.axios.$delete(this.urls.linksDelete, param).then(res => {
  393.            res.code == 200 && this.$message.success("解除成功!")
  394.            res.code != 200 && this.$message.error("解除失败!")
  395.         })
  396.          gantt.render();
  397.       }, 500)
  398.     });
  399.      // 修改连接项目关系
  400.      this.ganttEvent.onAfterLinkUpdate = gantt.attachEvent("onAfterLinkUpdate", (id, item) => {
  401.        clearTimeout(this.timer)
  402.        this.timer = setTimeout(() => {
  403.          let param = Object.assign({}, { projectId:this.$store.state.project_data.id }, item)
  404.          this.axios.$put(this.urls.linksEdit, param).then(res => {
  405.            res.code == 200 && this.$message.success("关联成功!")
  406.            res.code != 200 && this.$message.error("关联失败!")
  407.         })
  408.          gantt.render()
  409.       }, 500)
  410.     });
  411.      // 新增连接项目关系
  412.      this.ganttEvent.onBeforeLinkAdd = gantt.attachEvent("onBeforeLinkAdd", (id, item) => {
  413.        this.timer = setTimeout(() => {
  414.          clearTimeout(this.timer)
  415.          let param = Object.assign({}, { projectId: this.$store.state.project_data.id }, item)
  416.          this.axios.$put(this.urls.linksEdit, param).then(res => {
  417.            res.code == 200 && this.$message.success("关联成功!");
  418.            res.code != 200 && this.$message.error("关联失败!");
  419.          
  420.         })
  421.          gantt.render()
  422.       }, 20)
  423.     });
  424.      // 保存新增
  425.      this.ganttEvent.onLightboxSave = gantt.attachEvent("onLightboxSave", (id, item) => {
  426.        if (!item.text) {
  427.          this.$message.error("请填写计划名称!");
  428.          return false;
  429.       }
  430.        return true;
  431.     });
  432.   },
  433.    // 处理id 对应名称label
  434.    ganttDealById(list, id) {
  435.      for (let i = 0; i < list.length; i++) {
  436.        if (list[i].key == id)
  437.          return list[i].label ;
  438.     }
  439.      return "";
  440.   },
  441.    // 切换 年 季 月 周 日视图
  442.    ganttChangeDateView(type) {
  443.      switch (type) {
  444.        case 'y':
  445.          gantt.config.scale_unit = "year";
  446.          gantt.config.step = 1;
  447.          gantt.config.subscales = null;
  448.          gantt.config.date_scale = "%Y年";
  449.          gantt.templates.date_scale = null;
  450.          break;
  451.        case 'm':
  452.          gantt.config.scale_unit = 'month';
  453.          gantt.config.step = 1;
  454.          gantt.config.date_scale = "%m月";
  455.          gantt.templates.date_scale = null;
  456.        
  457.          break;
  458.        case 'w':
  459.          gantt.config.scale_unit = 'week';
  460.          gantt.config.step = 1;
  461.          gantt.config.date_scale = "第%w周";
  462.          gantt.templates.date_scale = null;
  463.      
  464.          break;
  465.        case 'd':
  466.          gantt.config.scale_unit = 'day';
  467.          gantt.config.step = 1;
  468.          gantt.config.date_scale = "%m月%d日";
  469.          gantt.templates.date_scale = null;
  470.          gantt.config.subscales = null;
  471.          
  472.          break;
  473.     }
  474.      gantt.render();
  475.   },
  476.    // 今日线
  477.    createTodayLine() {
  478.      var dateToStr = gantt.date.date_to_str("%Y年%M%d日");
  479.      var markerId = gantt.addMarker({
  480.        id: 'markerLine',
  481.        start_date: new Date(),
  482.        css: "today",
  483.        text: "今日",
  484.        title: dateToStr(new Date())
  485.     });
  486.      gantt.updateMarker(markerId);
  487.   },
  488.    // 是否全屏
  489.    changeFull() {
  490.      gantt.ext.fullscreen.toggle();
  491.   },
  492.    // 定位到今日线
  493.    changeToday() {
  494.      this.$nextTick(() => {
  495.        let ganTT = document.getElementsByClassName('gantt_marker today')
  496.        gantt.scrollTo(ganTT[0].offsetLeft-300, null);
  497.     })
  498.   },
  499.    /*
  500.   操作
  501.   */
  502.    // 获取项目成员
  503.    getProjectStaff(projectID) {
  504.      this.axios.get(this.urls.staff, {
  505.        params: { projectId: projectID ? projectID : this.$store.state.project_data.id },
  506.     }).then(res => {
  507.        let staffArr = [];
  508.        res.data.code = 200 && res.data.result.forEach((item, index) => {
  509.          staffArr[index] = {};
  510.          staffArr[index].key = item.id;
  511.          staffArr[index].label = item.realname;
  512.       })
  513.        this.selectStaff = res.data.result;
  514.        // 补充gantt数据
  515.        this.ganttServerStaff=staffArr;
  516.        gantt.updateCollection("staff", staffArr);
  517.        gantt.render()
  518.     })
  519.   },
  520.    //计算进度
  521.    evalProgess(start,end,update) {
  522.      if (start && end && update) {
  523.        let start_date = this.moment(start).format("YYYY-MM-DD");
  524.        let end_date = this.moment(end).format("YYYY-MM-DD");
  525.        let update_date = this.moment(update).format("YYYY-MM-DD");
  526.        
  527.        if((new Date(end_date) - new Date(update_date)>0)){
  528.          let process= (new Date(update_date) - new Date(start_date)) / (new Date(end_date) - new Date(start_date));
  529.          return process.toFixed(2)
  530.       }else {
  531.          return 0
  532.       }
  533.     }
  534.      return 0
  535.   },
  536.    // 获取数据
  537.    onQuery(param) {
  538.      gantt.clearAll();
  539.      gantt.parse(this.savetasks);
  540.      gantt.render();
  541.      param = Object.assign({}, { projectId:
  542.        this.$store.state.project_data.id ? this.$store.state.project_data.id :'1'
  543.     }, param)
  544.      this.axios.get(this.urls.tasklinks, {
  545.        params: param
  546.     }).then(res => {
  547.        let result = res.data.result["taskList"];
  548.        let pushArr = [];
  549.        this.tasks.links = res.data.result["ganttchartList"];//连接项目
  550.        this.tasks.data = [];
  551.        result.forEach((item, index) => {
  552.          this.tasks.data[index] = {};
  553.          this.tasks.data[index].id = item.tid ? item.tid : '';//项目id
  554.          this.tasks.data[index].text = item.title ? item.title : '空标题';//标题
  555.          this.tasks.data[index].start_date = item.startTime;//开始时间
  556.          // 负责人--成员
  557.          this.tasks.data[index].head_id = item.headRole?.id?item.headRole?.id:'';//负责人id
  558.          this.tasks.data[index].head = item.headRole?.realname ? item.headRole?.realname : '';//负责人
  559.          this.tasks.data[index].progress = this.evalProgess(item.startTime,item.endTime,item.updateTime)//项目进展
  560.          // 后台时间加一天 显示减一天 处理条形图时间左闭右开
  561.          this.tasks.data[index].end_date = this.moment(new Date(item.endTime).valueOf() + 1000*60*60*24).format("YYYY-MM-DD");//结束时间
  562.          // this.tasks.data[index].end_date = item.endTime;//结束时间
  563.          this.tasks.data[index].priority = item.priority ? item.priority : '';//任务优先级
  564.          this.tasks.data[index].projectClass = item.type ? item.type : '';//类型 0项目任务 1 普通任务
  565.          this.tasks.data[index].taskProgress = item.taskStatus.toString();//任务状态
  566.          this.tasks.data[index].description = item.describe ? item.describe : '';//描述
  567.          this.tasks.data[index].color = item.stateDictionary.color ? item.stateDictionary.color : '';//颜色
  568.          if (item.taskList && item.taskList.length != 0) {
  569.            this.tasks.data[index].render = "split";//显示在单行
  570.            this.tasks.data[index].open = true;//展开
  571.            item.taskList.forEach((_item) => {
  572.              pushArr.push(
  573.               {
  574.                  id: _item.tid,
  575.                  text: _item.title ? _item.title : '空标题',
  576.                  start_date: _item.startTime,
  577.                  end_date: _item.endTime,
  578.                  head_id: _item.headId,
  579.                  head: _item.head,
  580.                  priority: _item.priority,
  581.                  projectClass: _item.type,
  582.                  taskProgress: _item.taskStatus.toString(),
  583.                  description: _item.describe,
  584.                  parent: _item.mainTaskId,
  585.               }
  586.             );
  587.           })
  588.         }
  589.       });
  590.        this.tasks.data = this.tasks.data.concat(pushArr)
  591.      
  592.        this.$nextTick(() => {
  593.          gantt.parse(this.tasks);
  594.          gantt.render();
  595.          gantt.refreshData();
  596.       })
  597.     })
  598.   },
  599.    // 项目新增 修改tid 删除tid
  600.    dealProject(type, data) {
  601.      let param = {};
  602.      if (type != 'add') {
  603.        param.tid = data.id;
  604.        param.title = data.text;
  605.        param.startTime = this.moment(data.start_date).format("YYYY-MM-DD");
  606.        param.endTime = this.moment(data.end_date).format("YYYY-MM-DD");
  607.      
  608.        param.describe = data.description;
  609.        param.priority = data.priority;
  610.      
  611.        param.head = data.head_id;
  612.        param.taskStatus = data.taskProgress;
  613.        param.projectId = this.$store.state.project_data.id;
  614.     } else {
  615.      
  616.        param.title = data.text;
  617.        param.startTime = this.moment(data.start_date).format("YYYY-MM-DD");
  618.        param.endTime = this.moment(data.end_date).format("YYYY-MM-DD");
  619.        
  620.        param.describe = data.description;
  621.        param.priority = data.priority;
  622.      
  623.        param.head = data.head_id;
  624.        param.taskStatus = data.taskProgress;
  625.        param.projectId = this.$store.state.project_data.id;
  626.     }
  627.      let formdata=new FormData();
  628.      for(let i in param){
  629.        formdata.append(i,param[i])
  630.     }
  631.      switch (type) {
  632.        case "add"://新增
  633.          this.axios.put(this.urls.addTask, formdata).then(res => {
  634.          
  635.            res.data.code == 200 && this.$message.success("新增成功!")
  636.            res.data.code != 200 && this.$message.error("新增失败!")
  637.         }).catch(err => {
  638.            this.$message.error("请求失败!")
  639.         })
  640.          break;
  641.        case "edit":
  642.          this.axios.put(this.urls.editTask, formdata).then(res => {
  643.            res.data.code == 200 && this.$message.success("修改成功!")
  644.            res.data.code != 200 && this.$message.error("修改失败!")
  645.         }).catch(err => {
  646.            this.$message.error("请求失败!")
  647.         })
  648.          break;
  649.        case "delete":
  650.          this.axios.delete(this.urls.deleteTask, formdata).then(res => {
  651.            res.data.code == 200 && this.$message.success("删除成功!")
  652.            res.data.code != 200 && this.$message.error("删除失败!")
  653.         }).catch(err => {
  654.            this.$message.error("请求失败!")
  655.         })
  656.          break;
  657.     }
  658.   },
  659.    selecthead(val){
  660.      
  661.      this.searchHead=val;//id
  662.   },
  663.    // 搜索判断数据
  664.    hasSubstr(parentId,type){
  665.      let task = gantt.getTask(parentId);
  666.      if(type=='tilte'){
  667.        if(task.text.toLowerCase().indexOf(this.searchTitle) !== -1)
  668.          return true;
  669.     }
  670.      // }  
  671.   },
  672.    //点击按钮搜索
  673.    searchDataClick(){
  674.  
  675.      if(this.searchTitle ){
  676.        this.ganttEvent.onBeforeTaskDisplay=gantt.attachEvent("onBeforeTaskDisplay", (id, task)=>{
  677.          if (this.hasSubstr(id,'tilte') ){ return true;}
  678.            return false;
  679.         });
  680.          gantt.refreshData()
  681.          gantt.render()
  682.     }else{
  683.        this.ganttEvent.onBeforeTaskDisplay=gantt.attachEvent("onBeforeTaskDisplay", (id, task)=>{
  684.         return true
  685.       })
  686.        gantt.refreshData()
  687.        gantt.render()
  688.     }
  689.   },
  690.    // 提交弹框
  691.    handleOk() {
  692.      if (this.modalTitle === 1) {
  693.        this.editForm.validateFields((err, values) => {
  694.          if (!err) {
  695.            Array.isArray(values.participants) && (values.participants = values.participants.join());
  696.            values = util.transformFields(values);
  697.            let formdata = new FormData();
  698.            for (let key in values) {
  699.              formdata.append(key, values[key] ? values[key] : '');
  700.           }
  701.            this.axios.put(this.urls.addTask, formdata).then((res) => {
  702.              if (res.data.code === 200) {
  703.                this.visible = false;
  704.                let msg = res.data.message
  705.                this.$message.success(msg)
  706.                this.editForm.resetFields()
  707.                this.onQuery();
  708.             }
  709.           })
  710.         }
  711.       })
  712.     }
  713.   },
  714. },
  715.  destroyed() {
  716.    // 销毁gantt事件
  717.    for (let i in this.ganttEvent) {
  718.      gantt.detachEvent(this.ganttEvent[i])
  719.   }
  720.   gantt.ext.tooltips.tooltip.hide();
  721. }
  722. }
  723. </script>
  724. <style scoped lang="less">
  725. @import url(./gantt.css);
  726. .ant-layout {
  727.  background: #f8f9f9;
  728. }
  729. .ant-layout-header {
  730.  background: #fdffff;
  731.  color: rgb(29, 28, 28);
  732.  border: 1px solid #dee0e0;
  733. }
  734. .header {
  735.  // position: fixed;
  736.  display: flex;
  737.  justify-content: space-between;
  738.  align-items: center;
  739. }
  740. .content {
  741.  background: #fdffff;
  742.  height: 99vh;
  743. }
  744. // 中间
  745. .centerContent {
  746.  position: relative;
  747.  background: #fdffff;
  748.  width: 100%;
  749.  overflow-y: auto;
  750.  display: flex;
  751.  justify-content: space-between;
  752. .selectDate {
  753.    width: 100px;
  754.    position: fixed;
  755.    top: 18%;
  756.    right: 9%;
  757.    z-index: 99;
  758.    display: flex;
  759.    justify-content: space-between;
  760. }
  761. }
  762. </style>
  763. 复制代码

自定义修改gantt样式文件

  1. .weekend {
  2.  background: #fafafa !important;
  3. }
  4. .weekday{
  5.  background: #fff;
  6. }
  7. .gantt_resource_task .gantt_task_content {
  8.  color: inherit;
  9. }
  10. .gantt_resource_task .gantt_task_progress {
  11.  background-color: rgba(33, 33, 33, 0.3);
  12. }
  13. .gantt_tree_content{
  14.  color: #808080;
  15. }
  16. .gantt_cell:nth-child(1) .gantt_tree_content {
  17.  border-radius: 16px;
  18.  width: 100%;
  19.  height: 80%;
  20.  margin: 5% 0;
  21.  line-height: 230%;
  22. }
  23. /* 今日线 */
  24. .gantt_marker.today{
  25.  background: #ffb121;
  26. }
  27. .gantt_cell,.gantt_grid_head_cell,.gantt_grid_data,.gantt_data_area,.gantt_scale_cell{
  28.  background-color:#fff ;
  29. }
  30. /* 滑块 */
  31. .gantt_task_content{
  32.  color: #fff;
  33.  font-size: 13px;
  34.  font-weight: bold;
  35.  outline: none;
  36. }
  37. /* 右边单元格 */
  38. .gantt_task_line,.gantt_task_inline_color{
  39.  border-radius: 10px;
  40.  box-sizing: border-box;
  41.  border-color: #fff !important;
  42. }
  43. .gantt_task_scale .gantt_scale_line{
  44.  /* border-bottom: 1px solid #e6ebf2; */
  45. }
  46. .gantt_row, .gantt_task_row{
  47.  /* border-bottom: none; */
  48. }
  49. /* 覆盖进度条 */
  50. .gantt_task_line.gantt_task_inline_color .gantt_task_progress{
  51.  opacity: none;
  52.  /* background: repeating-linear-gradient(70deg, #666 0px, #666 10px, #fff 0px,#fff 20px); */
  53.  /* animation: ani 1.5s ease-in-out 6; */
  54. }
  55. @keyframes ani {
  56.    0%{
  57.      background: repeating-linear-gradient(70deg, #666 0px, #666 10px, #fff 0px,#fff 20px);
  58.   }
  59.    100%{
  60.      background: repeating-linear-gradient(70deg, #fff 0px, #fff 10px, #666 0px,#666 20px);
  61.   }
  62. }
  63. .taskProgress{
  64.  margin: 0 auto;
  65.  margin-top: 5px;
  66.  height: 24px;
  67.  width: 65px;
  68.  font-size: 12px;
  69.  line-height: 24px;
  70.  font-weight: bold;
  71.  color: #f7fbfe;
  72.  border-radius: 20px;
  73. }
  74. .color_bg_1{
  75.  background-color:#60a3bc ;
  76. }
  77. .color_bg_2{
  78.  background-color:#079992 ;
  79. }
  80. .color_bg_3{
  81.  background-color:#78e08f ;
  82. }
  83. .color_bg_4{
  84.  background-color:#e55039 ;
  85. }
  86. .color_bg_5{
  87.  background-color:#f6b93b ;
  88. }
  89. .gantt_task_row .gantt_task_cell,.weekday{
  90.  outline: none;
  91. }
  92. .gantt_grid_scale{
  93.  background-color: #f7fbfe !important;
  94. }
  95. .gantt_task_row .gantt_selected .gantt_task_cell{
  96.  background-color: none;
  97.  border-right-color:none;
  98. }
  99. .gantt_grid_scale .gantt_grid_head_cell{
  100.  font-weight: bold;
  101.  font-size: 14px;
  102.  border: none;
  103.  color:#506270;
  104. }
  105. /* 滑动栏 */
  106. /* 项目icon标 */
  107. .gantt_tree_icon{
  108.  width: 14px;
  109.  margin-right: 2px;
  110.  margin-left: -8px;
  111. }
  112. .gantt_tree_icon.gantt_file {
  113.  /* 文件icon */
  114.  background-image: url(../../assets/img/file.png);
  115. }
  116. .gantt_tree_icon.gantt_folder_open{
  117.  /* 文件夹icon */
  118.  background-image: none;
  119. }
  120. .gantt_tree_icon.gantt_open{
  121.  /* 加号 */
  122.  background-image: url(../../assets//img/project.png);
  123. }
  124. .gantt_tree_icon.gantt_close{
  125.  /* 减号 */
  126.  background-image: none;
  127. }
  128. .userIcon{
  129.  display: inline-block;
  130.  width: 25px;
  131.  height: 25px;
  132.  margin-right: 5px;
  133.  text-align: center;
  134.  line-height: 25px;
  135.  color: #fafafa;
  136.  border-radius: 50%;
  137. }
  138. #search{
  139.  margin-left: 10px;
  140.  outline: none;
  141.  border: none;
  142.  font-size: 12px;
  143.  color: #666666;
  144. }
  145. /*定义滚动条宽高及背景,宽高分别对应横竖滚动条的尺寸*/
  146. *::-webkit-scrollbar {
  147.  width: 10px;
  148.  height: 10px;
  149.  background-color: rgba(255, 255, 255, 0);
  150. }
  151. /*定义滚动条的轨道,内阴影及圆角*/
  152. *::-webkit-scrollbar-track {
  153.  border-radius: 10px;
  154.  background-color: rgba(230, 230, 230, 0.05);
  155. }
  156. *:hover::-webkit-scrollbar-track {
  157.  background-color: rgba(230, 230, 230, 0.5);
  158. }
  159. /*定义滑块,内阴影及圆角*/
  160. *::-webkit-scrollbar-thumb {
  161.  height: 20px;
  162.  border-radius: 10px;
  163.  -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
  164.  background-color: rgba(216, 216, 216, 0.4);
  165.  transition: background-color 1s;
  166. }
  167. *:hover::-webkit-scrollbar-thumb {
  168.  background-color: rgba(216, 216, 216, 1);
  169. }
  170. *::-webkit-scrollbar-thumb:hover {
  171.  background-color: rgba(190, 190, 190, 1);
  172. }
  173. *::-webkit-scrollbar-thumb:active {
  174.  background-color: rgba(160, 160, 160, 1);
  175. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/499561
推荐阅读
相关标签
  

闽ICP备14008679号