DHTMLX Gantt

安装依赖

 pnpm add dhtmlx-gantt -save 

页面使用

<template>
  <section class="my-gantt">
    <div class="time-box">
      <a-radio-group v-model:value="timeState" @change="changeTime" button-style="solid">
        <a-radio-button v-for="(time, t_index) in data.timeList" :key="t_index" :value="time.code" size="default" border>{{
          time.name
        }}</a-radio-button>
      </a-radio-group>
    </div>
    <div id="gantt_here" class="gantt-container"></div>
  </section>
</template>

<script setup lang="tsx">
  import { reactive, toRefs, onBeforeMount, onMounted, watchEffect, defineExpose, onBeforeUnmount } from 'vue';
  import { gantt } from 'dhtmlx-gantt';
  import 'dhtmlx-gantt/codebase/dhtmlxgantt.css';
  import { ref } from 'vue';
  // import center from '@/views/demo/page/account/center/index.vue';
  // import demoData from './ganttData.json';

  //初始化甘特图
  const initGantt = () => {
    gantt.config.grid_width = 350;
    gantt.config.add_column = false; //添加符号
    //时间轴图表中,如果不设置,只有行边框,区分上下的任务,设置之后带有列的边框,整个时间轴变成格子状。
    gantt.config.autofit = true;
    gantt.config.row_height = 50; //设置行高
    gantt.config.bar_height = 30; //设置时间条高度
    gantt.config.fit_tasks = false; //自动延长时间刻度,以适应所有显示的任务
    gantt.config.auto_types = true; //将包含子任务的任务转换为项目,将没有子任务的项目转换回任务
    gantt.config.xml_date = '%Y-%m-%d'; //甘特图时间格式
    gantt.config.readonly = true; //是否只读
    gantt.config.details_on_dblclick = true; //双击任务是否打开详细信息
    gantt.i18n.setLocale('cn'); //设置语言
    // gantt.config.scale_unit = 'day'; //时间轴单位
    // gantt.config.step = 1; //单位数
    // gantt.config.date_scale = '%Y年%M'; //时间轴展现方式

    //设置时间轴上的文字内容
    gantt.templates.task_text = function (start, end, task) {
      return task.name;
    };
    // 配置表格列
    gantt.config.columns = [
      {
        name: 'billNo',
        label: '单据/任务编号',
        tree: false,
        width: '100',
        align: 'center',
      },
      {
        name: 'name',
        label: '名称',
        width: '100',
        align: 'center',
      },
      {
        name: 'number',
        label: '数量',
        width: '100',
        align: 'center',
      },
      {
        name: 'start_date',
        label: '开工日期',
        width: '100',
        align: 'center',
      },
      {
        name: 'end_date',
        label: '完工日期',
        width: '100',
        align: 'center',
      },
      {
        name: 'action',
        label: '操作',
        width: '100',
        align: 'center',
        template: function (task) {
          return `<a href="javascript:void(0)" class="gantt-action-btn" data-task-id="${task.id}">排产</a>`;
        },
      },
    ];
    // 设置提示框
    gantt.plugins({
      tooltip: true,
    });
    gantt.templates.tooltip_text = function (start, end, task) {
      return `        <div>
            名称:<strong>${task.name}</strong><br/>
            开工日期: ${gantt.templates.tooltip_date_format(start)}<br/>
            完工日期: ${gantt.templates.tooltip_date_format(end)}<br/>
            数量: ${task.number}</div>`;
    };
    gantt.init('gantt_here'); //初始化
    gantt.parse(demoData); //填充数据
    scrollInit(); //拖拽滚动视图
    gantt.ext.zoom.init(zoomConfig); //配置初始化扩展
    gantt.ext.zoom.setLevel('month'); //切换到指定的缩放级别
  };

  // 选项卡选择值
  const data = reactive({
    timeList: [
      {
        name: '日',
        code: 'day',
      },
      {
        name: '周',
        code: 'week',
      },
      {
        name: '月',
        code: 'month',
      },
      {
        name: '季',
        code: 'quarter',
      },
      {
        name: '年',
        code: 'year',
      },
    ],
    timeState: 'month',
  });
  // 选项卡默认值
  const timeState = ref('month');
  // 选项卡配置
  const zoomConfig = {
    levels: [
      {
        name: 'day',
        scale_height: 60,
        scales: [{ unit: 'day', step: 1, format: '%d %M' }],
      },
      {
        name: 'week',
        scale_height: 60,
        scales: [
          {
            unit: 'week',
            step: 1,
            format: function (date) {
              let dateToStr = gantt.date.date_to_str('%m-%d');
              let endDate = gantt.date.add(date, -6, 'day');
              let weekNum = gantt.date.date_to_str('%W')(date); //第几周
              return dateToStr(endDate) + ' 至 ' + dateToStr(date);
            },
          },
          {
            unit: 'day',
            step: 1,
            format: '%d', // + "周%D"
            css: function (date) {
              if (date.getDay() === 0 || date.getDay() === 6) {
                return 'day-item weekend weekend-border-bottom';
              } else {
                return 'day-item';
              }
            },
          },
        ],
      },
      {
        name: 'month',
        scale_height: 60,
        min_column_width: 18,
        scales: [
          { unit: 'month', format: '%Y-%m' },
          {
            unit: 'day',
            step: 1,
            format: '%d',
            css: function (date) {
              if (date.getDay() === 0 || date.getDay() === 6) {
                return 'day-item weekend weekend-border-bottom';
              } else {
                return 'day-item';
              }
            },
          },
        ],
      },
      {
        name: 'quarter',
        height: 60,
        min_column_width: 110,
        scales: [
          {
            unit: 'quarter',
            step: 1,
            format: function (date) {
              let yearStr = new Date(date).getFullYear() + '年';
              let dateToStr = gantt.date.date_to_str('%M');
              let endDate = gantt.date.add(gantt.date.add(date, 3, 'month'), -1, 'day');
              return yearStr + dateToStr(date) + ' - ' + dateToStr(endDate);
            },
          },
          {
            unit: 'week',
            step: 1,
            format: function (date) {
              let dateToStr = gantt.date.date_to_str('%m-%d');
              let endDate = gantt.date.add(date, 6, 'day');
              let weekNum = gantt.date.date_to_str('%W')(date);
              return dateToStr(date) + ' 至 ' + dateToStr(endDate);
            },
          },
        ],
      },
      {
        name: 'year',
        scale_height: 50,
        min_column_width: 150,
        scales: [
          { unit: 'year', step: 1, format: '%Y年' },
          { unit: 'month', format: '%Y-%m' },
        ],
      },
    ],
  };
  //拖拽滚动视图
  const scrollInit = () => {
    const nav = document.querySelectorAll('.gantt_task')[0];
    const parNav = document.querySelectorAll('.gantt_hor_scroll')[0];
    parNav.scrollLeft = 0;
    let flag;
    let downX;
    let scrollLeft;
    nav.addEventListener('mousedown', function (event) {
      flag = true;
      downX = event.clientX; // 获取到点击的x下标
      scrollLeft = this.scrollLeft; // 获取当前元素滚动条的偏移量
    });
    nav.addEventListener('mousemove', function (event) {
      if (flag) {
        let moveX = event.clientX;
        let scrollX = moveX - downX;
        parNav.scrollLeft = scrollLeft - scrollX;
      }
    });
    // 鼠标抬起停止拖动
    nav.addEventListener('mouseup', function () {
      flag = false;
    });
    // 鼠标离开元素停止拖动
    nav.addEventListener('mouseleave', function (event) {
      flag = false;
    });
  };
  // 数据列表
  const demoData = {
    data: [
      {
        id: 1,
        billNo: 'WORK39847',
        name: 'A.101.1.0001XX物料名称',
        number: 0,
        start_date: '2023-09-01',
        end_date: '2023-09-10',
        action: '操作',
        color: '#009dff',
      },
      {
        id: 2,
        billNo: 'TASK001',
        name: '机加工车间工作中心1',
        number: 5,
        start_date: '2021-01-01',
        end_date: '2021-01-15',
        action: '操作',
        color: '#36c67d',
      },
      {
        id: 3,
        billNo: 'BG-004',
        name: '车窗清洗',
        number: 3,
        start_date: '2021-01-01',
        end_date: '2021-01-15',
        action: '操作',
        color: '#36c67d',
      },
      {
        id: 4,
        billNo: 'BG-004',
        name: '车窗清洗',
        number: 3,
        start_date: '2021-01-01',
        end_date: '2021-01-15',
        action: '操作',
        color: '#36c67d',
      },
    ],
  };
  // 选项卡切换事件
  const changeTime = (e) => {
    timeState.value = e.target.value;
    gantt.ext.zoom.setLevel(timeState.value);
  };
  onBeforeMount(() => {});
  onBeforeUnmount(() => {
    document.addEventListener('click', handleButtonClick);
  });
  onMounted(() => {
    initGantt();
    document.addEventListener('click', handleButtonClick);
  });
  watchEffect(() => {});
  defineExpose({
    ...toRefs(data),
  });
  // 点击排产
  function handleButtonClick(e) {
    const target = e.target.closest('.gantt-action-btn');
    if (target) {
      const taskId = target.dataset.taskId;
      handleEdit(taskId);
    }
  }
  function handleEdit(taskId) {
    // 实现编辑任务的逻辑
    console.log(`编辑任务ID: ${taskId}`);
  }
