背景
由于要实现一个施工状态和时间段关联展示的总览图,可以看到一个整体,也可以看局部某一个阶段的,普通的柱状图无法满足需求,要根据时间段绘制不同的区间,柱状图的高度一致,宽度随着时间区间的大小去绘制。
实现方法
custom自定义系列里面使用了一个renderItem的方法,可以绘制不同的形状。
数据格式参考: https://echarts.apache.org/zh/option.html#series-custom.data
实现代码
<!DOCTYPE html>
<html lang="">
<head>
<title>ECharts Custom 自定义渲染</title>
<meta charset="utf-8">
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
</head>
<body>
<div id="myChart" style="width: 600px;height: 400px;"></div>
<script type="text/javascript">
// 数据格式,也可根据文档里面自定义
const dataList = [
{
"value": [
"2023-04-03 16:00:00",
"2023-04-03 18:30:00"
],
"status": "a",
"duration": 2.5
},
{
"value": [
"2023-04-03 18:30:00",
"2023-04-04 00:00:00"
],
"status": "b",
"duration": 5.5
},
{
"value": [
"2023-04-04 00:00:00",
"2023-04-04 03:00:00"
],
"status": "b",
"duration": 3
},
{
"value": [
"2023-04-04 03:00:00",
"2023-04-04 04:00:00"
],
"status": "d",
"duration": 1
},
{
"value": [
"2023-04-04 04:00:00",
"2023-04-04 06:00:00"
],
"status": "a",
"duration": 2
},
{
"value": [
"2023-04-04 06:00:00",
"2023-04-04 14:00:00"
],
"status": "c",
"duration": 8
},
{
"value": [
"2023-04-04 14:00:00",
"2023-04-04 14:30:00"
],
"status": "b",
"duration": 0.5
},
{
"value": [
"2023-04-04 14:30:00",
"2023-04-04 16:30:00"
],
"status": "d",
"duration": 2
},
{
"value": [
"2023-04-04 16:30:00",
"2023-04-04 17:15:00"
],
"status": "f",
"duration": 0.75
},
{
"value": [
"2023-04-04 17:15:00",
"2023-04-04 17:30:00"
],
"status": "a",
"duration": 0.25
}
]
function addOneMinuteToDateTime(dateTimeString) {
// 解析字符串到Date对象
var date = new Date(dateTimeString);
// 转换为时间戳
var timestamp = date.getTime();
// 加上1分钟
var newTimestamp = timestamp + 1 * 60 * 1000;
// 创建新的Date对象
var newDate = new Date(newTimestamp);
// 格式化新的日期时间
var year = newDate.getFullYear();
var month = ('0' + (newDate.getMonth() + 1)).slice(-2); // 月份是从0开始的,所以需要+1
var day = ('0' + newDate.getDate()).slice(-2);
var hours = ('0' + newDate.getHours()).slice(-2);
var minutes = ('0' + newDate.getMinutes()).slice(-2);
var seconds = ('0' + newDate.getSeconds()).slice(-2);
// 返回格式化的字符串
return (
year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
);
}
function getXValues() {
const start = dataList[0].value[0];
const end = dataList[dataList.length - 1].value[1];
const datesArray = [];
currentDate = new Date(start).getTime();
const endDate = new Date(end).getTime();
datesArray.push(start);
while (currentDate <= endDate) {
// 格式化当前日期时间
datesArray.push(addOneMinuteToDateTime(currentDate));
// 增加一分钟
currentDate += 1000 * 60;
}
return datesArray;
}
let option = {
dataZoom: { show: true },
grid: [
{
top: '60%',
height: '20%'
}
],
tooltip: {
trigger: 'item',
formatter: (params) => {
return params.data.status;
},
},
xAxis: {
type: 'category',
data: getXValues()
},
yAxis: {
type: 'value',
},
series: [
{
name: '时长',
type: 'custom',
clip: true, //超出裁剪
animation: false, //关闭动画
label: {
show: false
},
renderItem: function (params, api) {
let dataItem = dataList[params.dataIndex];
let xStartValue = dataItem.value[0];
let xEndValue = dataItem.value[1];
let startIndex = option.xAxis.data.findIndex(
(item) => item === xStartValue
);
let endIndex = option.xAxis.data.findIndex(
(item) => item === xEndValue
);
let xStart = api.coord([startIndex, 0])[0];
let xEnd = api.coord([endIndex, 0])[0];
let width = xEnd - xStart;
let y = api.coord([0, 0.5])[1];
let height = api.size([0, 1])[1];
const barLength = xEnd - xStart;
var colorList = ['#C33531', '#EFE42A', '#64BD3D', '#EE9201', '#29AAE3'];
return {
type: 'rect',
shape: {
x: xStart,
y: y - height / 2,
width: width,
height: height
},
style: api.style({ fill: colorList[params.dataIndex % colorList.length] }),
};
},
data: dataList,
}
]
};
let myChart = echarts.init(document.getElementById('myChart'));
myChart.setOption(option);
</script>
</body>
</html>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。