npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ry-gantt-chart

v1.2.0

Published

Vue3甘特图组件 An useful gantt chart component for Vue3.(work with element plus)

Downloads

27

Readme

⭐️一款基于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:Boolean | default:false | 甘特图是否只读 | | showSideExpander | default:false | 是否显示“展开收起”侧栏按钮 | | showBottomExpander | default:true | 是否显示“展开更多”甘特图视图按钮 | | showUnArrangeTable | default: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到某行row | rowIndex : 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