vue项目使用Echarts制作项目工期甘特图
1,前言
项目迭代过程中,碰上一个需求,要求用甘特图的方式显示项目的工期进度,开完会我赶紧搜索一下甘特图是啥东东,大概了解之后,做出了如下样式
Echarts版本4.5.0
vue版本2.x

2,布局和数据部分
HTML部分
<template>
<div id="index">
<div id="chart" />
</div>
</template>
CSS部分
<style lang="less" scoped>
#chart{
width: 100%;
height: 500px;
margin: 50px auto;
}
</style>
data部分
data() {
return {
chart: null, // chart实例
chartData: [], // chart数据源
startTime: '', // X轴起始时间
endTime: '', // X轴终末时间
yData: [], // Y轴项目类目
dayTime: 3600 * 24 * 1000, // 一天的毫秒,因为01.01日-01.01日,也算一天
initData: { // 可以认为是axios请求过来的数据res.data
startTime: '2020-12-01', // X轴起始时间
endTime: '2022-01-30', // X轴终末时间
value: [
{
itemName: '项目一', // 项目名
value: [
0, // 索引
'2021-06-01', // 项目开始时间
'2021-08-30', // 项目结束时间
'2021-07-01', // 项目实际开始时间
'2021-07-28' // 项目实际结束时间
]
},
{
itemName: '项目二',
value: [
1,
'2021-06-21',
'2021-07-21',
'2021-07-18',
'2021-08-10'
]
},
{
itemName: '项目三',
value: [
2,
'2021-06-01',
'2021-06-22',
'2021-06-01',
'2021-06-22'
]
},
{
itemName: '项目四',
value: [
3,
'2021-06-22',
'2021-06-30',
'2021-06-22',
'2021-07-05'
]
},
{
itemName: '项目五',
value: [
4,
'2021-06-21',
'2021-07-06',
'2021-07-01',
'2021-07-30'
]
},
{
itemName: '项目六',
value: [
5,
'2021-07-01',
'2021-07-21',
'2021-07-02',
'2021-07-30'
]
},
{
itemName: '项目七',
value: [
6,
'2021-06-18',
'2021-09-30',
'2021-06-30',
'2021-10-10'
]
}
]
}
}
}
3,制作甘特图
由于是demo,所以用的自己的数据,首先给需要用到的变量赋值
getData() {
this.chartData = this.initData.value // chart的数据
const arr = []
this.chartData.forEach(item => {
arr.push(item.itemName)
})
this.yData = arr // Y轴的类目标题
this.startTime = this.initData.startTime // X轴开始值
this.endTime = this.initData.endTime // X轴结束值
this.setData()
}
赋值之后,根据值,定义初始参数配置
setData() {
const _this = this
const param = {
title: {
text: '项目执行情况',
left: 'center'
},
tooltip: {
// 自定义提示信息
// params为当前点击图形元素的数据信息的对象
formatter(params) {
// 计划开始时间
let planStartDate = params[0].value[1]
// 计划结束时间
let planEndDate = params[0].value[2]
// 实际开始时间
let practiceStartDate = params[0].value[3]
// 实际结束时间
let practiceEndDate = params[0].value[4]
// 项目周期(毫秒值):计划结束日期 - 计划开始日期
// eslint-disable-next-line
let projectCycle_millisecond = +Echarts.number.parseDate(params[0].value[2]) - +Echarts.number.parseDate(params[0].value[1])
// 项目周期(天数)
let projectCycle_days = projectCycle_millisecond / _this.dayTime + 1
return params[0].name + '<br/>'
+ '计划开始时间:' + planStartDate + '<br/>'
+ '计划结束时间:' + planEndDate + '<br/>'
+ '项目周期:' + projectCycle_days + '天<br/>'
+ '实际开始时间:' + practiceStartDate + '<br/>'
+ '实际结束时间:' + practiceEndDate
}
},
dataZoom: [
{
// 区域缩放组件的类型为滑块,默认作用在x轴上
type: 'slider',
// 区域缩放组件的过滤模式,weakFilter:在进行区域缩放时,允许图形的一部分在坐标系上(可见),另一部分在坐标系外(隐藏)
filterMode: 'weakFilter',
showDataShadow: false,
top: 450,
height: 10,
// 区域缩放组件边框颜色
borderColor: 'transparent',
// 区域缩放组件边框背景
backgroundColor: '#e2e2e2',
// 区域缩放组件上的手柄的样式
// eslint-disable-next-line
handleIcon: 'M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z',
// 手柄大小
handleSize: 20,
// 为手柄设置阴影效果
handleStyle: {
shadowBlur: 6,
shadowOffsetX: 1,
shadowOffsetY: 2,
shadowColor: '#aaa'
},
labelFormatter: ''
},
{
// 区域缩放组件的类型为内置在坐标系中,默认作用在x轴的坐标系中
type: 'inside',
// 区域缩放组件的过滤模式,weakFilter:在进行区域缩放时,允许图形的一部分在坐标系上(可见),另一部分在坐标系外(隐藏)
filterMode: 'weakFilter'
}
],
// 图表底板
grid: {
height: 330,
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
}
},
xAxis: {
// x轴类型为时间轴
type: 'time',
// 最小值
min: _this.startTime,
// 最大值
max: _this.endTime,
axisLabel: {
// 强制显示所有标签
interval: 0
}
},
yAxis: {
data: _this.yData
},
legend: {
selectedMode: false,
left: '70%',
top: 10,
data: ['计划工期', '实际工期']
},
series: [
{
type: 'custom',
// 使用自定义的图形元素
renderItem: _this.renderItem,
name: '计划工期',
itemStyle: {
opacity: 0.7,
color: '#409EFF'
},
encode: {
// 将维度1和维度2的数据映射到x轴
x: [1, 2],
// 将维度0的数据映射到y轴
y: 0
},
data: _this.chartData
},
// 没有给它设置data,只是为了通过这个系列,显示图例(legend)而已
{
type: 'custom',
name: '实际工期',
itemStyle: {
color: '#F56C6C'
}
}
]
}
this.init(param)
}
上述参数配置中,还需定义一下自定义的图形绘制方法
// params为data中的数据项的信息对象 api是可调用的方法集合,可以对data中的数据项进行操作
renderItem(params, api) {
// 取出data中数据项的第一个维度的值
let categoryIndex = api.value(0)
// ===============计划工期进度条
// 计划开始日期(在屏幕上的像素值)
// 将数据项中的数值对应的坐标系上的点,转换为屏幕上的像素值
// 坐标系上的点:是数据项映射到坐标系的x轴和y轴后,对应的位置
// 屏幕上的像素值:是坐标系上的点,在屏幕上的位置
let planStartDate = api.coord([api.value(1), categoryIndex])
// 计划结束日期(在屏幕上的像素值)
let planEndDate = api.coord([api.value(2), categoryIndex])
// 由于data.value中维度1和维度2的数据会被映射到x轴,而x轴的type为time,即时间轴,
// 所以api.value(1)和api.value(2)获取到的值是将日期转换后的毫秒值
// 设置图形的高度
// 获得Y轴上数值范围为1的一段所对应的像素长度;这是官方文档的注释,对于api.size()方法,目前我还不是很理解;先做个标记??? 以后再说
let height = api.size([0, 1])[1] * 0.4
let width = planEndDate[0] - planStartDate[0]
if (width <= 10) {
width = 3
}
// 使用graphic图形元素组件,绘制矩形
// clipRectByRect方法,在绘制矩形时,如果矩形大小超出了当前坐标系的包围盒,则裁剪这个矩形
let rectShape1 = Echarts.graphic.clipRectByRect({
// 矩形的位置
x: planStartDate[0],
y: planStartDate[1],
// 矩形的宽高
width,
height
},
{
// 当前坐标系的包围盒
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
})
// ===============实际工期进度条
let rectShape2 = null
// 判断实际开始日期和结束日期是否为空
if (api.value(3) !== '' && api.value(4) !== '') {
// 实际开始日期(在屏幕上的像素值)
let practiceStartDate = api.coord([api.value(3), categoryIndex])
let practiceEndDate = api.coord([api.value(4), categoryIndex])
let widthNum = practiceEndDate[0] - practiceStartDate[0]
if (widthNum <= 5) {
widthNum = 3
}
// 使用graphic图形元素组件,绘制矩形
// clipRectByRect方法,在绘制矩形时,如果矩形大小超出了当前坐标系的包围盒,则裁剪这个矩形
rectShape2 = Echarts.graphic.clipRectByRect({
// 矩形的位置
x: practiceStartDate[0],
y: practiceStartDate[1],
// 矩形的宽高
width: widthNum,
height
}, {
// 当前坐标系的包围盒
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
})
}
let lineObj = {}
// 如果项目还没开始,那么只渲染计划工期的进度条
if (rectShape2 === null) {
// 设置绘制的矩形的元素定义
lineObj = rectShape1 && {
type: 'group',
children: [
{
// 类型为矩形
type: 'rect',
// 具体形状
shape: rectShape1,
// 样式
style: api.style({
fill: '#409EFF'
})
}
]
}
} else {
// 渲染计划工期和实际工期
// 设置绘制的矩形的元素定义
lineObj = rectShape1 && rectShape2 && {
type: 'group',
children: [
{
// 类型为矩形
type: 'rect',
// 具体形状
shape: rectShape1,
// 样式
style: api.style({
fill: '#409EFF'
})
},
{
// 类型为矩形
type: 'rect',
// 具体形状
shape: rectShape2,
// 样式
style: api.style({
fill: '#F56C6C'
})
}
]
}
}
return lineObj
}
这些都ok,我们就可以初始化chart了
init(param) {
this.chart = Echarts.init(document.getElementById('chart'))
this.chart.setOption(param)
}
大功告成
如果看了觉得有帮助的,我是@鹏多多,欢迎 点赞 关注 评论;
END

