前言
之前实现作业车间调度问题甘特图绘制,搜索过如何用Echart绘制甘特图,发现绘制方法都一毛一样,都是通过叠加series来实现,但这样绘制出来的甘特图,不仅够丑,而且数据也难以描述,如果要在react这种mvvm中绘制的话,也没法对甘特图做数据管理,所以经过自己的思考,发现可以有更好的绘制甘特图的方法。首先先看绘制出来的甘特图效果(项目GitHub地址:https://github.com/sundial-dreams/BitMESClient)
甘特图区域可控,可以通过看Echart配置项手册(https://www.echartsjs.com/option.html#title)改变外观、坐标轴等
甘特图绘制思路
要绘制甘特图,首先想想我们需要定义怎样的数据格式,就以作业车间调度问题为例,我们的元素有:工件、机器、工序,对于机器里加工的每一个工件的每一道工序都有一个起始时间和终止时间,所以我们的数据格式定义如下:
// 工件编号,工序编号,机器编号,起始时间,终止时间
const mockData = [
{ workpiece: 0, process: 0, machine: 0, startTime: 2, endTime: 5 },
{ workpiece: 0, process: 1, machine: 1, startTime: 5, endTime: 7 },
{ workpiece: 0, process: 2, machine: 2, startTime: 7, endTime: 9 },
{ workpiece: 1, process: 0, machine: 0, startTime: 0, endTime: 2 },
{ workpiece: 1, process: 1, machine: 2, startTime: 2, endTime: 3 },
{ workpiece: 1, process: 2, machine: 1, startTime: 7, endTime: 11 },
{ workpiece: 2, process: 0, machine: 1, startTime: 0, endTime: 4 },
{ workpiece: 2, process: 1, machine: 2, startTime: 4, endTime: 7 }
];
定义好了数据格式,其实不用Echart,用原生的HTML/CSS/JS也能很轻松的绘制出甘特图,代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<style>
#gantt-chart {
width: 60rem;
height: 40rem;
}
.chart {
position: relative;
display: inline-block;
width: 40rem;
height: 40rem;
vertical-align: top;
}
.block {
position: absolute;
display: inline-block;
}
.machine {
display: inline-block;
width: 8rem;
color: gray;
font-weight: bold;
vertical-align: top;
}
.machine > .label {
}
.legend {
width: 8rem;
color: gray;
font-weight: bold;
display: inline-block;
vertical-align: top;
}
.legend-block {
width: 8rem;
}
.color {
width: 1rem;
height: 1rem;
display: inline-block;
}
.text {
width: 4rem;
display: inline-block;
color: gray;
font-weight: bold;
}
</style>
<body>
<div id="gantt-chart">
<div class="machine">
</div>
<div class="chart">
</div>
<div class="legend">
</div>
</div>
</body>
<script>
void function () {
function createEle (tag, options) {
var el = document.createElement(tag);
for (var k in options