</script>
<style scoped lang="less">
  .my-gantt {
    margin: 15px;
    height: calc(100vh - 130px);
    width: 87.5vw;
    .time-box {
      text-align: center;
      margin-bottom: 20px;
    }
    :deep(.gantt-container) {
      width: 87.5vw;
      height: calc(100vh - 180px);
      .weekend {
        background: #ff9e2f;
        color: #fff;
      }
    }
  }
</style>

dhtmlxgantt是一个功能强大的JavaScript Gantt图库,用于创建交互式和可自定义的甘特图。这个库提供了一系列的配置选项,可以根据需要自定义甘特图的视图和行为。 引用提供了一些关于tooltip(工具提示)的配置选项。可以使用gantt.plugins({tooltip: true})启用工具提示功能。同时可以使用gantt.templates.tooltip_text函数来自定义工具提示的文本内容和格式。在函数中可以使用task对象的属性来填充工具提示文本。 引用展示了如何自定义任务内部的显示内容。可以使用gantt.templates.task_text函数来自定义任务的文本内容。在函数中可以使用task对象的属性来创建自定义的HTML元素。 引用提供了关于Gantt图的列配置和日期格式化的信息。可以使用gantt.config.columns来定义甘特图的列,包括列名、标签、对齐方式和宽度等。同时可以使用gantt.templates.task_date函数来自定义任务日期的格式化方式。 总之,dhtmlxgantt库提供了丰富的配置选项和模板函数,可以根据需要对甘特图的元素和行为进行自定义。通过使用这些配置和模板函数,您可以创建出符合需求的定制化甘特图。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Dhtmlx Gantt 常用方法及基本配置合集](https://blog.csdn.net/weixin_46221897/article/details/124723338)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值