1.2.0 • Published 11 months ago

ry-gantt-chart v1.2.0

Weekly downloads
-
License
MIT
Repository
-
Last release
11 months ago

⭐️一款基于Vue3结合Element Plus开发的实用性较强和支持大数据量操作的甘特图组件。

😇支持:
  • 查看项目和生产计划
  • 拖动或手动编辑计划任务
  • 拖动或手动调整计划进度
  • 拖动或手动移除计划任务
  • 拖动或手动新增计划任务
  • 聚焦到目标任务
  • 一键返回顶部
  • 可视区域伸展或折叠
  • 当前可视区域行数范围标记
  • 组件提供内置各种钩子函数以满足日常业务需求
  • 数据懒加载,支持大数据量(>1w条)任务展示或操作
  • ...
🙂安装
npm i ry-gantt-chart
😉引入
import { createApp } from "vue";
import App from "./App.vue";
import "./common/css/common.css";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";

import ryGanttChart from "ry-gantt-chart";
import 'ry-gantt-chart/dist/style.css'

const app = createApp(App)
  .use(ElementPlus)
  .use(ryGanttChart)
  .mount("#app");

😁使用

<script setup>
import { ref, onMounted, getCurrentInstance, computed } from "vue";
import mockGanttList from "../../mock/ganttList.js";
import unArrangeTableData from "../../mock/unArrangeTableData.js";
import dayjs from "dayjs";
const ctx = getCurrentInstance();

// 甘特图视图起始日期
const startDate = ref(
  dayjs()
    .subtract(2, "day")
    .format("YYYY-MM-DD") + " 00:00:00"
);

// 甘特图结束日期
const endDate = ref(
  dayjs()
    .add(3, "month")
    .format("YYYY-MM-DD") + " 00:00:00"
);

// 甘特图配置
const config = ref({
  type: "month", // year | month | date
  scaleWidth: 150, // px 下刻度每刻度长度
  divideBy: 2, // 上刻度
  rowHeight: 30, // 每条泳道高度
  viewHeight: 300, // 甘特图初始高度
  viewMaxHeight: 400, // 甘特图最大高度
  showCurrentTimeScaler: true, // 是否显示当前时间轴
  showRowsRange: true, // 是否显示当前可视区域显示行数范围
  showGoToTop: true, // 是否显示滚回视图顶部按钮
});

// 数据集合
const list = ref(mockGanttList(20).list);


// 甘特图左侧表格配置
const ganttTableConfig = ref({
  tableColumn: [
    {
      label: "项目",
      prop: "project",
    },
    {
      label: "生产线",
      prop: "prodLine",
    },
    {
      label: "区域",
      prop: "zone",
      "show-overflow-tooltip": true,
    },
  ],
});

// 下方待排区表格配置
const unArrangeConfig = ref({
  list: unArrangeTableData,
  tableColumn: [
    {
      label: "流水号",
      prop: "pkid",
    },
    {
      label: "工作任务",
      prop: "content",
    },
  ],
  // 待排区列表行按钮配置
  rowOperations: [
    {
      name: "查看",
      type: "success",
      click: (scope) => {
        console.log(scope);
      },
    },
  ],
  // 待排区列表操作列配置
  operationsConfig: {
    width: 100,
  },
});
const dateRange = ref([]);

const unitText = computed(() => {
  const units = {
    year: "年",
    month: "月",
    date: "日",
  };
  return units[config.value.type];
});


// 插入新任务
const insertNewTask = () => {
  const rowIndex = 2;
  ctx.refs.ryGanttChart.insertNewTask(rowIndex, {
    pkid: "8021",
    startTime: dayjs()
      .add("1", "day")
      .format("YYYY-MM-DD HH:mm:ss"),
    endTime: dayjs()
      .add("3", "day")
      .format("YYYY-MM-DD HH:mm:ss"),
    content: "检查燃油滤芯No7.",
    background: "rgb(223,102,2)",
  });
};

// 根据id删除某条任务
const handleDeleteTask = () => {
  ctx.refs.ryGanttChart.removeTaskById("23007");
};

// 点击了某条任务
const handleClickTask = (rowIndex, task) => {
  console.log("rowIndex, task: ", rowIndex, task);
};

// 获取操作过的任务集合
const handleGetModifiedData = () => {
  ctx.refs.ryGanttChart.getModifiedData((v) => console.log("v", v));
};