往期文章
个人主页
vue项目使用Echarts制作项目工期甘特图的更多相关文章
- vue中使用echarts 制作某市各个街道镇的地图
我要制作的是青州的各街道镇的地图,于是我上网搜,很感谢这篇文章的作者给的提点和帮助https://www.jianshu.com/p/7337c2f56876 现在我把自己的制作过程做个整理,以山东省 ...
- java项目使用Echarts 做柱状堆叠图,包含点击事件
基础知识请自行百度查看,以下直接贴出实现代码: <%@ page pageEncoding="UTF-8"%><!DOCTYPE html><html ...
- Vue中使用ECharts画散点图加均值线与阴影区域
[本文出自天外归云的博客园] 需求 1. Vue中使用ECharts画散点图 2. 在图中加入加均值线 3. 在图中标注出阴影区域 实现 实现这个需求,要明确两点: 1. 知道如何在vue中使用ech ...
- vue项目使用echarts按需引入实现地图动态显示效果时,报错:TypeError: Cannot read property 'dataToPoint' of undefined
vue项目使用echarts按需引入实现地图动态显示效果时,报错:TypeError: Cannot read property 'dataToPoint' of undefined 借鉴了该大神的文 ...
- [转]用Excel制作甘特图并管理项目
对于比较简单的项目管理,或绘制甘特图,选用电子表格工具——比如价格高也最强大的Excel.开源的OpenOffice.免费的WPS——可能比项目管理软件更方便. 1. XL-Easy Gantt 模板 ...
- 《论vue在前后端分离项目中的实践之年终总结》
我是2014年的时候开始了解知道的vue,当时vue还不太成熟,想用但是又怕自己hold不住,况且那时候vue还没有成熟的(路由.验证.ui组件)插件,社区也是不温不火的,再说也没有合适的机遇让我去项 ...
- Vue.js——60分钟browserify项目模板快速入门
概述 在之前的一系列vue.js文章,我们都是用传统模式引用vue.js以及其他的js文件的,这在开发时会产生一些问题. 首先,这限定了我们的开发模式是基于页面的,而不是基于组件的,组件的所有代码都直 ...
- 从零开始编写自己的C#框架(10)——项目实施计划与甘特图
不知不觉本系列已经写了一个月,编码前的各项工作到此也终于结束了.回头看看这一个月走过来,白天上班晚上码字查资料,写写改改,挺不容易的.很多时候有些知识会用,知道是怎么回事,但并不等于能写出来.错别字. ...
- vue+websocket+express+mongodb实战项目(实时聊天)
继上一个项目用vuejs仿网易云音乐(实现听歌以及搜索功能)后,发现上一个项目单纯用vue的model管理十分混乱,然后我去看了看vuex,打算做一个项目练练手,又不想做一个重复的项目,这次我就放弃颜 ...
随机推荐
- 【敏杰开发】Beta阶段项目展示
[敏杰开发]Beta阶段项目展示 项目相关地址汇总 线上地址:http://roadmap.imcoming.top 前端仓库:https://github.com/MinJieDev/Roadmap ...
- [bug] Authentication failed for token submission (认证失败)异常
原因 gitee上下的项目,启动后能访问首页,但登录报错.原因是根据用户名上数据库查密码没有得到结果,中间任何环节有问题都可能导致,我的是因为mapper.xml中的<mapper namesp ...
- 实例:使用playbook实现httpd安装、配置、以及虚拟主机的配置
一.安装环境配置 1.在控制节点给受控主机配置本地仓库文件 [root@ansible ~]# vim /etc/yum.repos.d/dvd.repo [AppStream] name=appst ...
- WORD表格中的文字总是靠上居中不了
WORD表格中的文字总是靠上居中不了 将表格选中 然后,点击格式工具栏里的格式(第一个项目)右侧的小三角(通常显示为正文),选择清除格式,然后,再用表格与边框工具栏中的居中功能设置居中就可以了 将表格 ...
- IDEA Git 项目实战场景
实战场景一:上班啦,从远程仓库克隆项目到本地仓库(Clone) 打开 IDEA,在 Check out from Version Control 下拉菜单选择 Git,如下: 在弹出窗口的 URL 地 ...
- 大师画PCB板子
1.低频电路对于模拟地和数字地要分开布线,不能混用 2.如果有多个A/D转换电路,几个ADC尽量放在一起,只在尽量靠近该器件处单点接地,AGND和DGND都要接到模拟地,电源端子都要接到模拟电源端子: ...
- Java基础之概述
1. 什么是程序 程序是计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合 2. Java三大版本 Java SE 标准版 Java EE 企业版 Java ME 小型版 3. Java重要 ...
- Archlinux+win10双系统扩容Boot/ESP分区
环境 系统:Archlinux + Windowns10 双系统 软件:MiniTool Partition Wizard 免费版 + Diskgenius 免费版 分区:原ESP分区100M 原恢复 ...
- [源码解析] 深度学习分布式训练框架 Horovod (1) --- 基础知识
[源码解析] 深度学习分布式训练框架 Horovod --- (1) 基础知识 目录 [源码解析] 深度学习分布式训练框架 Horovod --- (1) 基础知识 0x00 摘要 0x01 分布式并 ...
- Unity 2018.3.0f 版本用C#编程启动VS时出现"Visual Studio 2010 Shell 无效的许可证数据"的解决办法
C#编程时,启动VS出现的问题如图: 网上有提到用更改注册表的方式,亲测效果未发生改变,在不确定修改后效果如何时,尽量先将原有的数据备份下来: 本文介绍楼主用另外一种方式解决的: 由于脚本系统默认启动 ...