Obtenga la interfaz de programación dhtmlx-gantt en un artículo, use dhtmlxgantt en Vue para diseñar y desarrollar el módulo de diagrama de Gantt del proyecto (artículo de visualización de la interfaz frontal (1))

Prefacio:

Este artículo se basa en el desarrollo del módulo de diagrama de Gantt en un proyecto relativamente maduro y completo. No implica descargas, instalaciones ni usos relacionados de vue relacionados con nodos.

1 Módulos a instalar

npm install dhtmlx-gantt
npm install font-awesome

(1) dhtmlxgantt es una biblioteca de complementos utilizada en el desarrollo de diagramas de Gantt y se utiliza para aplicaciones multinavegador y multiplataforma con diagramas de Gantt relativamente completos. Su componente principal es una biblioteca de JavaScript que proporciona un conjunto completo de componentes de interfaz de usuario basados ​​en Ajax.

(2) font-awesome es una biblioteca de fuentes de iconos y un marco CSS. Se proporcionan varios estilos CSS.

2 módulos de importación

    import { gantt } from 'dhtmlx-gantt';
    import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
    import 'font-awesome/css/font-awesome.min.css';

(1) Consulte el estilo dhtmlxgantt.css para mostrar la interfaz del complemento;

(2) Haga referencia a los íconos font-awesome.min.css para mostrar varios complementos de gráficos.

3 Contenido del formato de página de diseño

(1) Diseño de interfaz de pantalla frontal:

//采用html5的el插件进行前端界面设计
<template>
//建立容器,在容器下存储界面样式与风格
  <div class="app-container">
//容器下设计gantt-container,用以装载甘特图界面的显示内容
    <div ref="gantt" class="gantt-container"></div>
//调用官方在线接口,设置摁钮方式实现甘特图导出(支持多种常见格式)
    <input value="导出PDF" type="button" onclick="gantt.exportToPDF()"/>
    <input value="导出Excel" type="button" onclick='gantt.exportToExcel()'/>
    <input value="导出Png" type="button" onclick="gantt.exportToPNG()"/>
    <input value="载入execl" type="button" onclick="gantt.load()"/>
    //自动导入文件并解析为json格式,便于后续开发导入json数组自动生成甘特图。
<form action="https://export.dhtmlx.com/gantt" method="post"
          enctype="multipart/form-data">
          <input type="file" name="file" />
          <input type="" name="type" value="excel-parse"/>
          <button type="submit">转为json文件</button>
    </form>
  </div>
</template>