const toggleResults = (val, list) => {
  const idx = list.findIndex((v) => v === val);
  return idx >= list.length - 1 ? list[0] : list[idx + 1];
};
const handleChangeScaleUnit = () => {
  config.value.type = toggleResults(config.value.type, ["year", "month", "date"]);
};
const handleChangeRowHeight = () => {
  config.value.rowHeight = toggleResults(config.value.rowHeight, [30, 40, 55]);
};
const handleChangeTopScale = () => {
  config.value.divideBy = toggleResults(config.value.divideBy, [1, 2, 3, 4]);
};
const handleChangeDownScale = () => {
  config.value.scaleWidth = toggleResults(config.value.scaleWidth, [100, 150, 300]);
};
const handleChangeQty = () => {
  const qty = toggleResults(list.value.length, [20, 200, 500]);
  list.value = mockGanttList(qty)["list"];
};
const handleDateChange = () => {
  [startDate.value, endDate.value] = dateRange.value;
};
// 根据id聚焦到某条任务
const handleFouce = () => {
  ctx.refs.ryGanttChart.scrollToTaskById("23022");
};
</script>

<template>
  <h1 class="title">RY-GANTT-CHART</h1>
  <div class="ctrl-wrapper">
    <div style="width: 300px;overflow: hidden;padding-right:20px;">
      <el-date-picker
        style="width:95%"
        type="daterange"
        v-model="dateRange"
        range-separator="至"
        start-placeholder="开始时间"
        end-placeholder="结束时间"
        value-format="YYYY-MM-DD HH:mm:ss"
        :clearable="false"
        @change="handleDateChange"
      ></el-date-picker>
    </div>

    <el-button type="success" @click="handleChangeQty">数据量</el-button>
    <el-button type="success" @click="handleChangeTopScale">上刻度宽度</el-button>
    <el-button type="success" @click="handleChangeDownScale">下刻度宽度</el-button>
    <el-button type="success" @click="handleChangeRowHeight">行高</el-button>
    <el-button type="success" @click="handleDeleteTask">删除某条任务</el-button>
    <el-button type="success" @click="handleFouce">聚焦到某一任务</el-button>
    <el-button type="success" @click="insertNewTask">插入新增任务</el-button>
    <el-button type="success" @click="handleGetModifiedData">获取操作项</el-button>
    <el-button type="success" @click="handleChangeScaleUnit">{{ unitText }}</el-button>
  </div>
  <ryGanttChart
    ref="ryGanttChart"
    :config="config"
    :list="list"
    :startDate="startDate"
    :endDate="endDate"
    :ganttTableConfig="ganttTableConfig"
    :unArrangeConfig="unArrangeConfig"
  >
    <!-- 任务条内容插槽 -->
    <template v-slot:taskContent="slotProps">
      <div class="text" @click="handleClickTask(slotProps.rowIndex, slotProps.task)">
        {{ `${slotProps.task.content} (id:${slotProps.task.pkid})` }}
      </div>
    </template>
  </ryGanttChart>
</template>

<style scoped lang="scss">
.title {
  margin: 0;
  text-align: center;
  font-family: "Times New Roman", Times, serif;
}
.text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ctrl-wrapper {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  padding: 10px 0;

  h1 {
    margin: 0;
    width: 500px;
    font-size: 30px;
    flex: 1;
  }
}
</style>

🧐数据结构

import { dayjs } from "../common/utils";

export default (qty) => {
  let taskCount = 23000;
  let count = 0;
  return {
    list: Array.from({ length: qty }, (_, index) => {
      count += 3;

      return {
        pkid: index.toString(), // pkid ->当前行父任务主键
        project:
          "ROCKET" +
          dayjs()
            .add(count, "day")
            .format("MMDD"),
        prodLine: "生产线-" + index,
        zone: "月球",
        /* tasks -> 子任务对象属性  */
        tasks: [
          {
            pkid: (taskCount++).toString(), // 子任务主键
            startTime:
              dayjs()
                .subtract(1, "day")
                .format("YYYY-MM-DD") + " 00:00:00", // startTime -> 任务开始日期
            endTime:
              dayjs()
                .add(1, "day")
                .format("YYYY-MM-DD") + " 00:00:00", // endTime ->任务结束日期
            content: "Daily check", // 任务内容
            background: "rgb(182,220,22)", // background ->任务条背景色
            color: "black", // color ->任务条字体颜色
            disabled: false, // disabled ->当前任务是否无法被拖动或编辑
          },
          // ...
       
        ],
      };
    }),
  };
};
export default [
  {
    pkid: "1055",
    content: "安装车门",
    rangeDays: 3,
  },
  {
    pkid: "1056",
    content: "安装倒后镜",
    rangeDays: 3,
  },
  {
    pkid: "1067",
    content: "全车检查",
    rangeDays: 3,
  },
  {
    pkid: "1058",
    content: "更换ECU",
    rangeDays: 3,
  },
];

RY-GANTT-TABLE 属性

