**
一:UI效果图
**
**
二:后台返回的数据格式
**
[
{measureTime:'2021-5-1',value:36,level:1},
{measureTime:'2021-5-2',value:37.9,level:2},
{measureTime:'2021-5-3',value:39,level:3},
...
]
**
三:代码实现
**
const weekDict2 = ["周一", "周二", "周三", "周四", "周五", "周六", "周日",]
const itemStyleList = [
{ color: '#50D3A1' },
{ color: '#FAAD14' },
{ color: '#FF5858' },
]
getLenRatio = () => {
const DESIGN_WIDTH = 750; // 设计稿宽度
return document.documentElement.clientWidth / DESIGN_WIDTH;
}
getFristDay = (date) => {
const frist = moment(date).startOf('month');
switch (frist.day()) {
case 6:
return frist.add(2, 'days');
case 0:
return frist.add(1, 'days');
default:
return frist;
}
}
initChart = (tempList = [], reportType) => {
tempList = tempList || [];
const { id, chartType } = chartIdList[reportType - 1];
const dom = document.getElementById(id);
if (!dom) return;
this[chartType] = echarts.init(dom);
const ratio = this.getLenRatio(); //获取比例
const xAxisData = []; //x轴数据
const seriesData1 = []; //实线折线图数据
const trueSeriesData1 = []; //实线折线图series数据
const trueTempData = []; //剔除不存在的体温数据
const tempNullData = []; //temp为null的数据
const fristDay = tempList && tempList.length && this.getFristDay(tempList[0].measureTime);
tempList.forEach((items, index) => {
const { measureTime, value, level } = items;
// level 1:正常 2:低热,3高热
xAxisData.push(measureTime);
seriesData1.push(value);
trueSeriesData1.push({ value, symbol: 'circle', itemStyle: level ? itemStyleList[level - 1] : {} })
if (level) trueTempData.push(value);
if (typeof level === 'object') tempNullData.push(index);
});
//有体温≥37.3°显示高热线
const maxTemp = Math.max.apply(null, trueTempData);
const minTemp = Math.min.apply(null, trueTempData);
const flag = maxTemp && maxTemp >= 37.3;
const markLineData = [
{ yAxis: 37.3, lineStyle: { color: '#FAAD14', type: 'dashed' } },
];
let yAxisMax = 38;
let yAxisMin = 34;
if (minTemp && minTemp < 34) {
yAxisMin = Math.floor(minTemp);
}
if (flag) {
markLineData.push({
yAxis: 38.5,
lineStyle: {
color: '#FF6B53',
type: 'dashed'
}
});
if (maxTemp > 39) {
yAxisMax = Math.ceil(maxTemp);
} else {
yAxisMax = 39;
}
}
console.log(markLineData);
//1.如果一个点为空,则其左右两个点得在第二数组,且此点是左右两值的平均点
//2.如果连续点为空,则取到其后不为null的那个点,
// 用此点减去上一个点的值的绝对值除以连续空白数量+1,
// 安插到null值处
let seriesData2 = []; //虚线折线图数据
const tempNullLength = tempNullData.length;
console.log(tempNullLength, seriesData1.length);
// 如果有null数据且不全为null数据则进入此判断
if (!!tempNullLength && tempNullLength !== seriesData1.length) {
const dataForSeries2 = []; //得出seriesData2的数组
seriesData1.forEach((items, index) => {
// 如果value为null 则isReal为false,表示为假数据,
// 如果为null情况下前后的temp有null,则isContinuous为true 表示连续
// 如果isReal为true,同时前后没有isReal为false的数据 isNull为true
const obj = {};
obj.index = index;
obj.value = items;
const preTempType = typeof seriesData1[index - 1] === 'object';
const nextTempType = typeof seriesData1[index + 1] === 'object';
if (typeof items === 'object') {
obj.isReal = false;
obj.isNull = false;
if (preTempType || nextTempType) {
obj.isContinuous = true;
} else {
obj.isContinuous = false;
}
} else {
obj.isReal = true;
if (preTempType || nextTempType) {
obj.isNull = false;
} else {
obj.isNull = true;
}
obj.isContinuous = false;
}
dataForSeries2.push(obj);
})
//得到dataForSeries2循环获取seriesData2
for (let i = 0; i < dataForSeries2.length;) {
const { isReal, isNull, isContinuous, value } = dataForSeries2[i];
if (isNull) { //如果是null值,就说明该数据前后都是真实数据,继续下一次循环
seriesData2[i] = null;
i++;
continue;
}
if (isReal) {//如果不是null值,且是真实数据,继续下一次循环
seriesData2[i] = value;
i++;
continue;
}
if (isContinuous) {//如果不是null值也不是真实数据,就判断是否连续,
//计算连续段数
let continuousNo = 1;
for (let continuousIndex = i + 1; continuousIndex < dataForSeries2.length; continuousIndex++) {
if (dataForSeries2[continuousIndex].isContinuous) {
continuousNo += 1;
} else {
break;
}
}
if (continuousNo + i === dataForSeries2.length) { // 如果连续到末尾,则所有数据都与之前数据相同
for (let continuousNo2 = i; continuousNo2 < dataForSeries2.length; continuousNo2++) {
seriesData2[continuousNo2] = dataForSeries2[i - 1].value
}
i += continuousNo;
} else {
// 如果连续就看连续段数,将连续结束后的真实数据-连续开始时的数据/(连续段数+1)设置好所有数据后i+上连续段数
let preTemp = dataForSeries2[i - 1] && dataForSeries2[i - 1].value;
const nextTemp = dataForSeries2[i + continuousNo] && dataForSeries2[i + continuousNo].value;
let diffValue = 0;
if (preTemp) {
diffValue = (nextTemp - preTemp) / (continuousNo + 1);
} else {
preTemp = nextTemp;
}
preTemp = preTemp - 0; //转化为数字
for (let continuousNo2 = i; continuousNo2 <= i + continuousNo; continuousNo2++) {
seriesData2[continuousNo2] = preTemp + diffValue;
preTemp += diffValue;
}
i += continuousNo;
}
} else {
//如果不连续,看前后是否都有值,有值就取平均值,没有就取有值的 主要是防止开头和结尾
const preTemp = dataForSeries2[i - 1] && dataForSeries2[i - 1].value;
const nextTemp = dataForSeries2[i + 1] && dataForSeries2[i + 1].value;
console.log(preTemp, nextTemp);
if (preTemp && nextTemp) {
seriesData2[i] = (preTemp - 0 + (nextTemp - 0)) / 2;
} else {
seriesData2[i] = preTemp || nextTemp;
}
i++;
}
}
}
const options = {
grid: {
left: 10 * ratio,
right: 24 * ratio,
top: 60,
bottom: 40,
containLabel: true,
},
xAxis: {
type: 'category',
data: reportType === 1 ? weekDict2 : xAxisData,
axisLine: {
lineStyle: {
color: '#968CAC',
opacity: .2
}
},
axisTick: {
show: false,
},
axisLabel: {
show: true,
margin: 24 * ratio,
align: 'center',
interval: 0,
color: '#666',
formatter: (value, index) => {
if (reportType === 1) {
return value;
}
//第一个日期显示为本月第一个工作日 后面为每周周一
let date = moment(value);
let weekDay = date.day();
if (date.isSame(fristDay)) return date.format('MM.DD');
if (weekDay === 1) return date.format('MM.DD');
}
},
splitLine: {
show: false
},
},
yAxis: {
type: 'value',
name: '(℃)',
nameGap: 16,
max: yAxisMax,
min: yAxisMin,
minInterval: 1,
nameTextStyle: {
color: '#666',
align: 'right',
padding: [0, 24 * ratio, 0, 0]
},
axisLine: {
show: true,
lineStyle: {
color: '#968CAC',
opacity: .2
}
},
axisTick: {
show: false
},
axisLabel: {
color: '#666',
verticalAlign: 'middle',
formatter: (value, index) => {
return `${value}.0`;
},
margin: 28 * ratio,
padding: [3, 0, 0, 0],
},
splitLine: {
lineStyle: {
color: '#968CAC',
opacity: .2
}
},
},
series: [
{
name: '体温',
symbolSize: 12 * ratio,
data: trueSeriesData1,
type: 'line',
lineStyle: {
color: 'rgba(0,0,0,.2)',
width: 2
},
markLine: {
symbol: 'none',
label: { show: false },
data: markLineData
}
},
{
name: '体温',
data: seriesData2,
type: 'line',
showSymbol: false,
lineStyle: {
color: 'rgba(0,0,0,.2)',
width: 1,
type: 'dashed'
},
}
]
};
this[chartType].setOption(options);
}
**
四:结尾
**
1.欢迎转载,请备明转载及链接
2.欢迎给出意见和建议,有问题可以在评论区指出