問(wèn)題描述:
開(kāi)發(fā)過(guò)程中隔箍,我們的前端使用Echarts.js開(kāi)發(fā)時(shí),碰到了一個(gè)困擾她的問(wèn)題脚乡。
上面的曲線的X軸為時(shí)間軸蜒滩, Y軸為數(shù)值, 問(wèn)題在當(dāng)這幾個(gè)線返回的X軸數(shù)據(jù)不一致時(shí), Echarts.js 在那個(gè)點(diǎn)會(huì)出現(xiàn)斷線帮掉。
寫(xiě)了個(gè)東西弦悉,將缺失的數(shù)據(jù)補(bǔ)全,
即X軸數(shù)據(jù)補(bǔ)全蟆炊,然后Y軸使用臨近的兩個(gè)點(diǎn)的均值補(bǔ)全稽莉;
當(dāng)前后沒(méi)有點(diǎn)時(shí),使用最近的點(diǎn)的數(shù)值進(jìn)行補(bǔ)全涩搓。
package com.loyotech.bigscreenbackend;
import com.loyotech.bigscreenbackend.dto.IceThicknessCurvesDTO;
import com.loyotech.bigscreenbackend.model.IceThicknessCurve;
import com.loyotech.bigscreenbackend.util.ObjectUtil;
import lombok.extern.java.Log;
import org.junit.Test;
import java.util.*;
import java.util.logging.Level;
import java.util.stream.Collectors;
/*
* @program big-screen-backend
* @description
* @author Rudolph Browne
* @create 19-1-15
*/
@Log
public class curveOfIceThicknessTest {
@Test
public void test01() {
List<IceThicknessCurvesDTO> result = prepareTestData();
log.log(Level.INFO, result.toString());
initialFakePoint(result);
log.log(Level.INFO, result.toString());
evaluateFakePoint(result);
log.log(Level.INFO, result.toString());
}
@Test
public void test02() {
IceThicknessCurve a = new IceThicknessCurve() {{
setRecPhase("C相");
setRecIceHeight("1");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 04:10:26");
}};
IceThicknessCurve b = new IceThicknessCurve();
ObjectUtil.copyProperties(IceThicknessCurve.class, a, IceThicknessCurve.class, b);
log.log(Level.INFO, b.toString());
}
@Test
public void test03() {
List list = Arrays.asList(1,2,3,2,1,3);
list = (List) list.stream().distinct().collect(Collectors.toList());
log.log(Level.INFO, list.toString());
}
}
private List<IceThicknessCurvesDTO> prepareTestData() {
return new LinkedList<IceThicknessCurvesDTO>() {{
add(new IceThicknessCurvesDTO() {{
setPhrase("A相");
setList(new LinkedList<IceThicknessCurve>(){{
add(new IceThicknessCurve() {{
setRecPhase("A相");
setRecIceHeight("1");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 21:10:26");
}});
add(new IceThicknessCurve() {{
setRecPhase("A相");
setRecIceHeight("5");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 15:10:26");
}});
add(new IceThicknessCurve() {{
setRecPhase("A相");
setRecIceHeight("1");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 05:10:26");
}});
}});
}});
add(new IceThicknessCurvesDTO() {{
setPhrase("B相");
setList(new LinkedList<IceThicknessCurve>(){{
add(new IceThicknessCurve() {{
setRecPhase("B相");
setRecIceHeight("1");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 13:10:26");
}});
add(new IceThicknessCurve() {{
setRecPhase("B相");
setRecIceHeight("5");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 19:10:26");
}});
add(new IceThicknessCurve() {{
setRecPhase("B相");
setRecIceHeight("1");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 01:10:26");
}});
}});
}});
add(new IceThicknessCurvesDTO() {{
setPhrase("B相");
setList(new LinkedList<IceThicknessCurve>(){{
add(new IceThicknessCurve() {{
setRecPhase("C相");
setRecIceHeight("1");
setRecBsId("CC2529");
setCreateDate("2019-01-13 02:34:27");
setRecUpdateTime("2019-01-13 13:10:26");
}});
add(new IceThicknessCurve() {{
setRecPhase("C相");
setRecIceHeight("5");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 03:10:26");
}});
add(new IceThicknessCurve() {{
setRecPhase("C相");
setRecIceHeight("1");
setRecBsId("CC2529");
setCreateDate("2019-01-13 21:34:27");
setRecUpdateTime("2019-01-13 04:10:26");
}});
}});
}});
}};
}
private void initialFakePoint(List<IceThicknessCurvesDTO> result) {
List<IceThicknessCurve> iceThicknessCurves = new LinkedList<>();
result.stream().forEach(
iceThicknessCurvesDTO -> {
iceThicknessCurves.addAll(iceThicknessCurvesDTO.getList());
}
);
iceThicknessCurves.stream().forEach(
iceThicknessCurve -> {
for (IceThicknessCurvesDTO iceThicknessCurvesDTO : result) {
if (!iceThicknessCurvesDTO.getPhrase().equalsIgnoreCase(iceThicknessCurve.getRecPhase())) {
iceThicknessCurvesDTO.getList().add(new IceThicknessCurve() {{ //為每條曲線設(shè)置空點(diǎn), 適配X時(shí)間軸
setRecUpdateTime(iceThicknessCurve.getRecUpdateTime());
}});
}
}
}
);
}
private void evaluateFakePoint(List<IceThicknessCurvesDTO> result) {
// 每一條曲線需要為虛點(diǎn)附上數(shù)值
for (IceThicknessCurvesDTO iceThicknessCurvesDTO : result) {
List<IceThicknessCurve> list = iceThicknessCurvesDTO.getList();
list.sort((o1, o2) -> (o1.getRecUpdateTime().compareTo(o2.getRecUpdateTime())));
Iterator iterator = list.listIterator();
IceThicknessCurve prevRealPoint = null;
IceThicknessCurve nextRealPoint = null;
IceThicknessCurve currentPoint;
// 循環(huán)執(zhí)行每個(gè)點(diǎn), 作為當(dāng)前點(diǎn)
while (iterator.hasNext()) {
// 拿到當(dāng)前點(diǎn)
currentPoint = (IceThicknessCurve) iterator.next();
// 如果當(dāng)前點(diǎn)為實(shí)點(diǎn)
if (isRealPoint(currentPoint)){
prevRealPoint = currentPoint;
continue;
} else { // 如果當(dāng)前點(diǎn)為虛點(diǎn)
// 如果當(dāng)前點(diǎn)既是虛點(diǎn), 又是第一個(gè)點(diǎn)
((ListIterator) iterator).previous();
boolean isFirstPoint = !((ListIterator) iterator).hasPrevious();
if (isFirstPoint) {
nextRealPoint = findNextRealPoint(iterator);
// 需要實(shí)現(xiàn)不想克隆的部分, 要不然會(huì)出現(xiàn)覆蓋時(shí)間點(diǎn)的情況
// ObjectUtil.copyProperties(IceThicknessCurve.class, nextRealPoint,
// IceThicknessCurve.class, currentPoint);
currentPoint.setRecIceHeight(nextRealPoint.getRecIceHeight());
currentPoint.setCreateDate(nextRealPoint.getCreateDate());
currentPoint.setRecBsId(nextRealPoint.getRecBsId());
currentPoint.setRecPhase(nextRealPoint.getRecPhase());
prevRealPoint = currentPoint;
backToCurrentPoint(iterator, currentPoint, currentPoint.getClass());
continue;
}
nextRealPoint = findNextRealPoint(iterator);
if (!isRealPoint(nextRealPoint)) {
// 如果最后不存在實(shí)點(diǎn)
// ObjectUtil.copyProperties(IceThicknessCurve.class, prevRealPoint,
// IceThicknessCurve.class, currentPoint);
currentPoint.setRecIceHeight(prevRealPoint.getRecIceHeight());
currentPoint.setCreateDate(prevRealPoint.getCreateDate());
currentPoint.setRecBsId(prevRealPoint.getRecBsId());
currentPoint.setRecPhase(prevRealPoint.getRecPhase());
} else {
// 當(dāng)找到左右兩個(gè)實(shí)點(diǎn), 將當(dāng)前虛點(diǎn)轉(zhuǎn)為實(shí)點(diǎn)
currentPoint.setRecIceHeight(String.valueOf((Double.valueOf(prevRealPoint.getRecIceHeight())
+ Double.valueOf(nextRealPoint.getRecIceHeight()))/2)) ;
currentPoint.setCreateDate(prevRealPoint.getCreateDate());
currentPoint.setRecBsId(prevRealPoint.getRecBsId());
currentPoint.setRecPhase(prevRealPoint.getRecPhase());
}
prevRealPoint = currentPoint;
backToCurrentPoint(iterator, currentPoint, currentPoint.getClass());
}
}
}
}
/**
* 指針重新回到當(dāng)前點(diǎn)
* @param iterator
* @param currentPoint
* @param currentPointType
*/
private void backToCurrentPoint(Iterator iterator, Object currentPoint, Class currentPointType) {
while (((ListIterator) iterator).hasPrevious()) {
if (((ListIterator) iterator).previous().equals(currentPointType.cast(currentPoint)))
break;
}
}
/**
* 尋找下一個(gè)實(shí)點(diǎn)
* @param iterator
* @param <T>
* @return
*/
private <T extends IceThicknessCurve> IceThicknessCurve findNextRealPoint(Iterator iterator) {
T nextRealPoint = null;
while (iterator.hasNext()) {
nextRealPoint = (T) iterator.next();
if ((nextRealPoint).getRecIceHeight() == null || "".equals(nextRealPoint.getRecIceHeight())) {
continue;
} else {
break;
}
}
return nextRealPoint;
}
/**
* 判斷傳入點(diǎn)是實(shí)點(diǎn)還是虛點(diǎn)
* @param point
* @param <T>
* @return
*/
private <T extends IceThicknessCurve> boolean isRealPoint(T point) {
return point.getRecIceHeight() != null && !"".equals(point.getRecIceHeight());
}