属性名参数 说明
list:Array数据结构见demo示例甘特图源数据
startDate:String"YYYY-MM-DD HH:mm:ss"刻度尺起始日期
endDate:String"YYYY-MM-DD HH:mm:ss"刻度尺结束日期
disabeld:Booleandefault:false甘特图是否只读
showSideExpanderdefault:false是否显示“展开收起”侧栏按钮
showBottomExpanderdefault:true是否显示“展开更多”甘特图视图按钮
showUnArrangeTabledefault:true是否显示待排区,默认true
config:Object甘特图视图区配置
type:String | 'year' ,'month' , 'date'刻度尺单位范围
scaleWidth:Number刻度尺下部每刻度间隔宽度(px)
divideBy:Number刻度尺上部刻度根据每间隔下部刻度多少个进行划分
rowHeight:Number泳道行高(px)
viewHeight:Number甘特图出初始高度
viewMaxHeight:Number甘特图最大高度
showCurrentTimeScaler:Boolean是否显示当前时间节点标线
showGoToTop:Boolean是否显示返回顶部按钮
showRowsRange:Boolean是否显示当前可视区域行数范围
topScaleFormatter(obj)obj:Object | 刻度尺上部每刻度内容格式化处理函数 | 需返回字符串
downScaleFormatter(obj)obj:Object | 刻度尺下部每刻度内容格式化处理函数 | 需返回字符串
unArrangeConfig:Object
待排区域表格配置
tableColumn:Array表头配置
data:Array待排区域表格源数据
rowOperations:Array行操作配置
operationsConfig:Object
ganttTableConfig:Object甘特图左侧表格配置
tableColumn:Array表头配置
beforeMountData:Function(data)=>data挂载甘特图视图层数据前调用,需返回数据对象。
afterMountedData:Function(data) =>{}挂载甘特图视图层数据完成后调用
beforeRemove:Function(task,next)=>{}完成移除任务前调用 | task:Object 当前任务对象 | next:Function 调用next执行后续逻辑
beforeHorizontalMove:Function(task,next)=>{}完成水平移动任务前调用 | task:Object 当前任务对象 | next:Function 调用next执行后续逻辑
beforeVerticalMove:Function(task,next)=>{}完成垂直移动任务前调用 | task:Object 当前任务对象 | next:Function 调用next执行后续逻辑
beforeInsertToGantt:Function(task,next)=>{}完成插入新数据前调用 | task:Object 当前任务对象 | next:Function 调用next执行后续逻辑
beforeDropToUnArrange(task,next)=>{}完成放置到待排区前校验 | task:Object 当前任务对象 | next:Function 调用next执行后续逻辑
afterDropToUnArrange(task)=>{}完成放置到待排区后调用 | task:Object 当前任务对象

RY-GANTT-CHART 方法

名称参数返回值
insertNewTask(rowIndex,task)插入任务task到某行rowrowIndex : Number | 行索引 task:Object 任务内容 (必要属性参考甘特图数据结构)
getModifiedData(res)(res)=>{} | res:变化过的任务数据集合Promise | 变化过的任务数据集合
getUnArrangeTableData()Array | 待排区表格数据
scrollToTaskById(id)id:string通过任务主键让视图滚动到该任务所在位置,并且会有高亮闪烁一次的圆点出现
removeTaskById(id)id:string根据任务id,从甘特图移除某条任务
editTask({targetRowIndex,task})targetRowIndex:number , task:Object手动编辑某条任务 | targetRowIndex :要把该任务移动到某行的索引 | task :任务对象,任务的pkid ,起始日期,结束日期字段不能为空。

RY-GANTT-CHART 事件

名称说明回调参数
expander-change收起展开按钮change事件type:String,isExpand:Boolean | type : side、bottom
scaler-click刻度尺区域点击事件

RY-GANTT-CHART SLOTS 插槽

名称说明类型
leftHeader-
taskContent任务内容作用域参数为 { task } ,该任务对象

**Demo: 1. npm run dev 启动这个项目,查看/examples/pages/demo 或 /examples/pages/demo1 的页面 2. 或 https://gitee.com/RYANLLL/ry-gantt-chart-demo

1.2.0

11 months ago

1.1.5

11 months ago

1.1.4

11 months ago

1.1.3

12 months ago

1.1.2

12 months ago

1.1.1

12 months ago

1.1.0

12 months ago

1.0.9

12 months ago

1.0.8

12 months ago

1.0.7

12 months ago

1.0.6

12 months ago

1.0.5

12 months ago

1.0.4

12 months ago

1.0.3

12 months ago

1.0.2

12 months ago

1.0.1

12 months ago

1.0.0

12 months ago