import * as echarts from 'echarts'
function getStartTime(timestamp) {
return new Date(new Date(timestamp).toLocaleDateString()).getTime();
}
function renderItem(params, api) {
var categoryIndex = api.value(0);
var start = api.coord([api.value(1), categoryIndex]);
var end = api.coord([api.value(2), categoryIndex]);
var height = api.size([0, 1])[1] * 2;
var rectShape = echarts.graphic.clipRectByRect(
{
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height,
},
{
x: params.coordSys.x,
y: params.coordSys.y - 16,
width: params.coordSys.width,
height: params.coordSys.height,
}
);
return (
rectShape && {
type: 'rect',
transition: ['shape'],
shape: rectShape,
style: api.style(),
}
);
}
// unused
function getXaxisRange(startTime) {
return Array(24)
.fill(startTime)
.map((item, index) => {
return new Date(item + index * 3600 * 1000)
.toLocaleTimeString()
.split(':')
.slice(0, 2)
.join(':');
});
}
function getTodayStart(today) {
const [y, m, d] = [
today.getFullYear(),
today.getMonth(),
today.getDate(),
];
// debugger;
return new Date(y, m, d).getTime();
}
/** 颜色配置 */
const types = [
{ name: '运行', color: '#288AFF' },
{ name: '故障', color: '#FC9C91' },
{ name: '计划停机', color: '#FFDC94' },
{ name: '空白', color: '#F2F4F9' },
];
export default class GanttGraph {
// tooltip - 基本是固定的
tooltip = {
trigger: 'item',
axisPointer: {
type: 'none',
},
formatter: (params) => {
return `
${params.seriesName}
${params.name}
${new Date(params.value[1]).toLocaleString()} ~ ${new Date(params.value[2]).toLocaleString()}
`
}
}
grid = []
xAxis = []
yAxis = []
series = []
constructor(data, startTime) {
this.gridIndex = 0;
this.currentXaxisId = null;
this.currentYaxisId = null;
// this.startTime = new Date(startTime);
this.startTime = new Date(new Date().toLocaleDateString());
console.log('<> Gantt Created', this.startTime);
this.grid.push(this.makeGrid())
this.xAxis.push(...this.makeXaxis())
this.yAxis.push(...this.makeYaxis("设备1"))
this.series.push(...this.makeSeries({ equipmentName: "设备1" }))
}
// 构造一个新的 grid
makeGrid() {
this.gridIndex++;
return {
id: 'GRID_' + this.gridIndex,
top: 12 + 64 * (this.gridIndex - 1),
right: 64,
height: 56
}
}
// 构造一个 xAxis
makeXaxis() {
const [id1, id2] = ['' + Math.random(), '' + Math.random()]
this.currentXaxisId = id1;
return [
{
id: id1,
gridIndex: 'GRID_' + this.gridIndex,
axisTick: {
alignWithLabel: true,
inside: true,
},
type: 'time',
min: getTodayStart(this.startTime),
max: getStartTime(this.startTime.getTime() + 3600 * 24 * 1000),
splitNumber: 10,
axisLabel: {
margin: 12,
formatter: function (val) {
return new Date(val)
.toLocaleTimeString()
.split(':')
.slice(0, 2)
.join(':');
},
},
boundaryGap: false,
// data: getXaxisRange(getTodayStart(new Date())),
},
{
id: id2,
gridIndex: 'GRID_' + this.gridIndex,
axisLabel: { show: false },
axisLine: { show: false },
},
]
}
// 构造一个 yAxis
makeYaxis(equipmentName) {
const [id1, id2] = ['' + Math.random(), '' + Math.random()]
this.currentYaxisId = id1;
return [
// 主y轴
{
id: id1,
gridIndex: 'GRID_' + this.gridIndex,
type: 'value',
splitLine: { show: false },
name: equipmentName,
nameLocation: 'center',
nameGap: 56,
nameRotate: 0,
nameTextStyle: {
fontSize: 18,
},
axisLine: {
show: true,
lineStyle: {},
},
axisLabel: { show: false },
axisTick: { show: false },
},
// 辅y轴
{
id: id2,
gridIndex: 'GRID_' + this.gridIndex,
type: 'value',
splitLine: { show: false },
axisLabel: { show: false },
axisTick: { show: false },
},
]
}
// 构造一个 series
makeSeries({ equipmentName }) {
const { currentXaxisId: xAxisIndex, currentYaxisId: yAxisIndex } = this;
const bgStartTime = this.startTime.getTime();
const bgEndTime = bgStartTime + 3600 * 24 * 1000;
return [
// 沉默的背景
{
xAxisIndex,
yAxisIndex,
type: 'custom',
renderItem: renderItem,
silent: true,
itemStyle: {
opacity: 0.8,
},
encode: {
x: [1, 2],
y: 0,
},
data: [
{
name: '无数据',
value: [0, bgStartTime, bgEndTime, 0],
tooltip: { show: false },
itemStyle: {
color: '#ccc',
opacity: 0.3,
}
},
]
},
{
name: equipmentName,
xAxisIndex,
yAxisIndex,
type: 'custom',
renderItem: renderItem,
itemStyle: {
opacity: 0.8,
},
encode: {
x: [1, 2],
y: 0,
},
data: [
// 暂时先静态数据
{
name: '运行',
value: [0, 1696694400000, 1696699400000, 0],
itemStyle: {
color: types[0].color,
},
},
{
name: '运行',
value: [0, 1696730000000, 1696734040450, 0],
itemStyle: {
color: types[0].color,
},
},
{
name: '故障',
value: [0, 1696737040000, 1696754040450, 0],
itemStyle: {
color: types[1].color,
},
},
{
name: '计划停机',
value: [0, 1696755000000, 1696759000000, 0],
itemStyle: {
color: types[2].color,
},
},
{
name: '运行',
value: [0, 1696759000000, 1696769000000, 0],
itemStyle: {
color: types[0].color,
},
},
{
name: '计划停机',
value: [0, 1696769400000, 1696779000000, 0],
itemStyle: {
color: types[2].color,
},
},
],
},
]
}
init(el) {
if (typeof el == 'string') {
el = document.querySelector(el);
}
this.chart = echarts.init(el);
setTimeout(() => {
console.log("init....", this.chart, this.option);
debugger;
this.chart.setOption(this.option);
}, 200);
}
update(data) {
// todo , handle data
this.chart.setOption(this.option);
}
resize() {
this.chart.resize();
}
get option() {
return {
tooltip: this.tooltip,
grid: this.grid,
xAxis: this.xAxis,
yAxis: this.yAxis,
series: this.series,
}
}
// print option
print() {
console.log(JSON.stringify(this.option, null, 2));
}
}