(2) Diseño de visualización del diagrama de Gantt (consulte el documento oficial (el contenido es muy completo solo para documentos en inglés):

El ejemplo de interfaz se puede editar en línea para facilitar el aprendizaje: Gantt: Ejemplos (dhtmlx.com)

Documentación oficial de aprendizaje: Gantt API Gantt Docs (dhtmlx.com)

La explicación de un sitio web es básicamente consistente con el documento oficial y es más detallada: tutorial dhtmlxGantt: cómo exportar/importar Excel, exportar a iCal

Un blog oficial, que resuelve algunos problemas más complejos y tiene códigos de muestra que se pueden editar en línea:

Blog DHTMLX - Biblioteca JavaScript DHTMLX - Noticias, consejos e información.

<script>
import { gantt } from 'dhtmlx-gantt';
import "dhtmlx-gantt/codebase/dhtmlxgantt.js";
import "./api.js";
import "dhtmlx-gantt/codebase/ext/dhtmlxgantt_tooltip.js";
import "dhtmlx-gantt/codebase/ext/dhtmlxgantt_marker.js";
import "dhtmlx-gantt/codebase/locale/locale_cn.js";
import "dhtmlx-gantt/codebase/dhtmlxgantt.css";
import 'font-awesome/css/font-awesome.min.css';
export default {
  name: "gantt",
  data() {
    return {
      tasks: {
        data: []
              }
            }
          },
   created() {
    this.getList();
  },
   mounted() {
    const than = this;
    //自适应甘特图的尺寸大小, 使得在不出现滚动条的情况下, 显示全部任务
    gantt.config.autosize = true;
    //允许拖拽
    gantt.config.drag_project = true;
    //只读模式
    //gantt.config.readonly = true;
    //是否显示左侧树表格
    gantt.config.show_grid = true;
    //定义日期编辑器
    var dateEditor = gantt.config.editor_types.date;
    gantt.config.editor_types.end_date = gantt.mixin({
      set_value: function(value, id, column, node){
        var correctedValue = gantt.date.add(value, -1, "day");
        return dateEditor.set_value.apply(this, [correctedValue, id, column, node]);
      },
      get_value: function(id, column, node) {
        var selectedValue = dateEditor.get_value.apply(this, [id, column, node]);
        return gantt.date.add(selectedValue, 1, "day");
      },
    }, dateEditor);
//定义各种编辑器及类型
    var textEditor = {type: "text", map_to: "text"};
    var colorEditor = {type: "color", map_to: "color"};
    var progressEditor={type:"text",map_to:"progress"};
    var startDateEditor = {type: "date", map_to: "start_date"};
    var endDateEditor = {type: "date", map_to: "end_date"};
    var priorityEditor={type: "select", map_to: "priority", options:gantt.serverList("priority")};
    var durationEditor = {type: "number", map_to: "duration", min:0, max: 100};
//设置甘特图中各个列相关配置
    gantt.config.columns = [
      {
        name: 'text',
        /*height:'40',*/
        label: '项目名称',
        editor: textEditor,
        resize: true,
          tree: true,
        width: '230',
       
        }
      },
      {
        name: "add",
        label:"",
        width: 30
      },
      {
        name:'priority',
        align: "center",
        label: "优先级",
        width:50,
        editor: priorityEditor,
        resize:true,
      },
      {
        name: "color",
        align: "center",
        label: "颜色",
        width:40,
        editor: colorEditor,
        resize:true,
      },

      {
        name: 'start_date',
        label: '项目开始时间',
        align: "center",
        editor: startDateEditor,
        resize:true,
        tree: false,
        width: '100',
      },
      {
        name: 'end_date',
        label: '项目结束时间',
        width:100,
        align: 'center',
        editor: endDateEditor,
        resize: true,
      },

      {
        name: 'sDuration',
        label: '任务期',
        align: "center",
        editor: durationEditor,
        resize:true,
        tree: false,
        width: '55',
        template: function (obj) {
          return obj.duration + '天'
        },
        hide: false
      },
      {
        name: 'progress',
        label: '项目进度',
        align: "center",
        tree: false,
        editor: progressEditor,
        resize:true,
        width: '50',
      },
     ]
//配置日期格式
    gantt.templates.task_end_date = function(date){
      return gantt.templates.task_date(new Date(date.valueOf() - 1));
    };
    var gridDateToStr = gantt.date.date_to_str("%Y-%m-%d");
    gantt.templates.grid_date_format = function(date, column){
      if(column === "end_date"){
        return gridDateToStr(new Date(date.valueOf() - 1));
      }else{
        return gridDateToStr(date);
      }
    }
//配置甘特图容器中的行列滚动条
    gantt.config.layout = {
      css: "gantt_container",
      cols: [
        {
          width: 680,
          min_width: 680,
          rows: [{
            view: "grid",
            scrollX: "gridScroll",
            scrollable: true,
            scrollY: "scrollVer"
          },
            {
              view: "scrollbar",
              id: "gridScroll",
              group: "horizontal"
            }
          ]
        },
        {
          resizer: true,
          width: 1
        },
        {
          rows: [{
            view: "timeline",
            scrollX: "scrollHor",
            scrollY: "scrollVer"
          },
            {
              view: "scrollbar",
              id: "scrollHor",
              group: "horizontal"
            }
          ]
        },
        {
          view: "scrollbar",
          id: "scrollVer"
        }
      ]
    };
//配置颜色编辑器提供颜色选择
    gantt.config.editor_types.color = {
      show: function (id, column, config, placeholder) {
        var html = "<div><input type='color' name=''" + column.name + "></div>";
        placeholder.innerHTML = html;
      },
      hide: function () {
      },
      set_value: function (value, id, column, node) {
        this.get_input(node).value = value;
      },
      get_value: function (id, column, node) {
        return this.get_input(node).value || "";
      },
      is_changed: function (value, id, column, node) {
        var input = this.get_input(node);
        return input.value !== value;
      },
      get_input: function (node) {
        return node.querySelector("input");
      },
      is_valid: function (value, id, column, node) {
        var input = this.get_input(node);
        return !!input.value;
      },
      focus: function (node) {
        var input = this.get_input(node);
        input.focus();
      }
    }
//配置时间规模,右上方日历
    gantt.config.subscales = [{
      unit: "year",
      step: 1,
      format: "%Y",
       template: weekScaleTemplate,
    },
    
      {
        unit: "day",
        step: 1,
        format: "%D",
        template:daysStyle,
      }
    ];
    // 初始化
    gantt.init(this.$refs.gantt)
    // 数据解析
    gantt.parse(this.tasks)
     //设置任务条进度内容
    gantt.templates.progress_text = function (start, end, task) {
      return "<div style='text-align:left;color:#fff;padding-left:20px'>" + Math.round(task.progress) +
        "% </div>";
    };
    //任务条显示内容
    gantt.templates.task_text = function (start, end, task) {
      return "<div style='text-align:center;color:#fff'>" + task.text + '(' + task.duration + '天)' +
        "</div>";
    }
    //任务条上的文字大小 以及取消border自带样式
    gantt.templates.task_class = function (start, end, item) {
      return item.$level == 0 ? 'firstLevelTask' : 'secondLevelTask'
    }
     //gantt图任务悬浮窗位置
    gantt.config.tooltip_offset_x = 10;
    gantt.config.tooltip_offset_y = 30;
    //激活列表展开、折叠功能
    gantt.config.open_split_tasks = true;
    //创建新事件通过点击”+“打开灯箱
    gantt.config.details_on_create = true;
    //甘特图图表宽度自适应
    gantt.config.autofit = true;
    //用户可以通过拖拽调整行高
    gantt.config.resize_rows = true;
    //图标项目栏可以任意拖拽
    gantt.config.order_branch = true;
    gantt.config.order_branch_free = true;
    //新增空白列后新增项目
    gantt.config.placeholder_task = true;
    //图标刷新后位置不变
    gantt.config.preserve_scroll = true;
    gantt.config.round_dnd_dates = true;
    //设置甘特图表头高度
    gantt.config.scale_height = 100;
    //是否显示依赖连线(取消)
    gantt.config.show_links = true;
    //点击表头可排序
    gantt.config.sort = true;
    //允许拖放
    gantt.config.drag_project = true;
    // 初始化
    gantt.init(this.$refs.gantt)
    // 数据解析
    gantt.parse(this.tasks)
    gantt.exportToExcel({
      name: "document.xlsx",
      columns: [
        {id: "text", header: "Title", width: 150},
        {id: "start_date", header: "Start date", width: 250, type: "date"}
      ],
      server: "https://myapp.com/myexport/gantt",
      visual: true,
      cellColors: true,
      data: {},
      date_format: "dddd d, mmmm yyyy"
    });

    gantt.exportToPNG({
      name: "gantt.png",      
      locale: "cn",    
      data: {},     
      server: "https://export.dhtmlx.com/gantt",
      raw: false,
      callback: function (res) {
        alert(res.gantt);
      }
    });
      gantt.exportToPDF({
      name: "gantt.pdf",      
      locale: "cn",
      skin: 'terrace',
      data: [],
      server: "https://myapp.com/myexport/gantt",
      raw: false,
      callback: function (res) {
        alert(res.data);
      }
    })
    // 初始化
    gantt.init(this.$refs.gantt)
    // 数据解析
    gantt.parse(this.tasks)
     //表格列宽自适应
    gantt.config.autofit=true;
    //r任务或者连线拖拽到浏览器屏幕外时,自动触发滚动效果
    gantt.config.autoscroll=true;
    //时间轴图表中,任务条形图的高度
    gantt.config.task_height = 28
    //时间轴图表中,甘特图的高度
    gantt.config.row_height = 36
    //时间轴图表中,如果不设置,只有行边框,区分上下的任务,设置之后带有列的边框,整个时间轴变成格子状。
    gantt.config.show_task_cells = true
    //当task的长度改变时,自动调整图表坐标轴区间用于适配task的长度
    gantt.config.fit_tasks = true;
    gantt.config.min_column_width = 40;
    gantt.config.auto_types = true;
    gantt.config.xml_date = "%Y-%m-%d";
    gantt.config.scale_unit = "month";
    gantt.config.step = 1;
    gantt.config.date_scale = "%Y年%M";
    gantt.config.start_on_monday = true;
    gantt.config.scale_height = 90;
    gantt.config.autoscroll = true;
    gantt.config.calendar_property = "start_date";
    gantt.config.calendar_property = "sPend";
    gantt.config.readonly = true;
    // 初始化
    gantt.init(this.$refs.gantt)
    // 数据解析
    gantt.parse(this.tasks)
    gantt.i18n.setLocale('cn');
    // 初始化
    gantt.init(this.$refs.gantt)
    // 数据解析
    gantt.parse(this.tasks)

(3) Acerca de la interfaz del diagrama de Gantt de representación de estilo CSS

<style lang="scss">
.firstLevelTask {
  border: none;

  .gantt_task_content {
    font-size: 13px;
  }
}

.secondLevelTask {
  border: none;
}


.weekend{
  background: #f4f7f4 !important;
}
.gantt_selected .weekend{
  background: #f7eb91 !important;
}


.thirdLevelTask {
  border: 2px solid #da645d;
  color: #da645d;
  background: #da645d;
}

.milestone-default {
  border: none;
  background: rgba(0, 0, 0, 0.45);
}

.milestone-unfinished {
  border: none;
  background: #5692f0;
}

.milestone-finished {
  border: none;
  background: #84bd54;
}

.milestone-canceled {
  border: none;
  background: #da645d;
}

html,
body {
  margin: 0px;
  padding: 0px;
  height: 100%;
  overflow: hidden;
}
.task-color-cell{
  margin:10%;
  width:20px;
  height:20px;
  border:1px solid #cecece;
  display:inline-block;
  border-radius:20px;
}

.container {
  height: 100%;
  width: 100%;
  position: relative;

  .gantt_grid_head_cell {
    padding-left: 20px;
    text-align: left !important;
    font-size: 14px;
    color: #333;
  }

  .select-wrap {
    position: absolute;
    top: 25px;
    z-index: 99;
    width: 90px;
    left: 180px;

    .el-input__inner {
      border: none;
    }
  }

  .left-container {
    height: 100%;
  }


  .parent {
    .gantt_tree_icon {
      &.gantt_folder_open {
        // background-image: url(../../../../assets/icons/tree-table.svg) !important;
      }

      &.gantt_folder_closed {
        // background-image: url(../../../../assets/icons/documentation.svg) !important;
      }
    }
  }

  .green,
  .yellow,
  .pink,
  .popular {
    .gantt_tree_icon.gantt_file {
      background: none;
      position: relative;

      &::before {
        content: "";
        width: 10px;
        height: 10px;
        border-radius: 50%;
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
      }
    }
  }

  .green {
    .gantt_tree_icon.gantt_file {
      &::before {
        background: #84bd54;
      }
    }
  }

  .yellow {
    .gantt_tree_icon.gantt_file {
      &::before {
        background: #fcca02;
      }
    }
  }

  .pink {
    .gantt_tree_icon.gantt_file {
      &::before {
        background: #da645d;
      }
    }
  }

  .popular {
    .gantt_tree_icon.gantt_file {
      &::before {
        background: #d1a6ff;
      }
    }
  }

}

.left-container {
  height: 100%;
}

.gantt_task_content {
  text-align: left;
  padding-left: 10px;
}



#gantt_here{
  width: 100vw;
  height: 100vh;
}


.fa {
  cursor: pointer;
  font-size: 14px;
  text-align: center;
  opacity: 0.2;
  padding: 5px;
}

.fa:hover {
  opacity: 1;
}

.fa-pencil {
  color: #ffa011;
}

.fa-plus {
  color: #328EA0;
}

.fa-times {
  color: red;
}

.weekend{
  background: #f4f7f4;
}
.gantt_selected .weekend{
  background: #f7eb91;
}


</style>

El estilo de implementación final es el siguiente:

Admite texto editable, haga clic en la fecha para que aparezca el calendario y seleccione la fecha, seleccione diferentes colores para diferentes tareas y muestre automáticamente el progreso. La duración total de la barra de progreso y el progreso actual se muestran en colores oscuros y claros. .

Al mismo tiempo, admite la exportación de archivos como png\pdf/execl/.

Supongo que te gusta

Origin blog.csdn.net/weixin_44979308/article/details/129280079
Recomendado
Clasificación