
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
ry-gantt-chart
Advanced tools
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,
},
];
| 属性名 | **参数 ** | **说明 ** |
|---|---|---|
| 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 当前任务对象 |
| 名称 | 参数 | 返回值 |
|---|---|---|
| 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 ,起始日期,结束日期字段不能为空。 |
| 名称 | 说明 | 回调参数 |
|---|---|---|
| expander-change | 收起展开按钮change事件 | type:String,isExpand:Boolean | type : side、bottom |
| scaler-click | 刻度尺区域点击事件 |
| 名称 | 说明 | 类型 |
|---|---|---|
| leftHeader | - | |
| taskContent | 任务内容 | 作用域参数为 { task } ,该任务对象 |
**Demo:
FAQs
Vue3甘特图组件 An useful gantt chart component for Vue3.(work with element plus)
The npm package ry-gantt-chart receives a total of 2 weekly downloads. As such, ry-gantt-chart popularity was classified as not popular.
We found that ry-gantt-chart demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.