![]()
基于 Vue 实现的 gantt-like 图表 ,用于排班展示

npm i v-gantt-chart --save
Include plugin in your main.js file.
import Vue from 'vue'
import vGanttChart from 'v-gantt-chart';
Vue.use(vGanttChart);
<script src="https://unpkg.com/v-gantt-chart/dist/v-gantt-chart.umd.min.js"></script>
<body>
<div id="app">
<v-gantt-chart></v-gantt-chart>
</div>
</body>
<!-- 先引入vue -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- 再引入v-gantt-chart.js -->
<script src="./v-gantt-chart.js"></script>
<script>
new Vue({
el: '#app',
})
</script>
</html>
<template>
<v-gantt-chart :startTime="startTime"
:endTime="endTime"
:datas="datas">
<template v-slot:block="{data,item}">
<!-- 你的容器块组件 -->
<Test :data="data" :item="item"></Test>
</template>
<template v-slot:left="{data}">
<!-- 你的行名组件 -->
<TestLeft :data="data"></TestLeft>
</template>
<template v-slot:title>
<!-- 你的表头组件 -->
hola
</template>
</v-gantt-chart>
</template>
import Test from "./test.vue"; //你自己的gantt条容器
import TestLeft from "./test-left.vue"; //你自己的行名称组件
import { mockDatas } from "@src/mock/index.js"; //伪造的数据
import dayjs from "dayjs" //时间库
export default {
name: "App",
components: { Test, TestLeft },
data() {
return {
startTime: dayjs().toString(),//时间轴开始时间
endTime: dayjs()
.add(2, "d")
.add(2, "h")
.add(5, "s").toString(), //时间结束时间
datas: mockDatas(100), // gantt数据
};
},
};
在默认情况下(即customGenerateBlocks为false)的渲染的数据需要特殊格式 ,目前要求数组中每一个值均为对象,且有gtAarry对象数组这个属性(默认取gtArray,也可以通过arrayKeys属性自定义需要渲染的数组)
数组中每一个对象需有两个属性,start和end(不提供的情况,偏移与宽度将为0),数值需为合法的时间字符串.例如
[
{
id:'test', //非必须
gtArray:[ //默认的需要渲染的数组
{
name:'test', //非必须
start:'2019-01-11 18:18:18',
end:'2019-01-11 18:18:18'
}
],
customKey:[ //自定义的需要渲染的数组
{
id:'test', //非必须
start:'2019-01-11 18:18:18',
end:'2019-01-11 18:18:18'
}
]
}
]
// 假设你传入的数据为
[
{
id:'arrayOne',
name:'sala',
gtArray:[
{
name:'itemOne',
start:'2019-01-11 18:18:18',
end:'2019-01-11 18:18:18'
// ...其他属性
}
],
//...其他属性
}
//... 其他数组数据
]
两种 需要注意customGenerateBlocks 为 false(默认值) 的情况<template v-slot:block="{data,item}">
<!-- 你的容器块组件 -->
<Test :data="data" :item="item"></Test>
</template>
data 为 gantt图表中每一行的所有数据
如下
{
id:'arrayOne',
name:'sala',
gtArray:[{...}],
//...
}
item 为 gantt图表中一个小方块对数据
如下
{
name:'itemOne',
start:'2019-01-11 18:18:18',
end:'2019-01-11 18:18:18'
//...
}
customGenerateBlocks 为 true 的情况此时arrayKeys,itemkey将不再次生效,如何渲染,渲染什么,将由你自己决定,下方是一个例子
<template v-slot:block="{data,
getPositonOffset,
getWidthAbout2Times,
isInRenderingTimeRange,
startTimeOfRenderArea,
isAcrossRenderingTimeRange,
endTimeOfRenderArea}">
<div class="myBlockContainer"
v-for="item in data.gtArray"
v-if="isInRenderingTimeRange(item.start)||isAcrossRenderingTimeRange(item.start,item.end)
||isInRenderingTimeRange(item.end)"
:key="item.id"
:style="{position:'absolute',
left:getPositonOffset(item.start)+'px',
width:getWidthAbout2Times(item.start,item.end)+'px'}">
<Test :data="data"
:item="item"></Test>
</div>
</template>
data 为gantt图表中每一行的所有数据
{
id:'test',
name:'sala',
gtArray:[{...}],
//...
}
除了data,还会提供以下属性和函数供调用
startTimeOfRenderArea
为当前渲染范围的时间轴开始时间的毫秒数
endTimeOfRenderArea
为当前渲染范围的时间轴结束时间的毫秒数
getPositonOffset(time:string):number
定位函数,根据给定字符串形式的时间生成相对时间轴起点的的偏移值
getWidthAbout2Times(start:string,end:string):number
为宽度计算函数,根据给定字符串形式的时间计算两个时间差的宽度值
isInRenderingTimeRange(time:string):boolean
判定给定的时间是否在屏幕显示的时间轴范围之内
isAcrossRenderingTimeRange(timeStart,timeEnd):boolean
判定给定的时间是否跨越了屏幕显示的时间轴范围之内
<template v-slot:left="{data}">
<!-- 你的行名组件 -->
<TestLeft :data="data"></TestLeft>
</template>
data 为 gantt图表中每一行的所有数据
{
id:'test',
name:'sala',
gtArray:[{...}],
//...
}
<template v-slot:timeline="{day , getTimeScales}">
<!-- 你的时间刻度组件 -->
<TestTimeline :day="day"></TestTimeline>
</template>
day 为 每一个刻度对应的dayjs 对象
getTimeScales(day:dayjs):dayjs[]
计算当前day可以分划多少刻度,参数为day,返回dayjs对象数组
<template v-slot:timeline="{day , getTimeScales}">
<!-- 你的时间刻度组件 -->
<span v-for="i in getTimeScales(day)"> </span>
</template>
<template v-slot:markLine="{timeConfig, getPosition}">
<!-- 你的时间标记线组件 -->
<TestMarkline :timeConfig="timeConfig" :getPosition="getPosition"></TestMarkline>
</template>
timeConfig 为 传入的timelines的每一个值
getPosition(day:string):number
计算当前时间的偏移值,参数为day,返回偏移值
<template v-slot:title>
<!-- 你的表头组件 -->
hola
</template>
通过使用vue的ref来调用组件内部的方法,params中的scrollToTime和scrollToPostion可能会择机废弃,最好使用下方的方法替代。
<template>
<v-gantt-chart ref="gantt"></v-gantt-chart>
</template>
export default {
methods:{
doScrollToPostion(){
this.$refs.gantt.scrollToPostionHandle({x:100,y:100})
},
doScrollToTime(){
this.$refs.gantt.scrollToTimehandle("Fri, 31 Jul 2020 12:41:39 GMT")
}
}
};
#clone项目,进入项目根目录
#安装
npm i
# 启动
npm run serve
or
yarn serve
#打开浏览器地址栏输入localhost:8080即可
// 2.6+语法
<template>
<v-gantt-chart :startTime="startTime"
:endTime="endTime"
:datas="datas">
<template v-slot:block="{data,item}">
<!-- 你的容器块组件 -->
<Test :data="data" :item="item"></Test>
</template>
</template>
// 2.6之前的语法
<template>
<v-gantt-chart :startTime="startTime"
:endTime="endTime"
:datas="datas">
<template slot="block" slot-scope="{data,item}"> //<--------区别在这里
<!-- 你的容器块组件 -->
<Test :data="data" :item="item"></Test>
</template>
</template>
1.6.1
1.6.0
1.5.2
1.5.1
1.5.0
1.4.0
1.3.7
1.3.6
1.3.5
1.3.4
1.3.3
1.3.2
1.3.1
1.3.0
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.3
1.1.2
MIT ©wuchouchou