forked from github/dataease
refactor(图表): 图表获取数据逻辑插件化(WIP)
This commit is contained in:
parent
dddf8649db
commit
f987734aa2
@ -0,0 +1,14 @@
|
||||
package io.dataease.chart.charts;
|
||||
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public abstract class AbstractChartHandler {
|
||||
public abstract <T> T formatAxis(ChartViewDTO view);
|
||||
public abstract <T extends CustomFilterResult, K extends AxisFormatResult> T customFilter(ChartViewDTO view, List<ChartExtFilterDTO> filterList, K formatResult);
|
||||
public abstract <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider);
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package io.dataease.chart.charts;
|
||||
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@Component
|
||||
public class ChartHandlerManager {
|
||||
@Lazy
|
||||
@Resource
|
||||
private DefaultChartHandler defaultChartHandler;
|
||||
private static final ConcurrentHashMap<String, AbstractChartHandler> CHART_HANDLER_MAP = new ConcurrentHashMap<>();
|
||||
|
||||
public void registerChartHandler(String render, String type, AbstractChartHandler chartHandler) {
|
||||
CHART_HANDLER_MAP.put(render + "-" + type, chartHandler);
|
||||
}
|
||||
|
||||
public AbstractChartHandler getChartHandler(String render, String type) {
|
||||
var handler = CHART_HANDLER_MAP.get(render + "-" + type);
|
||||
if (handler == null) {
|
||||
return defaultChartHandler;
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
}
|
@ -0,0 +1,495 @@
|
||||
package io.dataease.chart.charts.impl;
|
||||
|
||||
import io.dataease.chart.charts.AbstractChartHandler;
|
||||
import io.dataease.chart.constant.ChartConstants;
|
||||
import io.dataease.chart.manage.ChartViewManege;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.dataset.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.dataset.manage.DatasetTableFieldManage;
|
||||
import io.dataease.dataset.utils.SqlUtils;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.datasource.request.DatasourceRequest;
|
||||
import io.dataease.engine.constant.SQLConstants;
|
||||
import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.Dimension2SQLObj;
|
||||
import io.dataease.engine.trans.Quota2SQLObj;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.chart.charts.ChartHandlerManager;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
import io.dataease.extensions.view.util.ChartDataUtil;
|
||||
import io.dataease.extensions.view.util.FieldUtil;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Component
|
||||
public class DefaultChartHandler extends AbstractChartHandler {
|
||||
@Resource
|
||||
protected ChartHandlerManager chartHandlerManager;
|
||||
@Resource
|
||||
protected DatasetTableFieldManage datasetTableFieldManage;
|
||||
@Resource
|
||||
protected ChartViewManege chartViewManege;
|
||||
@Getter
|
||||
private String render = "antv";
|
||||
@Getter
|
||||
private String type = "*";
|
||||
|
||||
@PostConstruct
|
||||
public void init(){
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), this.getType(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var axisMap = new HashMap<ChartAxis, List<ChartViewFieldDTO>>();
|
||||
var context = new HashMap<String, Object>();
|
||||
var result = new AxisFormatResult(axisMap, context);
|
||||
axisMap.put(ChartAxis.xAxis, new ArrayList<>(view.getXAxis()));
|
||||
axisMap.put(ChartAxis.yAxis, new ArrayList<>(view.getYAxis()));
|
||||
axisMap.put(ChartAxis.drill, new ArrayList<>(view.getDrillFields()));
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends CustomFilterResult, K extends AxisFormatResult> T customFilter(ChartViewDTO view, List<ChartExtFilterDTO> filterList, K formatResult) {
|
||||
return (T) new CustomFilterResult(filterList, formatResult.getContext());
|
||||
}
|
||||
|
||||
public Map<String, Object> buildResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
Map<String, Object> result = ChartDataBuild.transChartData(xAxis, yAxis, view, data, isDrill);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider) {
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDsList(dsMap);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var allFields = getAllChartFields(view);
|
||||
filterResult.getContext().put("allFields", allFields);
|
||||
Dimension2SQLObj.dimension2sqlObj(sqlMeta, xAxis, FieldUtil.transFields(allFields), crossDs, dsMap);
|
||||
Quota2SQLObj.quota2sqlObj(sqlMeta, yAxis, FieldUtil.transFields(allFields), crossDs, dsMap);
|
||||
String querySql = SQLProvider.createQuerySQL(sqlMeta, true, needOrder, view);
|
||||
querySql = SqlUtils.rebuildSQL(querySql, sqlMeta, crossDs, dsMap);
|
||||
datasourceRequest.setQuery(querySql);
|
||||
List<String[]> data = (List<String[]>) provider.fetchResultField(datasourceRequest).get("data");
|
||||
//自定义排序
|
||||
data = ChartDataUtil.resultCustomSort(xAxis, data);
|
||||
//快速计算
|
||||
quickCalc(xAxis, yAxis, data);
|
||||
//数据重组逻辑可重载
|
||||
var result = this.buildResult(view, formatResult, filterResult, data);
|
||||
T calcResult = (T) new ChartCalcDataResult();
|
||||
calcResult.setData(result);
|
||||
calcResult.setContext(filterResult.getContext());
|
||||
calcResult.setQuerySql(querySql);
|
||||
calcResult.setOriginData(data);
|
||||
return calcResult;
|
||||
}
|
||||
|
||||
protected List<ChartViewFieldDTO> getAllChartFields(ChartViewDTO view) {
|
||||
// get all fields
|
||||
Map<String, List<ChartViewFieldDTO>> stringListMap = chartViewManege.listByDQ(view.getTableId(), view.getId(), view);
|
||||
List<ChartViewFieldDTO> dimensionList = stringListMap.get("dimensionList");
|
||||
List<ChartViewFieldDTO> quotaList = stringListMap.get("quotaList");
|
||||
List<ChartViewFieldDTO> allFields = new ArrayList<>();
|
||||
allFields.addAll(dimensionList);
|
||||
allFields.addAll(quotaList);
|
||||
return allFields.stream().filter(ele -> ele.getId() != -1L).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
protected List<ChartSeniorAssistDTO> getDynamicAssistFields(ChartViewDTO view) throws Exception {
|
||||
List<ChartSeniorAssistDTO> list = new ArrayList<>();
|
||||
|
||||
Map<String, Object> senior = view.getSenior();
|
||||
if (ObjectUtils.isEmpty(senior)) {
|
||||
return list;
|
||||
}
|
||||
|
||||
ChartSeniorAssistCfgDTO assistLineCfg = JsonUtil.parseObject((String) JsonUtil.toJSONString(senior.get("assistLineCfg")), ChartSeniorAssistCfgDTO.class);
|
||||
if (null == assistLineCfg || !assistLineCfg.isEnable()) {
|
||||
return list;
|
||||
}
|
||||
List<ChartSeniorAssistDTO> assistLines = assistLineCfg.getAssistLine();
|
||||
|
||||
if (ObjectUtils.isEmpty(assistLines)) {
|
||||
return list;
|
||||
}
|
||||
|
||||
for (ChartSeniorAssistDTO dto : assistLines) {
|
||||
if (StringUtils.equalsIgnoreCase(dto.getField(), "0")) {
|
||||
continue;
|
||||
}
|
||||
Long fieldId = dto.getFieldId();
|
||||
String summary = dto.getSummary();
|
||||
if (ObjectUtils.isEmpty(fieldId) || StringUtils.isEmpty(summary)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
DatasetTableFieldDTO datasetTableFieldDTO = datasetTableFieldManage.selectById(fieldId);
|
||||
|
||||
if (ObjectUtils.isEmpty(datasetTableFieldDTO)) {
|
||||
continue;
|
||||
}
|
||||
list.add(dto);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
protected List<ChartViewFieldDTO> getAssistFields(List<ChartSeniorAssistDTO> list, List<ChartViewFieldDTO> yAxis) {
|
||||
List<ChartViewFieldDTO> res = new ArrayList<>();
|
||||
for (ChartSeniorAssistDTO dto : list) {
|
||||
DatasetTableFieldDTO curField = dto.getCurField();
|
||||
ChartViewFieldDTO yField = null;
|
||||
String alias = "";
|
||||
for (int i = 0; i < yAxis.size(); i++) {
|
||||
ChartViewFieldDTO field = yAxis.get(i);
|
||||
if (Objects.equals(field.getId(), curField.getId())) {
|
||||
yField = field;
|
||||
alias = String.format(SQLConstants.FIELD_ALIAS_Y_PREFIX, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ObjectUtils.isEmpty(yField)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ChartViewFieldDTO chartViewFieldDTO = new ChartViewFieldDTO();
|
||||
BeanUtils.copyBean(chartViewFieldDTO, curField);
|
||||
chartViewFieldDTO.setSummary(dto.getSummary());
|
||||
chartViewFieldDTO.setOriginName(alias);// yAxis的字段别名,就是查找的字段名
|
||||
res.add(chartViewFieldDTO);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
protected String assistSQL(String sql, List<ChartViewFieldDTO> assistFields) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int i = 0; i < assistFields.size(); i++) {
|
||||
ChartViewFieldDTO dto = assistFields.get(i);
|
||||
if (i == (assistFields.size() - 1)) {
|
||||
stringBuilder.append(dto.getSummary() + "(" + dto.getOriginName() + ")");
|
||||
} else {
|
||||
stringBuilder.append(dto.getSummary() + "(" + dto.getOriginName() + "),");
|
||||
}
|
||||
}
|
||||
return "SELECT " + stringBuilder + " FROM (" + sql + ") tmp";
|
||||
}
|
||||
|
||||
protected void quickCalc(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, List<String[]> data) {
|
||||
for (int i = 0; i < yAxis.size(); i++) {
|
||||
ChartViewFieldDTO chartViewFieldDTO = yAxis.get(i);
|
||||
ChartFieldCompareDTO compareCalc = chartViewFieldDTO.getCompareCalc();
|
||||
if (ObjectUtils.isEmpty(compareCalc)) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isNotEmpty(compareCalc.getType())
|
||||
&& !StringUtils.equalsIgnoreCase(compareCalc.getType(), "none")) {
|
||||
Long compareFieldId = compareCalc.getField();// 选中字段
|
||||
// 数据字段下标
|
||||
int dataIndex = xAxis.size() + i;
|
||||
if (Arrays.asList(ChartConstants.M_Y).contains(compareCalc.getType())) {
|
||||
String resultData = compareCalc.getResultData();// 数据设置
|
||||
// 获取选中字段以及下标
|
||||
List<ChartViewFieldDTO> checkedField = new ArrayList<>(xAxis);
|
||||
int timeIndex = 0;// 时间字段下标
|
||||
ChartViewFieldDTO timeField = null;
|
||||
for (int j = 0; j < checkedField.size(); j++) {
|
||||
if (Objects.equals(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).abs(), 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;
|
||||
}
|
||||
item[dataIndex] = new BigDecimal(cValue)
|
||||
.divide(sum, 8, RoundingMode.HALF_UP)
|
||||
.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
protected boolean checkYoyFilter(List<ChartExtFilterDTO> filter, List<ChartViewFieldDTO> yoyAxis){
|
||||
boolean flag = false;
|
||||
for (ChartExtFilterDTO filterDTO : filter) {
|
||||
for (ChartViewFieldDTO chartViewFieldDTO : yoyAxis) {
|
||||
ChartFieldCompareDTO compareCalc = chartViewFieldDTO.getCompareCalc();
|
||||
if (ObjectUtils.isEmpty(compareCalc)) {
|
||||
continue;
|
||||
}
|
||||
if (StringUtils.isNotEmpty(compareCalc.getType())
|
||||
&& !StringUtils.equalsIgnoreCase(compareCalc.getType(), "none")) {
|
||||
if (Arrays.asList(ChartConstants.M_Y).contains(compareCalc.getType())) {
|
||||
if (StringUtils.equalsIgnoreCase(compareCalc.getField() + "", filterDTO.getFieldId()) && filterDTO.getFilterType() == 0) {
|
||||
// -1 year
|
||||
try {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(new Date(Long.parseLong(filterDTO.getValue().getFirst())));
|
||||
calendar.add(Calendar.YEAR, -1);
|
||||
filterDTO.getValue().set(0, String.valueOf(calendar.getTime().getTime()));
|
||||
flag = true;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return flag;
|
||||
};
|
||||
|
||||
protected void groupStackDrill(List<ChartViewFieldDTO> xAxis,
|
||||
List<ChartExtFilterDTO> filterList,
|
||||
List<ChartViewFieldDTO> fieldsToFilter,
|
||||
List<ChartViewFieldDTO> drillFields,
|
||||
List<ChartDrillRequest> drillRequestList) {
|
||||
var fields = xAxis.stream().map(ChartViewFieldDTO::getId).collect(Collectors.toSet());
|
||||
ChartDrillRequest head = drillRequestList.get(0);
|
||||
Map<Long, String> dimValMap = new HashMap<>();
|
||||
head.getDimensionList().forEach(item -> dimValMap.put(item.getId(), item.getValue()));
|
||||
Map<Long, ChartViewFieldDTO> fieldMap = xAxis.stream().collect(Collectors.toMap(ChartViewFieldDTO::getId, o -> o, ((p, n) -> p)));
|
||||
for (int i = 0; i < drillRequestList.size(); i++) {
|
||||
ChartDrillRequest request = drillRequestList.get(i);
|
||||
ChartViewFieldDTO chartViewFieldDTO = drillFields.get(i);
|
||||
for (ChartDimensionDTO requestDimension : request.getDimensionList()) {
|
||||
// 将钻取值作为条件传递,将所有钻取字段作为xAxis并加上下一个钻取字段
|
||||
if (Objects.equals(requestDimension.getId(), chartViewFieldDTO.getId())) {
|
||||
fieldsToFilter.add(chartViewFieldDTO);
|
||||
dimValMap.put(requestDimension.getId(), requestDimension.getValue());
|
||||
if (!fields.contains(requestDimension.getId())) {
|
||||
fieldMap.put(chartViewFieldDTO.getId(), chartViewFieldDTO);
|
||||
chartViewFieldDTO.setSource(FieldSource.DRILL);
|
||||
xAxis.add(chartViewFieldDTO);
|
||||
fields.add(requestDimension.getId());
|
||||
}
|
||||
if (i == drillRequestList.size() - 1) {
|
||||
ChartViewFieldDTO nextDrillField = drillFields.get(i + 1);
|
||||
if (!fields.contains(nextDrillField.getId())) {
|
||||
// get drill list first element's sort,then assign to nextDrillField
|
||||
nextDrillField.setSort(getDrillSort(xAxis, drillFields.get(0)));
|
||||
nextDrillField.setSource(FieldSource.DRILL);
|
||||
xAxis.add(nextDrillField);
|
||||
fields.add(nextDrillField.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < fieldsToFilter.size(); i++) {
|
||||
ChartViewFieldDTO tmpField = fieldsToFilter.get(i);
|
||||
ChartExtFilterDTO tmpFilter = new ChartExtFilterDTO();
|
||||
DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(tmpField.getId());
|
||||
tmpFilter.setDatasetTableField(datasetTableField);
|
||||
tmpFilter.setDateStyle(fieldMap.get(tmpField.getId()).getDateStyle());
|
||||
tmpFilter.setDatePattern(fieldMap.get(tmpField.getId()).getDatePattern());
|
||||
tmpFilter.setFieldId(String.valueOf(tmpField.getId()));
|
||||
tmpFilter.setFilterType(1);
|
||||
if (datasetTableField.getDeType() == 1) {
|
||||
tmpFilter.setOperator("between");
|
||||
// 把value类似过滤组件处理,获得start time和end time
|
||||
Map<String, Long> stringLongMap = Utils.parseDateTimeValue(dimValMap.get(tmpField.getId()));
|
||||
tmpFilter.setValue(Arrays.asList(String.valueOf(stringLongMap.get("startTime")), String.valueOf(stringLongMap.get("endTime"))));
|
||||
} else {
|
||||
tmpFilter.setOperator("in");
|
||||
tmpFilter.setValue(Collections.singletonList(dimValMap.get(tmpField.getId())));
|
||||
}
|
||||
filterList.add(tmpFilter);
|
||||
}
|
||||
}
|
||||
|
||||
private String getDrillSort(List<ChartViewFieldDTO> xAxis, ChartViewFieldDTO field) {
|
||||
String res = "";
|
||||
for (ChartViewFieldDTO f : xAxis) {
|
||||
if (Objects.equals(f.getId(), field.getId())) {
|
||||
if (StringUtils.equalsIgnoreCase(f.getSort(), "asc") || StringUtils.equalsIgnoreCase(f.getSort(), "desc")) {
|
||||
res = f.getSort();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package io.dataease.chart.charts.impl;
|
||||
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import io.dataease.extensions.view.dto.ChartViewFieldDTO;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ExtQuotaChartHandler extends DefaultChartHandler {
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = result.getAxisMap().get(ChartAxis.yAxis);
|
||||
yAxis.addAll(view.getExtLabel());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.extLabel, view.getExtLabel());
|
||||
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
package io.dataease.chart.charts.impl;
|
||||
|
||||
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import io.dataease.extensions.view.dto.ChartViewFieldDTO;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class GroupChartHandler extends DefaultChartHandler {
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var xAxis = new ArrayList<ChartViewFieldDTO>(view.getXAxis());
|
||||
xAxis.addAll(view.getXAxisExt());
|
||||
result.getAxisMap().put(ChartAxis.xAxis, xAxis);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,121 @@
|
||||
package io.dataease.chart.charts.impl;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.dataease.dataset.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.dataset.utils.SqlUtils;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.datasource.request.DatasourceRequest;
|
||||
import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.ExtWhere2Str;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
import io.dataease.extensions.view.util.FieldUtil;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 带同环比计算的图表处理器
|
||||
*/
|
||||
public class YoyChartHandler extends DefaultChartHandler {
|
||||
@Override
|
||||
public <T extends CustomFilterResult, K extends AxisFormatResult> T customFilter(ChartViewDTO view, List<ChartExtFilterDTO> filterList, K formatResult) {
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
String originFilterJson = (String) JsonUtil.toJSONString(filterList);
|
||||
// 如果设置了同环比的指标字段设置了过滤器,那就需要把该过滤器的时间往前回调一年
|
||||
// 计算完同环比之后,再把计算结果和原有的过滤结果对比,去除不该出现的前一年的数据
|
||||
boolean yoyFiltered = checkYoyFilter(filterList, yAxis);
|
||||
if (yoyFiltered) {
|
||||
List<ChartExtFilterDTO> originFilter = JsonUtil.parseList(originFilterJson, new TypeReference<>() {
|
||||
});
|
||||
formatResult.getContext().put("originFilter", originFilter);
|
||||
formatResult.getContext().put("yoyFiltered", true);
|
||||
}
|
||||
return (T) new CustomFilterResult(filterList, formatResult.getContext());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
var yoyFiltered = filterResult.getContext().get("yoyFiltered") != null;
|
||||
// 带过滤同环比直接返回原始数据,再由视图重新组装
|
||||
if (yoyFiltered) {
|
||||
var result = new HashMap<String, Object>();
|
||||
result.put("data", data);
|
||||
return result;
|
||||
}
|
||||
return buildNormalResult(view, formatResult, filterResult, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建同环比类型的数据
|
||||
* @param view 视图对象
|
||||
* @param formatResult 处理后的轴
|
||||
* @param filterResult 处理后的过滤器
|
||||
* @param data 原始数据
|
||||
* @return 视图构建结果
|
||||
*/
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
return super.buildResult(view, formatResult, filterResult, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider) {
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
// 这里拿到的可能有一年前的数据
|
||||
var expandedResult = (T) super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider);
|
||||
// 检查同环比过滤,拿到实际数据
|
||||
var yoyFiltered = filterResult.getContext().get("yoyFiltered") != null;
|
||||
if (yoyFiltered) {
|
||||
var originFilter = (List<ChartExtFilterDTO>) filterResult.getContext().get("originFilter");
|
||||
var allFields = (List<ChartViewFieldDTO>) filterResult.getContext().get("allFields");
|
||||
ExtWhere2Str.extWhere2sqlOjb(sqlMeta, originFilter, FieldUtil.transFields(allFields), crossDs, dsMap);
|
||||
var originSql = SQLProvider.createQuerySQL(sqlMeta, true, needOrder, view);
|
||||
originSql = SqlUtils.rebuildSQL(originSql, sqlMeta, crossDs, dsMap);
|
||||
var request = new DatasourceRequest();
|
||||
request.setDsList(dsMap);
|
||||
request.setQuery(originSql);
|
||||
// 实际过滤后的数据
|
||||
var originData = (List<String[]>) provider.fetchResultField(request).get("data");
|
||||
List<String[]> resultData = new ArrayList<>();
|
||||
// 包含一年前的数据, 已计算同环比
|
||||
var yoyData = (List<String[]>) expandedResult.getData().get("data");
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
// 对比维度,只保留实际过滤后的数据
|
||||
for (String[] yoyDataLine : yoyData) {
|
||||
StringBuilder x1 = new StringBuilder();
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
x1.append(yoyDataLine[i]);
|
||||
}
|
||||
for (String[] originDataLine : originData) {
|
||||
StringBuilder x2 = new StringBuilder();
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
x2.append(originDataLine[i]);
|
||||
}
|
||||
if (StringUtils.equals(x1, x2)) {
|
||||
resultData.add(yoyDataLine);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
yoyData.clear();
|
||||
yoyData.addAll(resultData);
|
||||
var result = this.buildNormalResult(view, formatResult, filterResult, yoyData);
|
||||
expandedResult.setData(result);
|
||||
expandedResult.setOriginData(originData);
|
||||
expandedResult.setQuerySql(originSql);
|
||||
}
|
||||
return expandedResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package io.dataease.chart.charts.impl.bar;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.chart.constant.ChartConstants;
|
||||
import io.dataease.dataset.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.dataset.utils.SqlUtils;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.datasource.request.DatasourceRequest;
|
||||
import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.ExtWhere2Str;
|
||||
import io.dataease.engine.utils.SQLUtils;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
import io.dataease.extensions.view.util.FieldUtil;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Component
|
||||
public class BarHandler extends YoyChartHandler {
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "bar", this);
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "bar-horizontal", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = result.getAxisMap().get(ChartAxis.yAxis);
|
||||
yAxis.addAll(view.getExtLabel());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.extLabel, view.getExtLabel());
|
||||
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider) {
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
var result = (T) super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider);
|
||||
try {
|
||||
//如果有同环比过滤,应该用原始sql
|
||||
var originSql = result.getQuerySql();
|
||||
var dynamicAssistFields = getDynamicAssistFields(view);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var assistFields = getAssistFields(dynamicAssistFields, yAxis);
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields);
|
||||
req.setQuery(assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
result.setAssistData(assistData);
|
||||
result.setDynamicAssistFields(dynamicAssistFields);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
package io.dataease.chart.charts.impl.bar;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class BidirectionalBarHandler extends ProgressBarHandler {
|
||||
@Getter
|
||||
private String type = "bidirectional-bar";
|
||||
}
|
@ -0,0 +1,75 @@
|
||||
package io.dataease.chart.charts.impl.bar;
|
||||
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Component
|
||||
public class GroupBarHandler extends BarHandler {
|
||||
@Getter
|
||||
private String type = "bar-group";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var xAxis = result.getAxisMap().get(ChartAxis.xAxis);
|
||||
xAxis.addAll(view.getXAxisExt());
|
||||
result.getAxisMap().put(ChartAxis.xAxisExt, view.getXAxisExt());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), this.getType(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends CustomFilterResult, K extends AxisFormatResult> T customFilter(ChartViewDTO view, List<ChartExtFilterDTO> filterList, K formatResult) {
|
||||
var result = super.customFilter(view, filterList, formatResult);
|
||||
List<ChartDrillRequest> drillRequestList = view.getChartExtRequest().getDrill();
|
||||
var drillFields = formatResult.getAxisMap().get(ChartAxis.drill);
|
||||
// 分组维度下钻
|
||||
if (ObjectUtils.isNotEmpty(drillRequestList) && (drillFields.size() > drillRequestList.size())) {
|
||||
List<ChartExtFilterDTO> noDrillFilterList = filterList
|
||||
.stream()
|
||||
.filter(ele -> ele.getFilterType() != 1)
|
||||
.collect(Collectors.toList());
|
||||
var noDrillFieldAxis = formatResult.getAxisMap().get(ChartAxis.xAxis)
|
||||
.stream()
|
||||
.filter(ele -> ele.getSource() != FieldSource.DRILL)
|
||||
.collect(Collectors.toList());
|
||||
List<ChartExtFilterDTO> drillFilters = new ArrayList<>();
|
||||
ArrayList<ChartViewFieldDTO> fieldsToFilter = new ArrayList<>();
|
||||
var xAxisExt = formatResult.getAxisMap().get(ChartAxis.xAxisExt);
|
||||
if (ObjectUtils.isNotEmpty(xAxisExt) &&
|
||||
Objects.equals(drillFields.get(0).getId(), xAxisExt.get(0).getId())) {
|
||||
fieldsToFilter.addAll(view.getXAxis());
|
||||
}
|
||||
groupStackDrill(noDrillFieldAxis, noDrillFilterList, fieldsToFilter, drillFields, drillRequestList);
|
||||
formatResult.getAxisMap().put(ChartAxis.xAxis, noDrillFieldAxis);
|
||||
result.setFilterList(noDrillFilterList);
|
||||
}
|
||||
return (T) result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var xAxisExt = formatResult.getAxisMap().get(ChartAxis.xAxisExt);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var xAxisBase = xAxis.subList(0, xAxis.size() - xAxisExt.size());
|
||||
return ChartDataBuild.transBaseGroupDataAntV(xAxisBase, xAxis, xAxisExt, yAxis, view, data, isDrill);
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package io.dataease.chart.charts.impl.bar;
|
||||
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class ProgressBarHandler extends BarHandler {
|
||||
@Getter
|
||||
private String type = "progress-bar";
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), this.getType(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = new ArrayList<>(view.getYAxis());
|
||||
yAxis.addAll(view.getYAxisExt());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.yAxis, yAxis);
|
||||
result.getAxisMap().put(ChartAxis.yAxisExt, view.getYAxisExt());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
Map<String, Object> result = ChartDataBuild.transMixChartDataAntV(xAxis, xAxis, new ArrayList<>(), yAxis, view, data, isDrill);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,81 @@
|
||||
package io.dataease.chart.charts.impl.bar;
|
||||
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class RangeBarHandler extends YoyChartHandler {
|
||||
@Getter
|
||||
private String type = "bar-range";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = new ArrayList<ChartViewFieldDTO>();
|
||||
var xAxis = new ArrayList<ChartViewFieldDTO>(view.getXAxis());
|
||||
boolean skipBarRange = false;
|
||||
boolean barRangeDate = false;
|
||||
if (CollectionUtils.isNotEmpty(view.getYAxis()) && CollectionUtils.isNotEmpty(view.getYAxisExt())) {
|
||||
ChartViewFieldDTO axis1 = view.getYAxis().get(0);
|
||||
ChartViewFieldDTO axis2 = view.getYAxisExt().get(0);
|
||||
|
||||
if (StringUtils.equalsIgnoreCase(axis1.getGroupType(), "q") && StringUtils.equalsIgnoreCase(axis2.getGroupType(), "q")) {
|
||||
yAxis.add(axis1);
|
||||
yAxis.add(axis2);
|
||||
} else if (StringUtils.equalsIgnoreCase(axis1.getGroupType(), "d") && axis1.getDeType() == 1 && StringUtils.equalsIgnoreCase(axis2.getGroupType(), "d") && axis2.getDeType() == 1) {
|
||||
barRangeDate = true;
|
||||
if (BooleanUtils.isTrue(view.getAggregate())) {
|
||||
axis1.setSummary("min");
|
||||
axis2.setSummary("max");
|
||||
yAxis.add(axis1);
|
||||
yAxis.add(axis2);
|
||||
} else {
|
||||
xAxis.add(axis1);
|
||||
xAxis.add(axis2);
|
||||
}
|
||||
} else {
|
||||
skipBarRange = true;
|
||||
}
|
||||
} else {
|
||||
skipBarRange = true;
|
||||
}
|
||||
result.getContext().put("skipBarRange", skipBarRange);
|
||||
result.getContext().put("barRangeDate", barRangeDate);
|
||||
result.getAxisMap().put(ChartAxis.xAxis, xAxis);
|
||||
result.getAxisMap().put(ChartAxis.yAxis, yAxis);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var skipBarRange = (boolean) formatResult.getContext().get("skipBarRange");
|
||||
var barRangeDate = (boolean) formatResult.getContext().get("barRangeDate");
|
||||
Map<String, Object> result = ChartDataBuild.transBarRangeDataAntV(skipBarRange, barRangeDate, xAxis, xAxis, yAxis, view, data, isDrill);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider) {
|
||||
sqlMeta.setChartType(this.type);
|
||||
return super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider);
|
||||
}
|
||||
}
|
@ -0,0 +1,71 @@
|
||||
package io.dataease.chart.charts.impl.bar;
|
||||
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class StackBarHandler extends BarHandler {
|
||||
@Getter
|
||||
private String type = "bar-stack";
|
||||
@Override
|
||||
public void init() {
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "bar-stack", this);
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "bar-stack-horizontal", this);
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "percentage-bar-stack", this);
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "percentage-bar-stack-horizontal", this);
|
||||
}
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var xAxis = result.getAxisMap().get(ChartAxis.xAxis);
|
||||
xAxis.addAll(view.getExtStack());
|
||||
result.getAxisMap().put(ChartAxis.extStack, view.getExtStack());
|
||||
return result;
|
||||
}
|
||||
@Override
|
||||
public <T extends CustomFilterResult, K extends AxisFormatResult> T customFilter(ChartViewDTO view, List<ChartExtFilterDTO> filterList, K formatResult) {
|
||||
var result = super.customFilter(view, filterList, formatResult);
|
||||
List<ChartDrillRequest> drillRequestList = view.getChartExtRequest().getDrill();
|
||||
var drillFields = formatResult.getAxisMap().get(ChartAxis.drill);
|
||||
// 堆叠维度下钻
|
||||
if (ObjectUtils.isNotEmpty(drillRequestList) && (drillFields.size() > drillRequestList.size())) {
|
||||
List<ChartExtFilterDTO> noDrillFilterList = filterList
|
||||
.stream()
|
||||
.filter(ele -> ele.getFilterType() != 1)
|
||||
.collect(Collectors.toList());
|
||||
var noDrillFieldAxis = formatResult.getAxisMap().get(ChartAxis.xAxis)
|
||||
.stream()
|
||||
.filter(ele -> ele.getSource() != FieldSource.DRILL)
|
||||
.collect(Collectors.toList());
|
||||
List<ChartExtFilterDTO> drillFilters = new ArrayList<>();
|
||||
ArrayList<ChartViewFieldDTO> fieldsToFilter = new ArrayList<>();
|
||||
var extStack = formatResult.getAxisMap().get(ChartAxis.extStack);
|
||||
if (ObjectUtils.isNotEmpty(extStack) &&
|
||||
Objects.equals(drillFields.get(0).getId(), extStack.get(0).getId())) {
|
||||
fieldsToFilter.addAll(view.getXAxis());
|
||||
}
|
||||
groupStackDrill(noDrillFieldAxis, noDrillFilterList, fieldsToFilter, drillFields, drillRequestList);
|
||||
formatResult.getAxisMap().put(ChartAxis.xAxis, noDrillFieldAxis);
|
||||
result.setFilterList(noDrillFilterList);
|
||||
}
|
||||
return (T) result;
|
||||
}
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult.getFilterList().stream().anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var extStack = formatResult.getAxisMap().get(ChartAxis.extStack);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var xAxisBase = xAxis.subList(0, xAxis.size() - extStack.size());
|
||||
return ChartDataBuild.transStackChartDataAntV(xAxisBase, yAxis, view, data, extStack, isDrill);
|
||||
}
|
||||
}
|
@ -0,0 +1,90 @@
|
||||
package io.dataease.chart.charts.impl.bar;
|
||||
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static io.dataease.extensions.view.dto.ChartAxis.extStack;
|
||||
import static io.dataease.extensions.view.dto.ChartAxis.xAxisExt;
|
||||
|
||||
@Component
|
||||
public class StackGroupBarHandler extends BarHandler {
|
||||
@Getter
|
||||
private String type = "bar-group-stack";
|
||||
|
||||
@Override
|
||||
public void init() {
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), this.getType(), this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var xAxis = result.getAxisMap().get(ChartAxis.xAxis);
|
||||
xAxis.addAll(view.getXAxisExt());
|
||||
xAxis.addAll(view.getExtStack());
|
||||
result.getAxisMap().put(ChartAxis.xAxisExt, view.getExtStack());
|
||||
result.getAxisMap().put(ChartAxis.extStack, view.getExtStack());
|
||||
result.getAxisMap().put(ChartAxis.xAxisExt, view.getXAxisExt());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends CustomFilterResult, K extends AxisFormatResult> T customFilter(ChartViewDTO view, List<ChartExtFilterDTO> filterList, K formatResult) {
|
||||
var result = super.customFilter(view, filterList, formatResult);
|
||||
List<ChartDrillRequest> drillRequestList = view.getChartExtRequest().getDrill();
|
||||
var drillFields = formatResult.getAxisMap().get(ChartAxis.drill);
|
||||
// 分组维度下钻
|
||||
if (ObjectUtils.isNotEmpty(drillRequestList) && (drillFields.size() > drillRequestList.size())) {
|
||||
List<ChartExtFilterDTO> noDrillFilterList = filterList
|
||||
.stream()
|
||||
.filter(ele -> ele.getFilterType() != 1)
|
||||
.collect(Collectors.toList());
|
||||
var noDrillFieldAxis = formatResult.getAxisMap().get(ChartAxis.xAxis)
|
||||
.stream()
|
||||
.filter(ele -> ele.getSource() != FieldSource.DRILL)
|
||||
.collect(Collectors.toList());
|
||||
List<ChartExtFilterDTO> drillFilters = new ArrayList<>();
|
||||
ArrayList<ChartViewFieldDTO> fieldsToFilter = new ArrayList<>();
|
||||
var xAxisExt = formatResult.getAxisMap().get(ChartAxis.xAxisExt);
|
||||
var extStack = formatResult.getAxisMap().get(ChartAxis.extStack);
|
||||
if (ObjectUtils.isNotEmpty(xAxisExt) && ObjectUtils.isNotEmpty(extStack)) {
|
||||
if (Objects.equals(drillFields.get(0).getId(), xAxisExt.get(0).getId())) {
|
||||
fieldsToFilter.addAll(view.getXAxis());
|
||||
fieldsToFilter.addAll(extStack);
|
||||
}
|
||||
if (Objects.equals(drillFields.get(0).getId(), extStack.get(0).getId())) {
|
||||
fieldsToFilter.addAll(view.getXAxis());
|
||||
fieldsToFilter.addAll(xAxisExt);
|
||||
}
|
||||
}
|
||||
groupStackDrill(noDrillFieldAxis, noDrillFilterList, fieldsToFilter, drillFields, drillRequestList);
|
||||
formatResult.getAxisMap().put(ChartAxis.xAxis, noDrillFieldAxis);
|
||||
result.setFilterList(noDrillFilterList);
|
||||
}
|
||||
return (T) result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var xAxisExt = formatResult.getAxisMap().get(ChartAxis.xAxisExt);
|
||||
var extStack = formatResult.getAxisMap().get(ChartAxis.extStack);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var xAxisBase = xAxis.subList(0, xAxis.size() - xAxisExt.size() - extStack.size());
|
||||
var xAxisMain = xAxis.subList(0, xAxis.size() - extStack.size());
|
||||
return ChartDataBuild.transGroupStackDataAntV(xAxisBase, xAxisMain, xAxisExt, yAxis, extStack, data, view, isDrill);
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package io.dataease.chart.charts.impl.line;
|
||||
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class AreaHandler extends LineHandler {
|
||||
@Getter
|
||||
private String type = "area";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
result.getAxisMap().put(ChartAxis.xAxis, view.getXAxis());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult.getFilterList().stream().anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
return ChartDataBuild.transChartData(xAxis, yAxis, view, data, isDrill);
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package io.dataease.chart.charts.impl.line;
|
||||
|
||||
import io.dataease.chart.charts.impl.GroupChartHandler;
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.dataset.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.datasource.request.DatasourceRequest;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class LineHandler extends YoyChartHandler {
|
||||
@Getter
|
||||
private String type = "line";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var xAxis = result.getAxisMap().get(ChartAxis.xAxis);
|
||||
xAxis.addAll(view.getXAxisExt());
|
||||
var yAxis = result.getAxisMap().get(ChartAxis.yAxis);
|
||||
yAxis.addAll(view.getExtLabel());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.xAxisExt, view.getXAxisExt());
|
||||
result.getAxisMap().put(ChartAxis.extLabel, view.getExtLabel());
|
||||
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var xAxisExt = formatResult.getAxisMap().get(ChartAxis.xAxisExt);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var xAxisBase = xAxis.subList(0, xAxis.size() - xAxisExt.size());
|
||||
return ChartDataBuild.transBaseGroupDataAntV(xAxisBase, xAxis, xAxisExt, yAxis, view, data, isDrill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider) {
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
var result = (T) super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider);
|
||||
try {
|
||||
//如果有同环比过滤,应该用原始sql
|
||||
var originSql = result.getQuerySql();
|
||||
var dynamicAssistFields = getDynamicAssistFields(view);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var assistFields = getAssistFields(dynamicAssistFields, yAxis);
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields);
|
||||
req.setQuery(assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
result.setAssistData(assistData);
|
||||
result.setDynamicAssistFields(dynamicAssistFields);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
package io.dataease.chart.charts.impl.line;
|
||||
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.dataset.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.datasource.request.DatasourceRequest;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class StackAreaHandler extends YoyChartHandler {
|
||||
@Getter
|
||||
private String type = "area-stack";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var xAxis = result.getAxisMap().get(ChartAxis.xAxis);
|
||||
xAxis.addAll(view.getExtStack());
|
||||
var yAxis = result.getAxisMap().get(ChartAxis.yAxis);
|
||||
yAxis.addAll(view.getExtLabel());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.extStack, view.getExtStack());
|
||||
result.getAxisMap().put(ChartAxis.extLabel, view.getExtLabel());
|
||||
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var extStack = formatResult.getAxisMap().get(ChartAxis.extStack);
|
||||
var axisBase = xAxis.subList(0, xAxis.size() - extStack.size());
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
return ChartDataBuild.transStackChartDataAntV(axisBase, yAxis, view, data, extStack, isDrill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends CustomFilterResult, K extends AxisFormatResult> T customFilter(ChartViewDTO view, List<ChartExtFilterDTO> filterList, K formatResult) {
|
||||
var result = super.customFilter(view, filterList, formatResult);
|
||||
List<ChartDrillRequest> drillRequestList = view.getChartExtRequest().getDrill();
|
||||
var drillFields = formatResult.getAxisMap().get(ChartAxis.drill);
|
||||
// 堆叠维度下钻
|
||||
if (ObjectUtils.isNotEmpty(drillRequestList) && (drillFields.size() > drillRequestList.size())) {
|
||||
List<ChartExtFilterDTO> noDrillFilterList = filterList
|
||||
.stream()
|
||||
.filter(ele -> ele.getFilterType() != 1)
|
||||
.collect(Collectors.toList());
|
||||
var noDrillFieldAxis = formatResult.getAxisMap().get(ChartAxis.xAxis)
|
||||
.stream()
|
||||
.filter(ele -> ele.getSource() != FieldSource.DRILL)
|
||||
.collect(Collectors.toList());
|
||||
List<ChartExtFilterDTO> drillFilters = new ArrayList<>();
|
||||
ArrayList<ChartViewFieldDTO> fieldsToFilter = new ArrayList<>();
|
||||
var extStack = formatResult.getAxisMap().get(ChartAxis.extStack);
|
||||
if (ObjectUtils.isNotEmpty(extStack) &&
|
||||
Objects.equals(drillFields.get(0).getId(), extStack.get(0).getId())) {
|
||||
fieldsToFilter.addAll(view.getXAxis());
|
||||
}
|
||||
groupStackDrill(noDrillFieldAxis, noDrillFilterList, fieldsToFilter, drillFields, drillRequestList);
|
||||
formatResult.getAxisMap().put(ChartAxis.xAxis, noDrillFieldAxis);
|
||||
result.setFilterList(noDrillFilterList);
|
||||
}
|
||||
return (T) result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider) {
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
var result = (T) super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider);
|
||||
try {
|
||||
//如果有同环比过滤,应该用原始sql
|
||||
var originSql = result.getQuerySql();
|
||||
var dynamicAssistFields = getDynamicAssistFields(view);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var assistFields = getAssistFields(dynamicAssistFields, yAxis);
|
||||
if (CollectionUtils.isNotEmpty(assistFields)) {
|
||||
var req = new DatasourceRequest();
|
||||
req.setDsList(dsMap);
|
||||
var assistSql = assistSQL(originSql, assistFields);
|
||||
req.setQuery(assistSql);
|
||||
var assistData = (List<String[]>) provider.fetchResultField(req).get("data");
|
||||
result.setAssistData(assistData);
|
||||
result.setDynamicAssistFields(dynamicAssistFields);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.dataease.chart.charts.impl.map;
|
||||
|
||||
import io.dataease.chart.charts.impl.GroupChartHandler;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class FlowMapHandler extends GroupChartHandler {
|
||||
@Getter
|
||||
private String type = "flow-map";
|
||||
}
|
@ -0,0 +1,28 @@
|
||||
package io.dataease.chart.charts.impl.map;
|
||||
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class HeatMapHandler extends DefaultChartHandler {
|
||||
@Getter
|
||||
private String type = "heat-map";
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
Map<String, Object> result = ChartDataBuild.transHeatMapChartDataAntV(xAxis, xAxis, yAxis, view, data, isDrill);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package io.dataease.chart.charts.impl.map;
|
||||
|
||||
import io.dataease.chart.charts.impl.ExtQuotaChartHandler;
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class MapHandler extends ExtQuotaChartHandler {
|
||||
@Getter
|
||||
private String type = "map";
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package io.dataease.chart.charts.impl.map;
|
||||
|
||||
import io.dataease.chart.charts.impl.GroupChartHandler;
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SymbolicMapHandler extends GroupChartHandler {
|
||||
@Getter
|
||||
private String type = "symbolic-map";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = result.getAxisMap().get(ChartAxis.yAxis);
|
||||
yAxis.addAll(view.getExtBubble());
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
package io.dataease.chart.charts.impl.mix;
|
||||
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ChartMixHandler extends DefaultChartHandler {
|
||||
@Getter
|
||||
private final String type = "chart-mix";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package io.dataease.chart.charts.impl.numberic;
|
||||
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.dataset.manage.DatasetTableFieldManage;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import io.dataease.extensions.view.dto.ChartViewFieldDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class GaugeHandler extends NumbericChartHandler {
|
||||
@Getter
|
||||
private String type = "gauge";
|
||||
@Resource
|
||||
private DatasetTableFieldManage datasetTableFieldManage;
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var axisMap = new HashMap<ChartAxis, List<ChartViewFieldDTO>>();
|
||||
var yAxis = new ArrayList<>(view.getYAxis());
|
||||
Map<String, Object> customAttr = view.getCustomAttr();
|
||||
Map<String, Object> size = (Map<String, Object>) customAttr.get("misc");
|
||||
ChartViewFieldDTO gaugeMinViewField = getDynamicField(size, "gaugeMinType", "gaugeMinField");
|
||||
if (gaugeMinViewField != null) {
|
||||
yAxis.add(gaugeMinViewField);
|
||||
}
|
||||
ChartViewFieldDTO gaugeMaxViewField = getDynamicField(size, "gaugeMaxType", "gaugeMaxField");
|
||||
if (gaugeMaxViewField != null) {
|
||||
yAxis.add(gaugeMaxViewField);
|
||||
}
|
||||
axisMap.put(ChartAxis.xAxis, new ArrayList<>());
|
||||
axisMap.put(ChartAxis.yAxis, yAxis);
|
||||
var context = new HashMap<String, Object>();
|
||||
var result = new AxisFormatResult(axisMap, context);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.dataease.chart.charts.impl.numberic;
|
||||
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class IndicatorHandler extends NumbericChartHandler {
|
||||
@Getter
|
||||
private String render = "custom";
|
||||
@Getter
|
||||
private String type = "indicator";
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
package io.dataease.chart.charts.impl.numberic;
|
||||
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import io.dataease.extensions.view.dto.ChartViewFieldDTO;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class LiquidHandler extends NumbericChartHandler {
|
||||
@Getter
|
||||
private String type = "liquid";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var axisMap = new HashMap<ChartAxis, List<ChartViewFieldDTO>>();
|
||||
var yAxis = new ArrayList<>(view.getYAxis());
|
||||
Map<String, Object> customAttr = view.getCustomAttr();
|
||||
Map<String, Object> misc = (Map<String, Object>) customAttr.get("misc");
|
||||
ChartViewFieldDTO liquidMaxViewField = getDynamicField(misc, "liquidMaxType", "liquidMaxField");
|
||||
if (liquidMaxViewField != null) {
|
||||
yAxis.add(liquidMaxViewField);
|
||||
}
|
||||
axisMap.put(ChartAxis.xAxis, new ArrayList<>());
|
||||
axisMap.put(ChartAxis.yAxis, yAxis);
|
||||
var context = new HashMap<String, Object>();
|
||||
var result = new AxisFormatResult(axisMap, context);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,82 @@
|
||||
package io.dataease.chart.charts.impl.numberic;
|
||||
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.dataset.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.dataset.utils.SqlUtils;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.datasource.request.DatasourceRequest;
|
||||
import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.Quota2SQLObj;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
import io.dataease.extensions.view.util.FieldUtil;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.utils.BeanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class NumbericChartHandler extends DefaultChartHandler {
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider) {
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDsList(dsMap);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var allFields = getAllChartFields(view);
|
||||
Quota2SQLObj.quota2sqlObj(sqlMeta, yAxis, FieldUtil.transFields(allFields), crossDs, dsMap);
|
||||
String querySql = SQLProvider.createQuerySQL(sqlMeta, true, needOrder, view);
|
||||
querySql = SqlUtils.rebuildSQL(querySql, sqlMeta, crossDs, dsMap);
|
||||
datasourceRequest.setQuery(querySql);
|
||||
List<String[]> data = (List<String[]>) provider.fetchResultField(datasourceRequest).get("data");
|
||||
boolean isdrill = filterResult
|
||||
.getFilterList()
|
||||
.stream()
|
||||
.anyMatch(ele -> ele.getFilterType() == 1);
|
||||
Map<String, Object> result = ChartDataBuild.transNormalChartData(xAxis, yAxis, view, data, isdrill);
|
||||
T calcResult = (T) new ChartCalcDataResult();
|
||||
calcResult.setData(result);
|
||||
calcResult.setContext(filterResult.getContext());
|
||||
calcResult.setQuerySql(querySql);
|
||||
calcResult.setOriginData(data);
|
||||
return calcResult;
|
||||
}
|
||||
|
||||
protected ChartViewFieldDTO getDynamicField(Map<String, Object> target, String type, String field) {
|
||||
String maxType = (String) target.get(type);
|
||||
if (StringUtils.equalsIgnoreCase("dynamic", maxType)) {
|
||||
Map<String, Object> maxField = (Map<String, Object>) target.get(field);
|
||||
Long id = Long.valueOf((String) maxField.get("id"));
|
||||
String summary = (String) maxField.get("summary");
|
||||
DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(id);
|
||||
if (ObjectUtils.isNotEmpty(datasetTableField)) {
|
||||
if (datasetTableField.getDeType() == 0 || datasetTableField.getDeType() == 1 || datasetTableField.getDeType() == 5) {
|
||||
if (!StringUtils.containsIgnoreCase(summary, "count")) {
|
||||
DEException.throwException(Translator.get("i18n_gauge_field_change"));
|
||||
}
|
||||
}
|
||||
ChartViewFieldDTO dto = new ChartViewFieldDTO();
|
||||
BeanUtils.copyBean(dto, datasetTableField);
|
||||
dto.setSummary(summary);
|
||||
return dto;
|
||||
} else {
|
||||
DEException.throwException(Translator.get("i18n_gauge_field_delete"));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.dataease.chart.charts.impl.others;
|
||||
|
||||
import io.dataease.chart.charts.impl.ExtQuotaChartHandler;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class FunnelHandler extends ExtQuotaChartHandler {
|
||||
@Getter
|
||||
private String type = "funnel";
|
||||
}
|
@ -0,0 +1,26 @@
|
||||
package io.dataease.chart.charts.impl.others;
|
||||
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class RadarHandler extends YoyChartHandler {
|
||||
@Getter
|
||||
private String type = "radar";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = result.getAxisMap().get(ChartAxis.yAxis);
|
||||
yAxis.addAll(view.getExtLabel());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.extLabel, view.getExtLabel());
|
||||
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.dataease.chart.charts.impl.others;
|
||||
|
||||
import io.dataease.chart.charts.impl.GroupChartHandler;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class SankeyHandler extends GroupChartHandler {
|
||||
@Getter
|
||||
private String type = "sankey";
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.dataease.chart.charts.impl.others;
|
||||
|
||||
import io.dataease.chart.charts.impl.ExtQuotaChartHandler;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class WaterfallHandler extends ExtQuotaChartHandler {
|
||||
@Getter
|
||||
private String type = "waterfall";
|
||||
}
|
@ -0,0 +1,15 @@
|
||||
package io.dataease.chart.charts.impl.others;
|
||||
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.chart.charts.impl.ExtQuotaChartHandler;
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class WordCloudHandler extends ExtQuotaChartHandler {
|
||||
@Getter
|
||||
private String type = "word-cloud";
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package io.dataease.chart.charts.impl.pie;
|
||||
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.chart.charts.impl.ExtQuotaChartHandler;
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.extensions.view.dto.AxisFormatResult;
|
||||
import io.dataease.extensions.view.dto.ChartAxis;
|
||||
import io.dataease.extensions.view.dto.ChartViewDTO;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class PieHandler extends YoyChartHandler {
|
||||
@Override
|
||||
public void init() {
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "pie", this);
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "pie-rose", this);
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "pie-donut", this);
|
||||
chartHandlerManager.registerChartHandler(this.getRender(), "pie-rose-donut", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = result.getAxisMap().get(ChartAxis.yAxis);
|
||||
yAxis.addAll(view.getExtLabel());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.extLabel, view.getExtLabel());
|
||||
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,40 @@
|
||||
package io.dataease.chart.charts.impl.scatter;
|
||||
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class QuadrantHandler extends YoyChartHandler {
|
||||
@Getter
|
||||
private String type = "quadrant";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = new ArrayList<>(view.getYAxis());
|
||||
yAxis.addAll(view.getYAxisExt());
|
||||
yAxis.addAll(view.getExtBubble());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.yAxis, yAxis);
|
||||
result.getAxisMap().put(ChartAxis.extBubble, view.getExtBubble());
|
||||
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.yAxisExt, view.getYAxisExt());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult.getFilterList().stream().anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
Map<String, Object> result = ChartDataBuild.transMixChartDataAntV(xAxis, xAxis, new ArrayList<>(), yAxis, view, data, isDrill);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
package io.dataease.chart.charts.impl.scatter;
|
||||
|
||||
import io.dataease.chart.charts.impl.YoyChartHandler;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class ScatterHandler extends YoyChartHandler {
|
||||
@Getter
|
||||
private String type = "scatter";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
var yAxis = new ArrayList<>(view.getYAxis());
|
||||
yAxis.addAll(view.getExtBubble());
|
||||
yAxis.addAll(view.getExtLabel());
|
||||
yAxis.addAll(view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.yAxis, yAxis);
|
||||
result.getAxisMap().put(ChartAxis.extBubble, view.getExtBubble());
|
||||
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
|
||||
result.getAxisMap().put(ChartAxis.extLabel, view.getExtLabel());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List<String[]> data) {
|
||||
boolean isDrill = filterResult.getFilterList().stream().anyMatch(ele -> ele.getFilterType() == 1);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
var extBubble = formatResult.getAxisMap().get(ChartAxis.extBubble);
|
||||
Map<String, Object> result = ChartDataBuild.transScatterDataAntV(xAxis, yAxis, view, data, extBubble, isDrill);
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
package io.dataease.chart.charts.impl.table;
|
||||
|
||||
import io.dataease.api.chart.dto.PageInfo;
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.dataset.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.dataset.utils.SqlUtils;
|
||||
import io.dataease.datasource.provider.CalciteProvider;
|
||||
import io.dataease.datasource.request.DatasourceRequest;
|
||||
import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.Dimension2SQLObj;
|
||||
import io.dataease.engine.trans.Quota2SQLObj;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.model.SQLMeta;
|
||||
import io.dataease.extensions.view.util.ChartDataUtil;
|
||||
import io.dataease.extensions.view.util.FieldUtil;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Component
|
||||
public class TableInfoHandler extends DefaultChartHandler {
|
||||
@Getter
|
||||
private String type = "table-info";
|
||||
|
||||
@Override
|
||||
public AxisFormatResult formatAxis(ChartViewDTO view) {
|
||||
var result = super.formatAxis(view);
|
||||
result.getAxisMap().put(ChartAxis.yAxis, new ArrayList<>());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends CustomFilterResult, K extends AxisFormatResult> T customFilter(ChartViewDTO view, List<ChartExtFilterDTO> filterList, K formatResult) {
|
||||
var chartExtRequest = view.getChartExtRequest();
|
||||
Map<String, Object> mapAttr = view.getCustomAttr();
|
||||
Map<String, Object> mapSize = (Map<String, Object>) mapAttr.get("basicStyle");
|
||||
var tablePageMode = (String) mapSize.get("tablePageMode");
|
||||
formatResult.getContext().put("tablePageMode", tablePageMode);
|
||||
if (StringUtils.equalsIgnoreCase(tablePageMode, "page") && !view.getIsExcelExport()) {
|
||||
if (chartExtRequest.getGoPage() == null) {
|
||||
chartExtRequest.setGoPage(1L);
|
||||
}
|
||||
if (chartExtRequest.getPageSize() == null) {
|
||||
int pageSize = (int) mapSize.get("tablePageSize");
|
||||
if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) {
|
||||
chartExtRequest.setPageSize(Math.min(pageSize, view.getResultCount().longValue()));
|
||||
} else {
|
||||
chartExtRequest.setPageSize((long) pageSize);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) {
|
||||
chartExtRequest.setGoPage(1L);
|
||||
chartExtRequest.setPageSize(view.getResultCount().longValue());
|
||||
} else if (!view.getIsExcelExport()) {
|
||||
chartExtRequest.setGoPage(null);
|
||||
chartExtRequest.setPageSize(null);
|
||||
}
|
||||
}
|
||||
return super.customFilter(view, filterList, formatResult);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T extends ChartCalcDataResult> T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map<String, Object> sqlMap, SQLMeta sqlMeta, CalciteProvider provider) {
|
||||
var chartExtRequest = view.getChartExtRequest();
|
||||
var dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
DatasourceRequest datasourceRequest = new DatasourceRequest();
|
||||
datasourceRequest.setDsList(dsMap);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var allFields = getAllChartFields(view);
|
||||
PageInfo pageInfo = new PageInfo();
|
||||
pageInfo.setGoPage(chartExtRequest.getGoPage());
|
||||
if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) {
|
||||
pageInfo.setPageSize(Math.min(view.getResultCount() - (chartExtRequest.getGoPage() - 1) * chartExtRequest.getPageSize(), chartExtRequest.getPageSize()));
|
||||
} else {
|
||||
pageInfo.setPageSize(chartExtRequest.getPageSize());
|
||||
}
|
||||
Dimension2SQLObj.dimension2sqlObj(sqlMeta, xAxis, FieldUtil.transFields(allFields), crossDs, dsMap);
|
||||
String originSql = SQLProvider.createQuerySQL(sqlMeta, false, true, view);// 明细表强制加排序
|
||||
String limit = ((pageInfo.getGoPage() != null && pageInfo.getPageSize() != null) ? " LIMIT " + pageInfo.getPageSize() + " OFFSET " + (pageInfo.getGoPage() - 1) * pageInfo.getPageSize() : "");
|
||||
var querySql = originSql + limit;
|
||||
|
||||
var tablePageMode = (String) filterResult.getContext().get("tablePageMode");
|
||||
var totalPageSql = "SELECT COUNT(*) FROM (" + SQLProvider.createQuerySQL(sqlMeta, false, false, view) + ") COUNT_TEMP";
|
||||
if (StringUtils.isNotEmpty(totalPageSql) && StringUtils.equalsIgnoreCase(tablePageMode, "page")) {
|
||||
totalPageSql = SqlUtils.rebuildSQL(totalPageSql, sqlMeta, crossDs, dsMap);
|
||||
datasourceRequest.setQuery(totalPageSql);
|
||||
datasourceRequest.setTotalPageFlag(true);
|
||||
List<String[]> tmpData = (List<String[]>) provider.fetchResultField(datasourceRequest).get("data");
|
||||
var totalItems = ObjectUtils.isEmpty(tmpData) ? 0 : Long.valueOf(tmpData.get(0)[0]);
|
||||
if (StringUtils.equalsIgnoreCase(view.getResultMode(), "custom")) {
|
||||
totalItems = totalItems <= view.getResultCount() ? totalItems : view.getResultCount();
|
||||
}
|
||||
var totalPage = (totalItems / pageInfo.getPageSize()) + (totalItems % pageInfo.getPageSize() > 0 ? 1 : 0);
|
||||
view.setTotalItems(totalItems);
|
||||
view.setTotalPage(totalPage);
|
||||
}
|
||||
|
||||
querySql = SqlUtils.rebuildSQL(querySql, sqlMeta, crossDs, dsMap);
|
||||
datasourceRequest.setQuery(querySql);
|
||||
List<String[]> data = (List<String[]>) provider.fetchResultField(datasourceRequest).get("data");
|
||||
//自定义排序
|
||||
data = ChartDataUtil.resultCustomSort(xAxis, data);
|
||||
//数据重组逻辑可重载
|
||||
var result = this.buildResult(view, formatResult, filterResult, data);
|
||||
T calcResult = (T) new ChartCalcDataResult();
|
||||
calcResult.setData(result);
|
||||
calcResult.setContext(filterResult.getContext());
|
||||
calcResult.setQuerySql(querySql);
|
||||
calcResult.setOriginData(data);
|
||||
return calcResult;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
package io.dataease.chart.charts.impl.table;
|
||||
|
||||
import io.dataease.chart.charts.impl.GroupChartHandler;
|
||||
import lombok.Getter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class TablePivotHandler extends GroupChartHandler {
|
||||
@Getter
|
||||
private String type = "table-pivot";
|
||||
}
|
@ -6,6 +6,8 @@ import io.dataease.api.chart.dto.PageInfo;
|
||||
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
|
||||
import io.dataease.api.permissions.auth.dto.BusiPerCheckDTO;
|
||||
import io.dataease.api.permissions.dataset.dto.DataSetRowPermissionsTreeDTO;
|
||||
import io.dataease.chart.charts.AbstractChartHandler;
|
||||
import io.dataease.chart.charts.ChartHandlerManager;
|
||||
import io.dataease.chart.constant.ChartConstants;
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.constant.AuthEnum;
|
||||
@ -51,6 +53,8 @@ import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static io.dataease.extensions.view.dto.ChartAxis.*;
|
||||
|
||||
/**
|
||||
* @Author Junjun
|
||||
*/
|
||||
@ -70,6 +74,8 @@ public class ChartDataManage {
|
||||
private PermissionManage permissionManage;
|
||||
@Resource
|
||||
private ChartFilterTreeService chartFilterTreeService;
|
||||
@Resource
|
||||
private ChartHandlerManager chartHandlerManager;
|
||||
|
||||
@Resource
|
||||
private CorePermissionManage corePermissionManage;
|
||||
@ -115,6 +121,9 @@ public class ChartDataManage {
|
||||
List<ChartViewFieldDTO> allFields = getAllChartFields(view);
|
||||
ChartViewDTO chartViewDTO = null;
|
||||
|
||||
if (ObjectUtils.isNotEmpty(view.getIsPlugin()) && view.getIsPlugin()) {
|
||||
calcData1(view, chartExtRequest, allFields, viewFields);
|
||||
}
|
||||
if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix")) {
|
||||
// 需要排除掉除类别轴以外所有的排序
|
||||
view.getXAxisExt().forEach(dto -> dto.setSort("none"));
|
||||
@ -145,7 +154,7 @@ public class ChartDataManage {
|
||||
view1.getSenior().put("assistLineCfg", assistLineCfg1);
|
||||
}
|
||||
}
|
||||
ChartViewDTO left = calcData(view1, chartExtRequest, allFields, viewFields);
|
||||
ChartViewDTO left = calcData1(view1, chartExtRequest, allFields, viewFields);
|
||||
data.put("left", left.getData());
|
||||
//针对右轴,删除yAxis
|
||||
ChartViewDTO view2 = JsonUtil.parseObject(viewJson, ChartViewDTO.class);
|
||||
@ -162,7 +171,7 @@ public class ChartDataManage {
|
||||
view2.setXAxisExt(view2.getExtBubble());
|
||||
view2.setExtStack(new ArrayList<>());
|
||||
view2.setExtBubble(new ArrayList<>());
|
||||
ChartViewDTO right = calcData(view2, chartExtRequest, allFields, viewFields);
|
||||
ChartViewDTO right = calcData1(view2, chartExtRequest, allFields, viewFields);
|
||||
data.put("right", right.getData());
|
||||
|
||||
//重新组装
|
||||
@ -181,6 +190,273 @@ public class ChartDataManage {
|
||||
}
|
||||
|
||||
public ChartViewDTO calcData(ChartViewDTO view, ChartExtRequest chartExtRequest, List<ChartViewFieldDTO> allFields, List<ChartViewFieldDTO> viewFields) throws Exception {
|
||||
AbstractChartHandler chartHandler = chartHandlerManager.getChartHandler(view.getRender(), view.getType());
|
||||
AxisFormatResult formatResult = chartHandler.formatAxis(view);
|
||||
var xAxis = formatResult.getAxisMap().get(ChartAxis.xAxis);
|
||||
var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis);
|
||||
|
||||
DatasetGroupInfoDTO table = datasetGroupManage.getDatasetGroupInfoDTO(view.getTableId(), null);
|
||||
if (table == null) {
|
||||
DEException.throwException(ResultCode.DATA_IS_WRONG.code(), Translator.get("i18n_no_ds"));
|
||||
}
|
||||
// check permission
|
||||
BusiPerCheckDTO dto = new BusiPerCheckDTO();
|
||||
dto.setId(table.getId());
|
||||
dto.setAuthEnum(AuthEnum.READ);
|
||||
boolean checked = corePermissionManage.checkAuth(dto);
|
||||
if (!checked) {
|
||||
DEException.throwException(Translator.get("i18n_no_datasource_permission"));
|
||||
}
|
||||
|
||||
// column permission
|
||||
Map<String, ColumnPermissionItem> desensitizationList = new HashMap<>();
|
||||
List<DatasetTableFieldDTO> columnPermissionFields = permissionManage.filterColumnPermissions(transFields(allFields), desensitizationList, table.getId(), chartExtRequest.getUser());
|
||||
// row permission
|
||||
List<DataSetRowPermissionsTreeDTO> rowPermissionsTree = permissionManage.getRowPermissionsTree(table.getId(), chartExtRequest.getUser());
|
||||
//将没有权限的列删掉
|
||||
List<String> dataeaseNames = columnPermissionFields.stream().map(DatasetTableFieldDTO::getDataeaseName).collect(Collectors.toList());
|
||||
dataeaseNames.add("*");
|
||||
var axisMap = formatResult.getAxisMap();
|
||||
axisMap.forEach((axis, fields) -> {
|
||||
Iterator<ChartViewFieldDTO> iterator = fields.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
ChartViewFieldDTO fieldDTO = iterator.next();
|
||||
if (desensitizationList.containsKey(fieldDTO.getDataeaseName()) || !dataeaseNames.contains(fieldDTO.getDataeaseName())) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (ObjectUtils.isEmpty(xAxis) && ObjectUtils.isEmpty(yAxis)) {
|
||||
return emptyChartViewDTO(view);
|
||||
}
|
||||
|
||||
// 过滤来自仪表板的条件
|
||||
List<ChartExtFilterDTO> extFilterList = new ArrayList<>();
|
||||
//组件过滤条件
|
||||
if (ObjectUtils.isNotEmpty(chartExtRequest.getFilter())) {
|
||||
for (ChartExtFilterDTO request : chartExtRequest.getFilter()) {
|
||||
// 解析多个fieldId,fieldId是一个逗号分隔的字符串
|
||||
String fieldId = request.getFieldId();
|
||||
if (request.getIsTree() == null) {
|
||||
request.setIsTree(false);
|
||||
}
|
||||
|
||||
boolean hasParameters = false;
|
||||
List<SqlVariableDetails> sqlVariables = datasetGroupManage.getSqlParams(Arrays.asList(view.getTableId()));
|
||||
if (CollectionUtils.isNotEmpty(sqlVariables)) {
|
||||
for (SqlVariableDetails parameter : Optional.ofNullable(request.getParameters()).orElse(new ArrayList<>())) {
|
||||
String parameterId = StringUtils.endsWith(parameter.getId(), START_END_SEPARATOR) ? parameter.getId().split(START_END_SEPARATOR)[0] : parameter.getId();
|
||||
if (sqlVariables.stream().map(SqlVariableDetails::getId).collect(Collectors.toList()).contains(parameterId)) {
|
||||
hasParameters = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasParameters) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (StringUtils.isNotEmpty(fieldId)) {
|
||||
List<Long> fieldIds = Arrays.stream(fieldId.split(",")).map(Long::valueOf).collect(Collectors.toList());
|
||||
|
||||
if (request.getIsTree()) {
|
||||
ChartExtFilterDTO filterRequest = new ChartExtFilterDTO();
|
||||
BeanUtils.copyBean(filterRequest, request);
|
||||
filterRequest.setFilterType(0);
|
||||
filterRequest.setDatasetTableFieldList(new ArrayList<>());
|
||||
for (Long fId : fieldIds) {
|
||||
DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(fId);
|
||||
if (datasetTableField == null) {
|
||||
continue;
|
||||
}
|
||||
if (Objects.equals(datasetTableField.getDatasetTableId(), view.getTableId())) {
|
||||
if (ObjectUtils.isNotEmpty(filterRequest.getViewIds())) {
|
||||
if (filterRequest.getViewIds().contains(view.getId())) {
|
||||
filterRequest.getDatasetTableFieldList().add(datasetTableField);
|
||||
}
|
||||
} else {
|
||||
filterRequest.getDatasetTableFieldList().add(datasetTableField);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ObjectUtils.isNotEmpty(filterRequest.getDatasetTableFieldList())) {
|
||||
extFilterList.add(filterRequest);
|
||||
}
|
||||
} else {
|
||||
for (Long fId : fieldIds) {
|
||||
ChartExtFilterDTO filterRequest = new ChartExtFilterDTO();
|
||||
BeanUtils.copyBean(filterRequest, request);
|
||||
filterRequest.setFilterType(0);
|
||||
filterRequest.setFieldId(fId + "");
|
||||
|
||||
DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(fId);
|
||||
if (datasetTableField == null) {
|
||||
continue;
|
||||
}
|
||||
filterRequest.setDatasetTableField(datasetTableField);
|
||||
if (Objects.equals(datasetTableField.getDatasetGroupId(), view.getTableId())) {
|
||||
if (ObjectUtils.isNotEmpty(filterRequest.getViewIds())) {
|
||||
if (filterRequest.getViewIds().contains(view.getId())) {
|
||||
extFilterList.add(filterRequest);
|
||||
}
|
||||
} else {
|
||||
extFilterList.add(filterRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<ChartExtFilterDTO> filters = new ArrayList<>();
|
||||
// 联动条件
|
||||
if (ObjectUtils.isNotEmpty(chartExtRequest.getLinkageFilters())) {
|
||||
filters.addAll(chartExtRequest.getLinkageFilters());
|
||||
}
|
||||
|
||||
// 外部参数条件
|
||||
if (ObjectUtils.isNotEmpty(chartExtRequest.getOuterParamsFilters())) {
|
||||
filters.addAll(chartExtRequest.getOuterParamsFilters());
|
||||
}
|
||||
|
||||
//联动过滤条件和外部参数过滤条件全部加上
|
||||
if (ObjectUtils.isNotEmpty(filters)) {
|
||||
for (ChartExtFilterDTO request : filters) {
|
||||
DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(Long.valueOf(request.getFieldId()));
|
||||
request.setDatasetTableField(datasetTableField);
|
||||
request.setFilterType(2);
|
||||
// 相同数据集
|
||||
if (Objects.equals(datasetTableField.getDatasetGroupId(), view.getTableId())) {
|
||||
if (ObjectUtils.isNotEmpty(request.getViewIds())) {
|
||||
if (request.getViewIds().contains(view.getId())) {
|
||||
extFilterList.add(request);
|
||||
}
|
||||
} else {
|
||||
extFilterList.add(request);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 下钻
|
||||
List<ChartDrillRequest> drillRequestList = chartExtRequest.getDrill();
|
||||
var drill = formatResult.getAxisMap().get(ChartAxis.drill);
|
||||
if (ObjectUtils.isNotEmpty(drillRequestList) && (drill.size() > drillRequestList.size())) {
|
||||
var fields = xAxis.stream().map(ChartViewFieldDTO::getId).collect(Collectors.toSet());
|
||||
for (int i = 0; i < drillRequestList.size(); i++) {
|
||||
ChartDrillRequest request = drillRequestList.get(i);
|
||||
for (ChartDimensionDTO dim : request.getDimensionList()) {
|
||||
ChartViewFieldDTO viewField = drill.get(i);
|
||||
// 将钻取值作为条件传递,将所有钻取字段作为xAxis并加上下一个钻取字段
|
||||
if (Objects.equals(dim.getId(), viewField.getId())) {
|
||||
DatasetTableFieldDTO datasetTableField = datasetTableFieldManage.selectById(dim.getId());
|
||||
ChartViewFieldDTO d = new ChartViewFieldDTO();
|
||||
BeanUtils.copyBean(d, datasetTableField);
|
||||
|
||||
ChartExtFilterDTO drillFilter = new ChartExtFilterDTO();
|
||||
drillFilter.setFieldId(String.valueOf(dim.getId()));
|
||||
drillFilter.setDatasetTableField(datasetTableField);
|
||||
drillFilter.setDatePattern(viewField.getDatePattern());
|
||||
drillFilter.setDateStyle(viewField.getDateStyle());
|
||||
drillFilter.setFilterType(1);
|
||||
if (datasetTableField.getDeType() == 1) {
|
||||
drillFilter.setOperator("between");
|
||||
// 把value类似过滤组件处理,获得start time和end time
|
||||
Map<String, Long> stringLongMap = Utils.parseDateTimeValue(dim.getValue());
|
||||
drillFilter.setValue(Arrays.asList(String.valueOf(stringLongMap.get("startTime")), String.valueOf(stringLongMap.get("endTime"))));
|
||||
} else {
|
||||
drillFilter.setOperator("in");
|
||||
drillFilter.setValue(Collections.singletonList(dim.getValue()));
|
||||
}
|
||||
extFilterList.add(drillFilter);
|
||||
|
||||
if (!fields.contains(dim.getId())) {
|
||||
viewField.setSource(FieldSource.DRILL);
|
||||
xAxis.add(viewField);
|
||||
fields.add(dim.getId());
|
||||
}
|
||||
if (i == drillRequestList.size() - 1) {
|
||||
ChartViewFieldDTO nextDrillField = drill.get(i + 1);
|
||||
if (!fields.contains(nextDrillField.getId())) {
|
||||
viewField.setSource(FieldSource.DRILL);
|
||||
nextDrillField.setSort(getDrillSort(xAxis, drill.get(0)));
|
||||
xAxis.add(nextDrillField);
|
||||
fields.add(nextDrillField.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//转义特殊字符
|
||||
extFilterList = extFilterList.stream().peek(ele -> {
|
||||
if (ObjectUtils.isNotEmpty(ele.getValue())) {
|
||||
List<String> collect = ele.getValue().stream().map(SQLUtils::transKeyword).collect(Collectors.toList());
|
||||
ele.setValue(collect);
|
||||
}
|
||||
}).collect(Collectors.toList());
|
||||
// 视图自定义过滤逻辑
|
||||
CustomFilterResult filterResult = chartHandler.customFilter(view, extFilterList, formatResult);
|
||||
// 字段过滤器
|
||||
FilterTreeObj fieldCustomFilter = view.getCustomFilter();
|
||||
chartFilterTreeService.searchFieldAndSet(fieldCustomFilter);
|
||||
fieldCustomFilter = chartFilterTreeService.charReplace(fieldCustomFilter);
|
||||
// 获取dsMap,union sql
|
||||
Map<String, Object> sqlMap = datasetSQLManage.getUnionSQLForEdit(table, chartExtRequest);
|
||||
String sql = (String) sqlMap.get("sql");
|
||||
Map<Long, DatasourceSchemaDTO> dsMap = (Map<Long, DatasourceSchemaDTO>) sqlMap.get("dsMap");
|
||||
List<String> dsList = new ArrayList<>();
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
dsList.add(next.getValue().getType());
|
||||
}
|
||||
boolean needOrder = Utils.isNeedOrder(dsList);
|
||||
boolean crossDs = Utils.isCrossDs(dsMap);
|
||||
if (!crossDs) {
|
||||
sql = Utils.replaceSchemaAlias(sql, dsMap);
|
||||
}
|
||||
|
||||
List<ChartViewFieldDTO> detailFieldList = new ArrayList<>();
|
||||
String detailFieldSql = null;
|
||||
List<String[]> detailData = new ArrayList<>();
|
||||
if (ObjectUtils.isEmpty(dsMap)) {
|
||||
DEException.throwException(ResultCode.DATA_IS_WRONG.code(), Translator.get("i18n_datasource_delete"));
|
||||
}
|
||||
for (Map.Entry<Long, DatasourceSchemaDTO> next : dsMap.entrySet()) {
|
||||
DatasourceSchemaDTO ds = next.getValue();
|
||||
if (StringUtils.isNotEmpty(ds.getStatus()) && "Error".equalsIgnoreCase(ds.getStatus())) {
|
||||
DEException.throwException(ResultCode.DATA_IS_WRONG.code(), Translator.get("i18n_invalid_ds"));
|
||||
}
|
||||
}
|
||||
|
||||
SQLMeta sqlMeta = new SQLMeta();
|
||||
Table2SQLObj.table2sqlobj(sqlMeta, null, "(" + sql + ")", crossDs);
|
||||
CustomWhere2Str.customWhere2sqlObj(sqlMeta, fieldCustomFilter, transFields(allFields), crossDs, dsMap);
|
||||
ExtWhere2Str.extWhere2sqlOjb(sqlMeta, extFilterList, transFields(allFields), crossDs, dsMap);
|
||||
WhereTree2Str.transFilterTrees(sqlMeta, rowPermissionsTree, transFields(allFields), crossDs, dsMap);
|
||||
Map<Long, String> dsTypeMap = dsMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().getType()));
|
||||
ChartCalcDataResult calcResult = chartHandler.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, calciteProvider);
|
||||
// 如果是表格导出查询 则在此处直接就可以返回
|
||||
var extStack = formatResult.getAxisMap().get(ChartAxis.extStack);
|
||||
if (view.getIsExcelExport()) {
|
||||
Map<String, Object> sourceInfo = ChartDataBuild.transTableNormal(xAxis, yAxis, view, calcResult.getOriginData(), extStack, desensitizationList);
|
||||
sourceInfo.put("sourceData", calcResult.getOriginData());
|
||||
view.setData(sourceInfo);
|
||||
return view;
|
||||
}
|
||||
|
||||
// 构建结果
|
||||
Map<String, Object> map = new TreeMap<>();
|
||||
// 图表组件可再扩展
|
||||
Map<String, Object> mapTableNormal = ChartDataBuild.transTableNormal(xAxis, yAxis, view, calcResult.getOriginData(), extStack, desensitizationList);
|
||||
var drillFilters = filterResult.getFilterList().stream().filter(f -> f.getFilterType() == 1).collect(Collectors.toList());
|
||||
var isDrill = CollectionUtils.isNotEmpty(drillFilters);
|
||||
ChartViewDTO chartViewDTO = uniteViewResult(calcResult.getQuerySql(), calcResult.getData(), mapTableNormal, view, isDrill, drillFilters, calcResult.getDynamicAssistFields(), calcResult.getAssistData());
|
||||
return chartViewDTO;
|
||||
}
|
||||
|
||||
public ChartViewDTO calcData1(ChartViewDTO view, ChartExtRequest chartExtRequest, List<ChartViewFieldDTO> allFields, List<ChartViewFieldDTO> viewFields) throws Exception {
|
||||
List<ChartViewFieldDTO> xAxisBase = null;
|
||||
List<ChartViewFieldDTO> xAxis = null;
|
||||
List<ChartViewFieldDTO> xAxisExt = null;
|
||||
|
@ -699,28 +699,38 @@ public class ChartDataBuild {
|
||||
public static Map<String, Object> transChartData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewDTO view, List<String[]> data, boolean isDrill) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
|
||||
List<String> x = new ArrayList<>();
|
||||
List<Series> series = new ArrayList<>();
|
||||
for (ChartViewFieldDTO y : yAxis) {
|
||||
Series series1 = new Series();
|
||||
series1.setName(y.getName());
|
||||
series1.setType(view.getType());
|
||||
series1.setData(new ArrayList<>());
|
||||
series.add(series1);
|
||||
}
|
||||
List<AxisChartDataAntVDTO> dataList = new ArrayList<>();
|
||||
for (int i1 = 0; i1 < data.size(); i1++) {
|
||||
String[] d = data.get(i1);
|
||||
String[] row = data.get(i1);
|
||||
|
||||
StringBuilder a = new StringBuilder();
|
||||
for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) {
|
||||
if (isDrill) {
|
||||
a.append(row[xAxis.size() - 1]);
|
||||
} else {
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
if (i == xAxis.size() - 1) {
|
||||
a.append(row[i]);
|
||||
} else {
|
||||
a.append(row[i]).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
// yAxis最后的数据对应extLabel和extTooltip,将他们从yAxis中去掉,同时转换成动态值
|
||||
int size = xAxis.size() + yAxis.size();
|
||||
int extSize = view.getExtLabel().size() + view.getExtTooltip().size();
|
||||
|
||||
for (int i = xAxis.size(); i < size - extSize; i++) {
|
||||
AxisChartDataAntVDTO axisChartDataDTO = new AxisChartDataAntVDTO();
|
||||
axisChartDataDTO.setField(a.toString());
|
||||
axisChartDataDTO.setName(a.toString());
|
||||
|
||||
List<ChartDimensionDTO> dimensionList = new ArrayList<>();
|
||||
List<ChartQuotaDTO> quotaList = new ArrayList<>();
|
||||
AxisChartDataDTO axisChartDataDTO = new AxisChartDataDTO();
|
||||
|
||||
for (int j = 0; j < xAxis.size(); j++) {
|
||||
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
|
||||
chartDimensionDTO.setId(xAxis.get(j).getId());
|
||||
chartDimensionDTO.setValue(d[j]);
|
||||
chartDimensionDTO.setValue(row[j]);
|
||||
dimensionList.add(chartDimensionDTO);
|
||||
}
|
||||
axisChartDataDTO.setDimensionList(dimensionList);
|
||||
@ -731,28 +741,16 @@ public class ChartDataBuild {
|
||||
quotaList.add(chartQuotaDTO);
|
||||
axisChartDataDTO.setQuotaList(quotaList);
|
||||
try {
|
||||
axisChartDataDTO.setValue(StringUtils.isEmpty(d[i]) ? null : new BigDecimal(d[i]));
|
||||
axisChartDataDTO.setValue(StringUtils.isEmpty(row[i]) ? null : new BigDecimal(row[i]));
|
||||
} catch (Exception e) {
|
||||
axisChartDataDTO.setValue(new BigDecimal(0));
|
||||
}
|
||||
series.get(j).getData().add(axisChartDataDTO);
|
||||
axisChartDataDTO.setCategory(StringUtils.defaultIfBlank(yAxis.get(j).getChartShowName(), yAxis.get(j).getName()));
|
||||
buildDynamicValue(view, axisChartDataDTO, row, size, extSize);
|
||||
dataList.add(axisChartDataDTO);
|
||||
}
|
||||
if (isDrill) {
|
||||
a.append(d[xAxis.size() - 1]);
|
||||
} else {
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
if (i == xAxis.size() - 1) {
|
||||
a.append(d[i]);
|
||||
} else {
|
||||
a.append(d[i]).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
x.add(a.toString());
|
||||
}
|
||||
|
||||
map.put("x", x);
|
||||
map.put("series", series);
|
||||
map.put("data", dataList);
|
||||
return map;
|
||||
}
|
||||
|
||||
|
@ -394,7 +394,6 @@ export class RangeBar extends G2PlotChartView<BarOptions, Bar> {
|
||||
this.configXAxis,
|
||||
this.configYAxis,
|
||||
this.configSlider,
|
||||
this.configAnalyseHorizontal,
|
||||
this.configEmptyDataStrategy
|
||||
)(chart, options)
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package io.dataease.extensions.view.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class AxisFormatResult {
|
||||
private Map<ChartAxis, List<ChartViewFieldDTO>> axisMap;
|
||||
private Map<String, Object> context;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.dataease.extensions.view.dto;
|
||||
|
||||
public enum ChartAxis {
|
||||
xAxis,
|
||||
xAxisExt,
|
||||
extStack,
|
||||
extLabel,
|
||||
extTooltip,
|
||||
yAxis,
|
||||
yAxisExt,
|
||||
drill,
|
||||
extBubble;
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package io.dataease.extensions.view.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
public class ChartCalcDataResult {
|
||||
private Map<String, Object> data;
|
||||
private List<String[]> originData;
|
||||
private List<String[]> assistData;
|
||||
private List<ChartSeniorAssistDTO> dynamicAssistFields;
|
||||
private Map<String, Object> context;
|
||||
// TODO 数据源插件化之后换成整个请求对象
|
||||
private String querySql;
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package io.dataease.extensions.view.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
@ -23,4 +24,10 @@ public class ChartViewFieldDTO extends ChartViewFieldBaseDTO implements Serializ
|
||||
private String busiType;
|
||||
|
||||
private boolean isAgg;
|
||||
|
||||
/**
|
||||
* 字段来源
|
||||
*/
|
||||
@JsonIgnore
|
||||
private FieldSource source;
|
||||
}
|
||||
|
@ -0,0 +1,14 @@
|
||||
package io.dataease.extensions.view.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class CustomFilterResult {
|
||||
private List<ChartExtFilterDTO> filterList;
|
||||
private Map<String, Object> context;
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package io.dataease.extensions.view.dto;
|
||||
|
||||
public enum FieldSource {
|
||||
DRILL
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package io.dataease.extensions.view.util;
|
||||
|
||||
import io.dataease.extensions.view.dto.ChartViewFieldDTO;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class ChartDataUtil {
|
||||
// 对结果排序
|
||||
public static List<String[]> resultCustomSort(List<ChartViewFieldDTO> xAxis, List<String[]> data) {
|
||||
List<String[]> res = new ArrayList<>(data);
|
||||
if (xAxis.size() > 0) {
|
||||
// 找到对应维度
|
||||
for (int i = 0; i < xAxis.size(); i++) {
|
||||
ChartViewFieldDTO item = xAxis.get(i);
|
||||
if (StringUtils.equalsIgnoreCase(item.getSort(), "custom_sort")) {
|
||||
// 获取自定义值与data对应列的结果
|
||||
if (i > 0) {
|
||||
// 首先根据优先级高的字段分类,在每个前置字段相同的组里排序
|
||||
Map<String, List<String[]>> map = new LinkedHashMap<>();
|
||||
for (String[] d : res) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (int j = 0; j < i; j++) {
|
||||
if (StringUtils.equalsIgnoreCase(xAxis.get(j).getSort(), "none")) {
|
||||
continue;
|
||||
}
|
||||
stringBuilder.append(d[j]);
|
||||
}
|
||||
if (ObjectUtils.isEmpty(map.get(stringBuilder.toString()))) {
|
||||
map.put(stringBuilder.toString(), new ArrayList<>());
|
||||
}
|
||||
map.get(stringBuilder.toString()).add(d);
|
||||
}
|
||||
Iterator<Map.Entry<String, List<String[]>>> iterator = map.entrySet().iterator();
|
||||
List<String[]> list = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
Map.Entry<String, List<String[]>> next = iterator.next();
|
||||
list.addAll(customSort(Optional.ofNullable(item.getCustomSort()).orElse(new ArrayList<>()), next.getValue(), i));
|
||||
}
|
||||
res.clear();
|
||||
res.addAll(list);
|
||||
} else {
|
||||
res = customSort(Optional.ofNullable(item.getCustomSort()).orElse(new ArrayList<>()), res, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public static List<String[]> customSort(List<String> custom, List<String[]> data, int index) {
|
||||
List<String[]> res = new ArrayList<>();
|
||||
|
||||
List<Integer> indexArr = new ArrayList<>();
|
||||
List<String[]> joinArr = new ArrayList<>();
|
||||
for (int i = 0; i < custom.size(); i++) {
|
||||
String ele = custom.get(i);
|
||||
for (int j = 0; j < data.size(); j++) {
|
||||
String[] d = data.get(j);
|
||||
if (StringUtils.equalsIgnoreCase(ele, d[index])) {
|
||||
joinArr.add(d);
|
||||
indexArr.add(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 取得 joinArr 就是两者的交集
|
||||
List<Integer> indexArrData = new ArrayList<>();
|
||||
for (int i = 0; i < data.size(); i++) {
|
||||
indexArrData.add(i);
|
||||
}
|
||||
List<Integer> indexResult = new ArrayList<>();
|
||||
for (int i = 0; i < indexArrData.size(); i++) {
|
||||
if (!indexArr.contains(indexArrData.get(i))) {
|
||||
indexResult.add(indexArrData.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
List<String[]> subArr = new ArrayList<>();
|
||||
for (int i = 0; i < indexResult.size(); i++) {
|
||||
subArr.add(data.get(indexResult.get(i)));
|
||||
}
|
||||
res.addAll(joinArr);
|
||||
res.addAll(subArr);
|
||||
return res;
|
||||
}
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
package io.dataease.extensions.view.util;
|
||||
|
||||
import io.dataease.extensions.view.dto.ChartViewFieldBaseDTO;
|
||||
import io.dataease.extensions.view.dto.DatasetTableFieldDTO;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class FieldUtil {
|
||||
public static List<DatasetTableFieldDTO> transFields(List<? extends ChartViewFieldBaseDTO> list) {
|
||||
return list.stream().map(ele -> {
|
||||
DatasetTableFieldDTO dto = new DatasetTableFieldDTO();
|
||||
BeanUtils.copyProperties(dto, ele);
|
||||
return dto;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user