Merge pull request #7360 from ulleo/dev

fix: antv组合图同比环比占比计算无效
This commit is contained in:
ulleo 2023-12-26 16:31:24 +08:00 committed by GitHub
commit 2f39a9b5f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 220 additions and 8 deletions

View File

@ -0,0 +1,14 @@
package io.dataease.plugins.view.official.impl;
/**
* @Author gin
* @Date 2021/12/9 3:58 下午
*/
public class ChartConstants {
public static final String YEAR_MOM = "year_mom";
public static final String MONTH_MOM = "month_mom";
public static final String YEAR_YOY = "year_yoy";
public static final String DAY_MOM = "day_mom";
public static final String MONTH_YOY = "month_yoy";
public static final String[] M_Y = {YEAR_MOM, MONTH_MOM, YEAR_YOY, DAY_MOM, MONTH_YOY};
}

View File

@ -1,20 +1,20 @@
package io.dataease.plugins.view.official.impl;
import com.google.gson.Gson;
import io.dataease.plugins.common.dto.StaticResource;
import io.dataease.plugins.common.dto.chart.ChartFieldCompareDTO;
import io.dataease.plugins.view.entity.*;
import io.dataease.plugins.view.official.handler.ChartMixViewStatHandler;
import io.dataease.plugins.view.service.ViewPluginService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
public class ChartMixService extends ViewPluginService {
@ -114,7 +114,6 @@ public class ChartMixService extends ViewPluginService {
return null;
}
String sql = new ChartMixViewStatHandler().build(param, this);
System.out.println(sql);
return sql;
}
@ -125,7 +124,6 @@ public class ChartMixService extends ViewPluginService {
List<PluginViewField> xAxis = new ArrayList<>();
List<PluginViewField> yAxis = new ArrayList<>();
System.out.println("pluginViewParam: " + new Gson().toJson(pluginViewParam));
pluginViewParam.getPluginViewFields().forEach(pluginViewField -> {
if (StringUtils.equals(pluginViewField.getTypeField(), "xAxis")) {
@ -141,12 +139,117 @@ public class ChartMixService extends ViewPluginService {
map.put("data", series);
System.out.println(new Gson().toJson(map));
return map;
}
private List<PluginSeries> format(String type, List<String[]> data, List<PluginViewField> xAxis, List<PluginViewField> yAxis) {
// 同比/环比计算
// 调整data数据
for (int i = 0; i < yAxis.size(); i++) {
PluginViewField chartViewFieldDTO = yAxis.get(i);
ChartFieldCompareDTO compareCalc = chartViewFieldDTO.getCompareCalc();
if (ObjectUtils.isEmpty(compareCalc)) {
continue;
}
if (StringUtils.isNotEmpty(compareCalc.getType())
&& !StringUtils.equalsIgnoreCase(compareCalc.getType(), "none")) {
String compareFieldId = compareCalc.getField();// 选中字段
// 计算指标对应的下标
int dataIndex = 0;// 数据字段下标
dataIndex = xAxis.size() + i;
if (Arrays.asList(ChartConstants.M_Y).contains(compareCalc.getType())) {
String resultData = compareCalc.getResultData();// 数据设置
// 获取选中字段以及下标
List<PluginViewField> checkedField = new ArrayList<>(xAxis);
int timeIndex = 0;// 时间字段下标
PluginViewField timeField = null;
for (int j = 0; j < checkedField.size(); j++) {
if (StringUtils.equalsIgnoreCase(checkedField.get(j).getId(), compareFieldId)) {
timeIndex = j;
timeField = checkedField.get(j);
}
}
// 无选中字段或者选中字段已经不在维度list中或者选中字段日期格式不符合对比类型的直接将对应数据置为null
if (ObjectUtils.isEmpty(timeField) || !checkCalcType(timeField.getDateStyle(), compareCalc.getType())) {
// set null
for (String[] item : data) {
item[dataIndex] = null;
}
} else {
// 计算 同比/环比
// 1处理当期数据2根据type计算上一期数据3根据resultData计算结果
Map<String, String> currentMap = new LinkedHashMap<>();
for (String[] item : data) {
String[] dimension = Arrays.copyOfRange(item, 0, checkedField.size());
currentMap.put(StringUtils.join(dimension, "-"), item[dataIndex]);
}
for (int index = 0; index < data.size(); index++) {
String[] item = data.get(index);
String cTime = item[timeIndex];
String cValue = item[dataIndex];
// 获取计算后的时间并且与所有维度拼接
String lastTime = calcLastTime(cTime, compareCalc.getType(), timeField.getDateStyle(), timeField.getDatePattern());
String[] dimension = Arrays.copyOfRange(item, 0, checkedField.size());
dimension[timeIndex] = lastTime;
String lastValue = currentMap.get(StringUtils.join(dimension, "-"));
if (StringUtils.isEmpty(cValue) || StringUtils.isEmpty(lastValue)) {
item[dataIndex] = null;
} else {
if (StringUtils.equalsIgnoreCase(resultData, "sub")) {
item[dataIndex] = new BigDecimal(cValue).subtract(new BigDecimal(lastValue)).toString();
} else if (StringUtils.equalsIgnoreCase(resultData, "percent")) {
if (new BigDecimal(lastValue).compareTo(BigDecimal.ZERO) == 0) {
item[dataIndex] = null;
} else {
item[dataIndex] = new BigDecimal(cValue)
.divide(new BigDecimal(lastValue), 8, RoundingMode.HALF_UP)
.subtract(new BigDecimal(1))
.setScale(8, RoundingMode.HALF_UP)
.toString();
}
}
}
}
}
} else if (StringUtils.equalsIgnoreCase(compareCalc.getType(), "percent")) {
// 求和
BigDecimal sum = new BigDecimal(0);
for (int index = 0; index < data.size(); index++) {
String[] item = data.get(index);
String cValue = item[dataIndex];
if (StringUtils.isEmpty(cValue)) {
continue;
}
sum = sum.add(new BigDecimal(cValue));
}
// 计算占比
for (int index = 0; index < data.size(); index++) {
String[] item = data.get(index);
String cValue = item[dataIndex];
if (StringUtils.isEmpty(cValue)) {
continue;
}
if (sum.equals(new BigDecimal(0))) {
continue;
}
item[dataIndex] = new BigDecimal(cValue)
.divide(sum, 8, RoundingMode.HALF_UP)
.toString();
}
}
}
}
// 同比/环比计算 over
List<PluginSeries> series = new ArrayList<>();
for (PluginViewField y : yAxis) {
PluginSeries series1 = new PluginSeries();
@ -188,4 +291,96 @@ public class ChartMixService extends ViewPluginService {
return series;
}
private boolean checkCalcType(String dateStyle, String calcType) {
switch (dateStyle) {
case "y":
return StringUtils.equalsIgnoreCase(calcType, "year_mom");
case "y_M":
return StringUtils.equalsIgnoreCase(calcType, "month_mom")
|| StringUtils.equalsIgnoreCase(calcType, "year_yoy");
case "y_M_d":
return StringUtils.equalsIgnoreCase(calcType, "day_mom")
|| StringUtils.equalsIgnoreCase(calcType, "month_yoy")
|| StringUtils.equalsIgnoreCase(calcType, "year_yoy");
}
return false;
}
private String calcLastTime(String cTime, String type, String dateStyle, String datePattern) {
try {
String lastTime = null;
Calendar calendar = Calendar.getInstance();
if (StringUtils.equalsIgnoreCase(type, ChartConstants.YEAR_MOM)) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy");
Date date = simpleDateFormat.parse(cTime);
calendar.setTime(date);
calendar.add(Calendar.YEAR, -1);
lastTime = simpleDateFormat.format(calendar.getTime());
} else if (StringUtils.equalsIgnoreCase(type, ChartConstants.MONTH_MOM)) {
SimpleDateFormat simpleDateFormat = null;
if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
simpleDateFormat = new SimpleDateFormat("yyyy/MM");
} else {
simpleDateFormat = new SimpleDateFormat("yyyy-MM");
}
Date date = simpleDateFormat.parse(cTime);
calendar.setTime(date);
calendar.add(Calendar.MONTH, -1);
lastTime = simpleDateFormat.format(calendar.getTime());
} else if (StringUtils.equalsIgnoreCase(type, ChartConstants.YEAR_YOY)) {
SimpleDateFormat simpleDateFormat = null;
if (StringUtils.equalsIgnoreCase(dateStyle, "y_M")) {
if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
simpleDateFormat = new SimpleDateFormat("yyyy/MM");
} else {
simpleDateFormat = new SimpleDateFormat("yyyy-MM");
}
} else if (StringUtils.equalsIgnoreCase(dateStyle, "y_M_d")) {
if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
} else {
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
}
}
Date date = simpleDateFormat.parse(cTime);
calendar.setTime(date);
calendar.add(Calendar.YEAR, -1);
lastTime = simpleDateFormat.format(calendar.getTime());
} else if (StringUtils.equalsIgnoreCase(type, ChartConstants.DAY_MOM)) {
SimpleDateFormat simpleDateFormat = null;
if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
} else {
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
}
Date date = simpleDateFormat.parse(cTime);
calendar.setTime(date);
calendar.add(Calendar.DAY_OF_MONTH, -1);
lastTime = simpleDateFormat.format(calendar.getTime());
} else if (StringUtils.equalsIgnoreCase(type, ChartConstants.MONTH_YOY)) {
SimpleDateFormat simpleDateFormat = null;
if (StringUtils.equalsIgnoreCase(dateStyle, "y_M")) {
if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
simpleDateFormat = new SimpleDateFormat("yyyy/MM");
} else {
simpleDateFormat = new SimpleDateFormat("yyyy-MM");
}
} else if (StringUtils.equalsIgnoreCase(dateStyle, "y_M_d")) {
if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
} else {
simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
}
}
Date date = simpleDateFormat.parse(cTime);
calendar.setTime(date);
calendar.add(Calendar.MONTH, -1);
lastTime = simpleDateFormat.format(calendar.getTime());
}
return lastTime;
} catch (Exception e) {
return cTime;
}
}
}

View File

@ -1,5 +1,6 @@
package io.dataease.plugins.view.entity;
import io.dataease.plugins.common.dto.chart.ChartFieldCompareDTO;
import lombok.Data;
import java.util.List;
@ -11,5 +12,7 @@ public class PluginViewField extends PluginChartViewFieldBase {
private List<PluginChartCustomFilterItem> filter;
private ChartFieldCompareDTO compareCalc;
private String busiType;
}