feat(echarts): 添加波形图绘制功能支持
- 新增drawWavePic方法用于绘制波形图 - 实现null数据段压缩算法,确保图表性能优化 - 添加markLine和markArea功能显示null段边界标记 - 集成到WavePicComponent组件中支持瞬时和RMS波形图生成 - 修复RestTemplate对Hutool JSON对象的支持问题 - 优化WaveUtil工具类处理空值数据逻辑
This commit is contained in:
@@ -1,10 +1,9 @@
|
||||
package com.njcn.event.file.component;
|
||||
|
||||
import cn.hutool.core.img.ImgUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.utils.FileUtil;
|
||||
import com.njcn.echarts.json.LineGenerator;
|
||||
import com.njcn.echarts.pojo.constant.PicCommonData;
|
||||
import com.njcn.echarts.util.DrawPicUtil;
|
||||
import com.njcn.event.file.pojo.bo.WaveDataDetail;
|
||||
@@ -12,21 +11,17 @@ import com.njcn.event.file.pojo.dto.WaveDataDTO;
|
||||
import com.njcn.event.file.pojo.enums.WaveFileResponseEnum;
|
||||
import com.njcn.oss.constant.OssPath;
|
||||
import com.njcn.oss.utils.FileStorageUtil;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import sun.awt.image.BufferedImageGraphicsConfig;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
@@ -49,36 +44,39 @@ public class WavePicComponent {
|
||||
* @date 2023/9/21 15:32
|
||||
* @return String 文件地址
|
||||
*/
|
||||
public String generateInstantImageZl(List<WaveDataDetail> waveDataDetails) {
|
||||
public String generateInstantImageZl(Integer nPush, List<WaveDataDetail> waveDataDetails, Double lastTime) {
|
||||
String firstPic = null, secondPic = null, thirdPic = null, forthPic = null;
|
||||
WaveDataDetail waveDataDetail0 = waveDataDetails.get(0);
|
||||
// 从instantData提取null边界x值,作为共享参考(与Shun图保持一致)
|
||||
List<Float> sharedNullBoundaries = LineGenerator.extractNullBoundaryXValues(waveDataDetail0.getInstantData().getAValue());
|
||||
for (WaveDataDetail waveDataDetail : waveDataDetails) {
|
||||
if (waveDataDetail.getChannelName().toUpperCase().startsWith("SU")) {
|
||||
firstPic = drawPicUtil.drawWavePic("电压-电网侧", waveDataDetail.getInstantData().getAValue(),
|
||||
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen()
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
|
||||
);
|
||||
} else if (waveDataDetail.getChannelName().toUpperCase().startsWith("SI")) {
|
||||
thirdPic = drawPicUtil.drawWavePic("电流-电网侧", waveDataDetail.getInstantData().getAValue(),
|
||||
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen()
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
|
||||
);
|
||||
} else if (waveDataDetail.getChannelName().toUpperCase().startsWith("LU")) {
|
||||
secondPic = drawPicUtil.drawWavePic("电压-负载侧", waveDataDetail.getInstantData().getAValue(),
|
||||
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen()
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
|
||||
);
|
||||
} else {
|
||||
forthPic = drawPicUtil.drawWavePic("电流-负载侧", waveDataDetail.getInstantData().getAValue(),
|
||||
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen()
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -91,36 +89,39 @@ public class WavePicComponent {
|
||||
* @date 2023/9/21 15:32
|
||||
* @return String 文件地址
|
||||
*/
|
||||
public String generateRmsImageZl(List<WaveDataDetail> waveDataDetails) {
|
||||
public String generateRmsImageZl(Integer nPush, List<WaveDataDetail> waveDataDetails, Double lastTime) {
|
||||
String firstPic = null, secondPic = null, thirdPic = null, forthPic = null;
|
||||
WaveDataDetail waveDataDetail0 = waveDataDetails.get(0);
|
||||
// 从instantData提取null边界x值,作为共享参考(与Shun图保持一致)
|
||||
List<Float> sharedNullBoundaries = LineGenerator.extractNullBoundaryXValues(waveDataDetail0.getInstantData().getAValue());
|
||||
for (WaveDataDetail waveDataDetail : waveDataDetails) {
|
||||
if (waveDataDetail.getChannelName().toUpperCase().startsWith("SU")) {
|
||||
firstPic = drawPicUtil.drawWavePic("电压-电网侧", waveDataDetail.getRmsData().getAValue(),
|
||||
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen()
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
|
||||
);
|
||||
} else if (waveDataDetail.getChannelName().toUpperCase().startsWith("SI")) {
|
||||
thirdPic = drawPicUtil.drawWavePic("电流-电网侧", waveDataDetail.getRmsData().getAValue(),
|
||||
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen()
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
|
||||
);
|
||||
} else if (waveDataDetail.getChannelName().toUpperCase().startsWith("LU")) {
|
||||
secondPic = drawPicUtil.drawWavePic("电压-负载侧", waveDataDetail.getRmsData().getAValue(),
|
||||
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen()
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
|
||||
);
|
||||
} else {
|
||||
forthPic = drawPicUtil.drawWavePic("电流-负载侧", waveDataDetail.getRmsData().getAValue(),
|
||||
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen()
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(),lastTime,sharedNullBoundaries,nPush
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -209,6 +210,47 @@ public class WavePicComponent {
|
||||
return picPath;
|
||||
}
|
||||
|
||||
/***
|
||||
* 绘制瞬时波形图 App端用来绘制图片,会去掉部分数据,只保留开始数据 结束数据
|
||||
* @author xy
|
||||
* @return String 文件地址
|
||||
*/
|
||||
public String generateImageShun(Integer nPush, List<WaveDataDetail> waveDataDetails, Double lastTime) {
|
||||
String picPath = null;
|
||||
WaveDataDetail waveDataDetail = waveDataDetails.get(0);
|
||||
// 从instantData提取null边界x值,作为共享参考
|
||||
List<Float> sharedNullBoundaries = LineGenerator.extractNullBoundaryXValues(waveDataDetail.getInstantData().getAValue());
|
||||
|
||||
String firstPic = drawPicUtil.drawWavePic(getTitle(waveDataDetail.getChannelName()), waveDataDetail.getInstantData().getAValue(),
|
||||
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(), lastTime, sharedNullBoundaries,nPush
|
||||
);
|
||||
String secondPic;
|
||||
if (waveDataDetails.size() == 1) {
|
||||
if (firstPic.contains(PicCommonData.PNG_PREFIX)) {
|
||||
firstPic = firstPic.replace(PicCommonData.PNG_PREFIX, "");
|
||||
}
|
||||
byte[] bytes = Base64.getDecoder().decode(firstPic);
|
||||
picPath = fileStorageUtil.uploadStream(new ByteArrayInputStream(bytes), OssPath.EVENT_WAVE_PIC, FileUtil.generateFileName("png"));
|
||||
} else if (waveDataDetails.size() == 2) {
|
||||
waveDataDetail = waveDataDetails.get(1);
|
||||
secondPic = drawPicUtil.drawWavePic(getTitle(waveDataDetail.getChannelName()), waveDataDetail.getInstantData().getAValue(),
|
||||
waveDataDetail.getInstantData().getBValue(), waveDataDetail.getInstantData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getInstantData().getMax(), waveDataDetail.getInstantData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(), lastTime, sharedNullBoundaries,nPush
|
||||
);
|
||||
picPath = composeImage(firstPic, secondPic);
|
||||
}
|
||||
return picPath;
|
||||
}
|
||||
|
||||
public String getTitle(String channelName) {
|
||||
return channelName.toUpperCase().startsWith("U1") ? "电压" : "电流";
|
||||
}
|
||||
|
||||
/***
|
||||
* 绘制RMS波形图
|
||||
* @author hongawen
|
||||
@@ -248,6 +290,44 @@ public class WavePicComponent {
|
||||
return picPath;
|
||||
}
|
||||
|
||||
/***
|
||||
* 绘制RMS波形图 App端用来绘制图片,会去掉部分数据,只保留开始数据 结束数据
|
||||
* @author xy
|
||||
* @return String 文件地址
|
||||
*/
|
||||
public String generateImageRms(Integer nPush, List<WaveDataDetail> waveDataDetails, Double lastTime) {
|
||||
String picPath = null;
|
||||
WaveDataDetail waveDataDetail = waveDataDetails.get(0);
|
||||
|
||||
// 从instantData提取null边界x值,作为共享参考(与Shun图保持一致)
|
||||
List<Float> sharedNullBoundaries = LineGenerator.extractNullBoundaryXValues(waveDataDetail.getInstantData().getAValue());
|
||||
|
||||
String firstPic = drawPicUtil.drawWavePic(getTitle(waveDataDetail.getChannelName()), waveDataDetail.getRmsData().getAValue(),
|
||||
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(), lastTime, sharedNullBoundaries,nPush
|
||||
);
|
||||
String secondPic;
|
||||
if (waveDataDetails.size() == 1) {
|
||||
if (firstPic.contains(PicCommonData.PNG_PREFIX)) {
|
||||
firstPic = firstPic.replace(PicCommonData.PNG_PREFIX, "");
|
||||
}
|
||||
byte[] bytes = Base64.getDecoder().decode(firstPic);
|
||||
picPath = fileStorageUtil.uploadStream(new ByteArrayInputStream(bytes), OssPath.EVENT_WAVE_PIC, FileUtil.generateFileName("png"));
|
||||
} else if (waveDataDetails.size() == 2) {
|
||||
waveDataDetail = waveDataDetails.get(1);
|
||||
secondPic = drawPicUtil.drawWavePic(getTitle(waveDataDetail.getChannelName()), waveDataDetail.getRmsData().getAValue(),
|
||||
waveDataDetail.getRmsData().getBValue(), waveDataDetail.getRmsData().getCValue(),
|
||||
waveDataDetail.getUnit(), waveDataDetail.getRmsData().getMax(), waveDataDetail.getRmsData().getMin(),
|
||||
waveDataDetail.getA(), waveDataDetail.getB(), waveDataDetail.getC(),
|
||||
waveDataDetail.getColors(), waveDataDetail.getIsOpen(), lastTime, sharedNullBoundaries,nPush
|
||||
);
|
||||
picPath = composeImage(firstPic, secondPic);
|
||||
}
|
||||
return picPath;
|
||||
}
|
||||
|
||||
/***
|
||||
* 合成图片
|
||||
* @author hongawen
|
||||
|
||||
@@ -7,6 +7,7 @@ import com.njcn.event.file.pojo.dto.WaveDataDTO;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
@@ -80,28 +81,49 @@ public class WaveUtil {
|
||||
//根据相别来确认标题的名称
|
||||
for (int m = 0; m < iPhase; m++) {
|
||||
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("A")) {
|
||||
float tmpShunFirstA = sunData.get(j).get(iPhase * i + m + 1) * xishu;
|
||||
shunFirstA = tmpShunFirstA;
|
||||
sAValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpShunFirstA);
|
||||
}});
|
||||
if (Objects.isNull(sunData.get(j).get(iPhase * i + m + 1))) {
|
||||
sAValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(null);
|
||||
}});
|
||||
} else {
|
||||
float tmpShunFirstA = sunData.get(j).get(iPhase * i + m + 1) * xishu;
|
||||
shunFirstA = tmpShunFirstA;
|
||||
sAValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpShunFirstA);
|
||||
}});
|
||||
}
|
||||
}
|
||||
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("B")) {
|
||||
float tmpShunFirstB = sunData.get(j).get(iPhase * i + m + 1) * xishu;
|
||||
shunFirstB = tmpShunFirstB;
|
||||
sBValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpShunFirstB);
|
||||
}});
|
||||
if (Objects.isNull(sunData.get(j).get(iPhase * i + m + 1))) {
|
||||
sBValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(null);
|
||||
}});
|
||||
} else {
|
||||
float tmpShunFirstB = sunData.get(j).get(iPhase * i + m + 1) * xishu;
|
||||
shunFirstB = tmpShunFirstB;
|
||||
sBValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpShunFirstB);
|
||||
}});
|
||||
}
|
||||
}
|
||||
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("C")) {
|
||||
float tmpShunFirstC = sunData.get(j).get(iPhase * i + m + 1) * xishu;
|
||||
shunFirstC = tmpShunFirstC;
|
||||
sCValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpShunFirstC);
|
||||
}});
|
||||
if (Objects.isNull(sunData.get(j).get(iPhase * i + m + 1))) {
|
||||
sCValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(null);
|
||||
}});
|
||||
} else {
|
||||
float tmpShunFirstC = sunData.get(j).get(iPhase * i + m + 1) * xishu;
|
||||
shunFirstC = tmpShunFirstC;
|
||||
sCValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpShunFirstC);
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
||||
sfMax = getMax(sfMax, shunFirstA, shunFirstB, shunFirstC);
|
||||
@@ -124,28 +146,50 @@ public class WaveUtil {
|
||||
//根据相别来确认标题的名称
|
||||
for (int m = 0; m < iPhase; m++) {
|
||||
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("A")) {
|
||||
float tmpRmsFirstA = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
|
||||
rmsFirstA = tmpRmsFirstA;
|
||||
rAValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpRmsFirstA);
|
||||
}});
|
||||
if (Objects.isNull(rmsData.get(k).get(iPhase * i + m + 1))) {
|
||||
rAValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(null);
|
||||
}});
|
||||
} else {
|
||||
float tmpRmsFirstA = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
|
||||
rmsFirstA = tmpRmsFirstA;
|
||||
rAValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpRmsFirstA);
|
||||
}});
|
||||
}
|
||||
}
|
||||
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("B")) {
|
||||
float tmpRmsFirstB = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
|
||||
rmsFirstB = tmpRmsFirstB;
|
||||
rBValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpRmsFirstB);
|
||||
}});
|
||||
if (Objects.isNull(rmsData.get(k).get(iPhase * i + m + 1))) {
|
||||
rBValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(null);
|
||||
}});
|
||||
} else {
|
||||
float tmpRmsFirstB = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
|
||||
rmsFirstB = tmpRmsFirstB;
|
||||
rBValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpRmsFirstB);
|
||||
}});
|
||||
}
|
||||
|
||||
}
|
||||
if (waveTitle.get(iPhase * i + m + 1).substring(1).contains("C")) {
|
||||
float tmpRmsFirstC = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
|
||||
rmsFirstC = tmpRmsFirstC;
|
||||
rCValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpRmsFirstC);
|
||||
}});
|
||||
if (Objects.isNull(rmsData.get(k).get(iPhase * i + m + 1))) {
|
||||
rCValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(null);
|
||||
}});
|
||||
} else {
|
||||
float tmpRmsFirstC = rmsData.get(k).get(iPhase * i + m + 1) * xishu;
|
||||
rmsFirstC = tmpRmsFirstC;
|
||||
rCValue.add(new ArrayList<Float>() {{
|
||||
add(x);
|
||||
add(tmpRmsFirstC);
|
||||
}});
|
||||
}
|
||||
}
|
||||
}
|
||||
rfMax = getMax(sfMax, rmsFirstA, rmsFirstB, rmsFirstC);
|
||||
|
||||
Reference in New Issue
Block a user