不知道这种图学名叫什么,暂且称之为 点线图
import { Chart, registerShape } from '@antv/g2';
// status决定线的颜色,type决定是否画圈圈
const data = [
{
'data0': "user1_test 发生告警了",
'status': 2,
'timestamp': "2021-06-23 15:29:00.000",
'type': 1
},
{
'data0': "user1_test 发生告警了",
'status': 2,
'timestamp': "2021-06-23 15:39:00.000",
'type': 0
},
{
'data0': "user1_test 发生告警了",
'status': 1,
'timestamp': "2021-06-23 15:39:00.000",
'type': 1
},
{
'data0': "user1_test 发生告警了",
'status': 1,
'timestamp': "2021-06-23 15:50:00.000",
'type': 0
},
{
'data0': "user1_test 发生告警了",
'status': 2,
'timestamp': "2021-06-23 16:29:00.000",
'type': 1
},
{
'data0': "user1_test 发生告警了",
'status': 2,
'timestamp': "2021-06-23 16:39:00.000",
'type': 0
},
{
'data0': "user1_test 发生告警了",
'status': 1,
'timestamp': "2021-06-23 16:49:00.000",
'type': 1
},
{
'data0': "user1_test 发生告警了",
'status': 1,
'timestamp': "2021-06-23 16:59:00.000",
'type': 0
},
{
'data0': "user1_test 发生告警了",
'status': 3,
'timestamp': "2021-06-23 17:29:00.000",
'type': 1
},
{
'data0': "user1_test 发生告警了",
'status': 3,
'timestamp': "2021-06-23 17:39:00.000",
'type': 0
},
{
'data0': "user1_test 发生告警了",
'status': 0,
'timestamp': "2021-06-23 17:49:00.000",
'type': 1
},
{
'data0': "user1_test 发生告警了",
'status': 0,
'timestamp': "2021-06-23 18:29:00.000",
'type': 0
},
{
'data0': "user1_test 发生告警了",
'status': 2,
'timestamp': "2021-06-23 18:39:00.000",
'type': 1
},
{
'data0': "user1_test 发生告警了",
'status': 2,
'timestamp': "2021-06-23 18:49:00.000",
'type': 0
},
]
function splitData(point,data) {
let currentStatus
let lastStatus
let resPoints = []
let tmpPoints = []
let d
for (let i = 0; i < data.length; i++) {
d = data[i];
currentStatus = d.status
if(currentStatus !== lastStatus && i !== 0){
resPoints.push({path: tmpPoints,color: getColor(data[i-1])})
tmpPoints = []
}
tmpPoints.push(point[i])
lastStatus = d.status
}
resPoints.push({path:tmpPoints,color: getColor(d)})
resPoints.forEach((path,index) => {
resPoints[index+1] && path.path.push(resPoints[index+1].path[0])
})
return resPoints;
}
function getColor(d){
let colorMap = {0: '#00C774',1: '#2A8DFF',2: '#FF8400',3: '#FF3C48'}
return colorMap[d.status]
}
function getStatusText (d) {
let textMap = { 0: '正常', 1: '通知', 2: '警告', 3: '严重' }
return textMap[d.status]
}
// 自定义画直线,并设置线的颜色
registerShape('line', 'mult-color-line', {
draw(cfg, container) {
// 自定义 Shape 需要将图形绘制在自己的 Shape/Group 里,并返回之
const group = container.addGroup();
const resPoints = splitData(cfg.points,data);
resPoints.forEach(oneLine => {
let color = oneLine.color
let path = oneLine.path
const path1 = [];
for (let i = 0; i < path.length; i++) {
let pre = 'L';
if (i === 0) {
pre = 'M';
}
path1.push([pre, path[i].x, path[i].y]);
}
group.addShape('path', {
attrs: {
path: path1,
stroke: color,
lineWidth: 2,
},
});
})
return group;
},
});
const chart = new Chart({
container: 'container',
autoFit: true,
height: 200,
});
chart.data(data);
chart.line().position('timestamp*data0').shape('mult-color-line');
for (let i = 0; i < data?.length; i++) {
const iTime = data[i].timestamp
const iType = data[i].type
const iColor = getColor(data[i])
if (iType === 1) {
chart.annotation().dataMarker({
position: [iTime, 0],
line: {
length: 0
},
point: {
style: {
fill: iColor,
stroke: iColor
}
}
})
}
}
chart.tooltip({
// Crosshairs就是tooltip的竖线
showCrosshairs: true, // 展示 Tooltip 辅助线
// Markers就是tooltip时激活的线上的点
showMarkers: false,
// marker: {
// fill: 'red'
// },
shared: false,
crosshairs: {
type: 'x',
follow: true
},
// 自定义tooltip内容
customContent: (name, items) => {
const container = document.createElement('div')
container.className = 'g2-tooltip'
// name就是时间
const time = `<div class="g2-tooltip-title" style="margin-top: 12px;margin-bottom: 12px;">${name}</div>`
let listItem = ''
items.forEach(item => {
let color = getColor(item.data)
let statusText = getStatusText(item.data)
listItem += `<li class="g2-tooltip-list-item" data-index={index} style="margin-bottom:4px;display:flex;align-items: center;">
<span>`
listItem += `<span style="margin-right: 16px;"><span>
<span style="background-color:${color};width:8px;height:8px;border-radius:50%;display:inline-block;margin-right:8px;"></span>
<span style="margin-right:8px;">${statusText}</span>
</span></span>
</span>
</li>`
})
container.innerHTML = time + listItem
return container
}
})
chart.render();