From f987734aa2f1c7ddf34a297ca12c18fc50d3bdce Mon Sep 17 00:00:00 2001 From: wisonic-s Date: Tue, 25 Jun 2024 18:43:55 +0800 Subject: [PATCH] =?UTF-8?q?refactor(=E5=9B=BE=E8=A1=A8):=20=E5=9B=BE?= =?UTF-8?q?=E8=A1=A8=E8=8E=B7=E5=8F=96=E6=95=B0=E6=8D=AE=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=8C=96(WIP)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chart/charts/AbstractChartHandler.java | 14 + .../chart/charts/ChartHandlerManager.java | 28 + .../charts/impl/DefaultChartHandler.java | 495 ++++++++++++++++++ .../charts/impl/ExtQuotaChartHandler.java | 21 + .../chart/charts/impl/GroupChartHandler.java | 20 + .../chart/charts/impl/YoyChartHandler.java | 121 +++++ .../chart/charts/impl/bar/BarHandler.java | 77 +++ .../impl/bar/BidirectionalBarHandler.java | 10 + .../charts/impl/bar/GroupBarHandler.java | 75 +++ .../charts/impl/bar/ProgressBarHandler.java | 44 ++ .../charts/impl/bar/RangeBarHandler.java | 81 +++ .../charts/impl/bar/StackBarHandler.java | 71 +++ .../charts/impl/bar/StackGroupBarHandler.java | 90 ++++ .../chart/charts/impl/line/AreaHandler.java | 31 ++ .../chart/charts/impl/line/LineHandler.java | 83 +++ .../charts/impl/line/StackAreaHandler.java | 114 ++++ .../chart/charts/impl/map/FlowMapHandler.java | 11 + .../chart/charts/impl/map/HeatMapHandler.java | 28 + .../chart/charts/impl/map/MapHandler.java | 15 + .../charts/impl/map/SymbolicMapHandler.java | 22 + .../charts/impl/mix/ChartMixHandler.java | 21 + .../charts/impl/numberic/GaugeHandler.java | 45 ++ .../impl/numberic/IndicatorHandler.java | 13 + .../charts/impl/numberic/LiquidHandler.java | 36 ++ .../impl/numberic/NumbericChartHandler.java | 82 +++ .../charts/impl/others/FunnelHandler.java | 11 + .../charts/impl/others/RadarHandler.java | 26 + .../charts/impl/others/SankeyHandler.java | 11 + .../charts/impl/others/WaterfallHandler.java | 11 + .../charts/impl/others/WordCloudHandler.java | 15 + .../chart/charts/impl/pie/PieHandler.java | 31 ++ .../charts/impl/scatter/QuadrantHandler.java | 40 ++ .../charts/impl/scatter/ScatterHandler.java | 41 ++ .../charts/impl/table/TableInfoHandler.java | 125 +++++ .../charts/impl/table/TablePivotHandler.java | 11 + .../chart/manage/ChartDataManage.java | 280 +++++++++- .../dataease/chart/utils/ChartDataBuild.java | 58 +- .../js/panel/charts/bar/range-bar.ts | 1 - .../extensions/view/dto/AxisFormatResult.java | 14 + .../extensions/view/dto/ChartAxis.java | 13 + .../view/dto/ChartCalcDataResult.java | 18 + .../view/dto/ChartViewFieldDTO.java | 7 + .../view/dto/CustomFilterResult.java | 14 + .../extensions/view/dto/FieldSource.java | 5 + .../extensions/view/util/ChartDataUtil.java | 87 +++ .../extensions/view/util/FieldUtil.java | 18 + 46 files changed, 2452 insertions(+), 33 deletions(-) create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/AbstractChartHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/ChartHandlerManager.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/DefaultChartHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/ExtQuotaChartHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/GroupChartHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/YoyChartHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/BarHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/BidirectionalBarHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/GroupBarHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/ProgressBarHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/RangeBarHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/StackBarHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/StackGroupBarHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/AreaHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/LineHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/StackAreaHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/FlowMapHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/HeatMapHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/MapHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/SymbolicMapHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/mix/ChartMixHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/GaugeHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/IndicatorHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/LiquidHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/NumbericChartHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/FunnelHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/RadarHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/SankeyHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/WaterfallHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/WordCloudHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/pie/PieHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/scatter/QuadrantHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/scatter/ScatterHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableInfoHandler.java create mode 100644 core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TablePivotHandler.java create mode 100644 sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/AxisFormatResult.java create mode 100644 sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartAxis.java create mode 100644 sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartCalcDataResult.java create mode 100644 sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/CustomFilterResult.java create mode 100644 sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/FieldSource.java create mode 100644 sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/util/ChartDataUtil.java create mode 100644 sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/util/FieldUtil.java diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/AbstractChartHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/AbstractChartHandler.java new file mode 100644 index 0000000000..c8cac291ab --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/AbstractChartHandler.java @@ -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 formatAxis(ChartViewDTO view); + public abstract T customFilter(ChartViewDTO view, List filterList, K formatResult); + public abstract T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider); +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/ChartHandlerManager.java b/core/core-backend/src/main/java/io/dataease/chart/charts/ChartHandlerManager.java new file mode 100644 index 0000000000..a59cd0a239 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/ChartHandlerManager.java @@ -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 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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/DefaultChartHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/DefaultChartHandler.java new file mode 100644 index 0000000000..04521cef18 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/DefaultChartHandler.java @@ -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>(); + var context = new HashMap(); + 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 customFilter(ChartViewDTO view, List filterList, K formatResult) { + return (T) new CustomFilterResult(filterList, formatResult.getContext()); + } + + public Map buildResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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 result = ChartDataBuild.transChartData(xAxis, yAxis, view, data, isDrill); + return result; + } + + @Override + public T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider) { + var dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry 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 data = (List) 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 getAllChartFields(ChartViewDTO view) { + // get all fields + Map> stringListMap = chartViewManege.listByDQ(view.getTableId(), view.getId(), view); + List dimensionList = stringListMap.get("dimensionList"); + List quotaList = stringListMap.get("quotaList"); + List allFields = new ArrayList<>(); + allFields.addAll(dimensionList); + allFields.addAll(quotaList); + return allFields.stream().filter(ele -> ele.getId() != -1L).collect(Collectors.toList()); + } + + protected List getDynamicAssistFields(ChartViewDTO view) throws Exception { + List list = new ArrayList<>(); + + Map 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 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 getAssistFields(List list, List yAxis) { + List 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 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 xAxis, List yAxis, List 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 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 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 filter, List 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 xAxis, + List filterList, + List fieldsToFilter, + List drillFields, + List drillRequestList) { + var fields = xAxis.stream().map(ChartViewFieldDTO::getId).collect(Collectors.toSet()); + ChartDrillRequest head = drillRequestList.get(0); + Map dimValMap = new HashMap<>(); + head.getDimensionList().forEach(item -> dimValMap.put(item.getId(), item.getValue())); + Map 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 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 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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/ExtQuotaChartHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/ExtQuotaChartHandler.java new file mode 100644 index 0000000000..d0fbaa51b5 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/ExtQuotaChartHandler.java @@ -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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/GroupChartHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/GroupChartHandler.java new file mode 100644 index 0000000000..fd45d9ad42 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/GroupChartHandler.java @@ -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(view.getXAxis()); + xAxis.addAll(view.getXAxisExt()); + result.getAxisMap().put(ChartAxis.xAxis, xAxis); + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/YoyChartHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/YoyChartHandler.java new file mode 100644 index 0000000000..ce1793a1ce --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/YoyChartHandler.java @@ -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 customFilter(ChartViewDTO view, List filterList, K formatResult) { + var yAxis = formatResult.getAxisMap().get(ChartAxis.yAxis); + String originFilterJson = (String) JsonUtil.toJSONString(filterList); + // 如果设置了同环比的指标字段设置了过滤器,那就需要把该过滤器的时间往前回调一年 + // 计算完同环比之后,再把计算结果和原有的过滤结果对比,去除不该出现的前一年的数据 + boolean yoyFiltered = checkYoyFilter(filterList, yAxis); + if (yoyFiltered) { + List 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 buildResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List data) { + var yoyFiltered = filterResult.getContext().get("yoyFiltered") != null; + // 带过滤同环比直接返回原始数据,再由视图重新组装 + if (yoyFiltered) { + var result = new HashMap(); + result.put("data", data); + return result; + } + return buildNormalResult(view, formatResult, filterResult, data); + } + + /** + * 构建同环比类型的数据 + * @param view 视图对象 + * @param formatResult 处理后的轴 + * @param filterResult 处理后的过滤器 + * @param data 原始数据 + * @return 视图构建结果 + */ + public Map buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List data) { + return super.buildResult(view, formatResult, filterResult, data); + } + + @Override + public T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider) { + var dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry 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) filterResult.getContext().get("originFilter"); + var allFields = (List) 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) provider.fetchResultField(request).get("data"); + List resultData = new ArrayList<>(); + // 包含一年前的数据, 已计算同环比 + var yoyData = (List) 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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/BarHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/BarHandler.java new file mode 100644 index 0000000000..a57fa02882 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/BarHandler.java @@ -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 calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider) { + var dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry 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) provider.fetchResultField(req).get("data"); + result.setAssistData(assistData); + result.setDynamicAssistFields(dynamicAssistFields); + } + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/BidirectionalBarHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/BidirectionalBarHandler.java new file mode 100644 index 0000000000..1b04272928 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/BidirectionalBarHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/GroupBarHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/GroupBarHandler.java new file mode 100644 index 0000000000..7547813156 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/GroupBarHandler.java @@ -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 customFilter(ChartViewDTO view, List filterList, K formatResult) { + var result = super.customFilter(view, filterList, formatResult); + List drillRequestList = view.getChartExtRequest().getDrill(); + var drillFields = formatResult.getAxisMap().get(ChartAxis.drill); + // 分组维度下钻 + if (ObjectUtils.isNotEmpty(drillRequestList) && (drillFields.size() > drillRequestList.size())) { + List 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 drillFilters = new ArrayList<>(); + ArrayList 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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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); + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/ProgressBarHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/ProgressBarHandler.java new file mode 100644 index 0000000000..49fc7e7bc0 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/ProgressBarHandler.java @@ -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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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 result = ChartDataBuild.transMixChartDataAntV(xAxis, xAxis, new ArrayList<>(), yAxis, view, data, isDrill); + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/RangeBarHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/RangeBarHandler.java new file mode 100644 index 0000000000..5e05016e9d --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/RangeBarHandler.java @@ -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(); + var xAxis = new ArrayList(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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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 result = ChartDataBuild.transBarRangeDataAntV(skipBarRange, barRangeDate, xAxis, xAxis, yAxis, view, data, isDrill); + return result; + } + + @Override + public T calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider) { + sqlMeta.setChartType(this.type); + return super.calcChartResult(view, formatResult, filterResult, sqlMap, sqlMeta, provider); + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/StackBarHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/StackBarHandler.java new file mode 100644 index 0000000000..614a865cec --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/StackBarHandler.java @@ -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 customFilter(ChartViewDTO view, List filterList, K formatResult) { + var result = super.customFilter(view, filterList, formatResult); + List drillRequestList = view.getChartExtRequest().getDrill(); + var drillFields = formatResult.getAxisMap().get(ChartAxis.drill); + // 堆叠维度下钻 + if (ObjectUtils.isNotEmpty(drillRequestList) && (drillFields.size() > drillRequestList.size())) { + List 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 drillFilters = new ArrayList<>(); + ArrayList 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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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); + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/StackGroupBarHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/StackGroupBarHandler.java new file mode 100644 index 0000000000..1badf8d5a0 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/bar/StackGroupBarHandler.java @@ -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 customFilter(ChartViewDTO view, List filterList, K formatResult) { + var result = super.customFilter(view, filterList, formatResult); + List drillRequestList = view.getChartExtRequest().getDrill(); + var drillFields = formatResult.getAxisMap().get(ChartAxis.drill); + // 分组维度下钻 + if (ObjectUtils.isNotEmpty(drillRequestList) && (drillFields.size() > drillRequestList.size())) { + List 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 drillFilters = new ArrayList<>(); + ArrayList 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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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); + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/AreaHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/AreaHandler.java new file mode 100644 index 0000000000..ea1787df99 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/AreaHandler.java @@ -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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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); + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/LineHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/LineHandler.java new file mode 100644 index 0000000000..57ed1522dd --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/LineHandler.java @@ -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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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 calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider) { + var dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry 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) provider.fetchResultField(req).get("data"); + result.setAssistData(assistData); + result.setDynamicAssistFields(dynamicAssistFields); + } + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/StackAreaHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/StackAreaHandler.java new file mode 100644 index 0000000000..a39e01c238 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/line/StackAreaHandler.java @@ -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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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 customFilter(ChartViewDTO view, List filterList, K formatResult) { + var result = super.customFilter(view, filterList, formatResult); + List drillRequestList = view.getChartExtRequest().getDrill(); + var drillFields = formatResult.getAxisMap().get(ChartAxis.drill); + // 堆叠维度下钻 + if (ObjectUtils.isNotEmpty(drillRequestList) && (drillFields.size() > drillRequestList.size())) { + List 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 drillFilters = new ArrayList<>(); + ArrayList 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 calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider) { + var dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry 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) provider.fetchResultField(req).get("data"); + result.setAssistData(assistData); + result.setDynamicAssistFields(dynamicAssistFields); + } + } catch (Exception e) { + e.printStackTrace(); + } + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/FlowMapHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/FlowMapHandler.java new file mode 100644 index 0000000000..aa0963e0c4 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/FlowMapHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/HeatMapHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/HeatMapHandler.java new file mode 100644 index 0000000000..e210bf9254 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/HeatMapHandler.java @@ -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 buildResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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 result = ChartDataBuild.transHeatMapChartDataAntV(xAxis, xAxis, yAxis, view, data, isDrill); + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/MapHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/MapHandler.java new file mode 100644 index 0000000000..02581ff07c --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/MapHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/SymbolicMapHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/SymbolicMapHandler.java new file mode 100644 index 0000000000..47cc138fbe --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/map/SymbolicMapHandler.java @@ -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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/mix/ChartMixHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/mix/ChartMixHandler.java new file mode 100644 index 0000000000..96963add3c --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/mix/ChartMixHandler.java @@ -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; + } + +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/GaugeHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/GaugeHandler.java new file mode 100644 index 0000000000..71a65e7210 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/GaugeHandler.java @@ -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>(); + var yAxis = new ArrayList<>(view.getYAxis()); + Map customAttr = view.getCustomAttr(); + Map size = (Map) 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(); + var result = new AxisFormatResult(axisMap, context); + return result; + } + +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/IndicatorHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/IndicatorHandler.java new file mode 100644 index 0000000000..2e1de08453 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/IndicatorHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/LiquidHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/LiquidHandler.java new file mode 100644 index 0000000000..8d4d2d36c0 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/LiquidHandler.java @@ -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>(); + var yAxis = new ArrayList<>(view.getYAxis()); + Map customAttr = view.getCustomAttr(); + Map misc = (Map) 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(); + var result = new AxisFormatResult(axisMap, context); + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/NumbericChartHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/NumbericChartHandler.java new file mode 100644 index 0000000000..9f3ebb1391 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/numberic/NumbericChartHandler.java @@ -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 calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider) { + var dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry 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 data = (List) provider.fetchResultField(datasourceRequest).get("data"); + boolean isdrill = filterResult + .getFilterList() + .stream() + .anyMatch(ele -> ele.getFilterType() == 1); + Map 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 target, String type, String field) { + String maxType = (String) target.get(type); + if (StringUtils.equalsIgnoreCase("dynamic", maxType)) { + Map maxField = (Map) 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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/FunnelHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/FunnelHandler.java new file mode 100644 index 0000000000..b5f6434b4f --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/FunnelHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/RadarHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/RadarHandler.java new file mode 100644 index 0000000000..c84f12da12 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/RadarHandler.java @@ -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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/SankeyHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/SankeyHandler.java new file mode 100644 index 0000000000..788644caed --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/SankeyHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/WaterfallHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/WaterfallHandler.java new file mode 100644 index 0000000000..76a0ae2aae --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/WaterfallHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/WordCloudHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/WordCloudHandler.java new file mode 100644 index 0000000000..599509181c --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/others/WordCloudHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/pie/PieHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/pie/PieHandler.java new file mode 100644 index 0000000000..b72db58f6b --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/pie/PieHandler.java @@ -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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/scatter/QuadrantHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/scatter/QuadrantHandler.java new file mode 100644 index 0000000000..8017af4b0e --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/scatter/QuadrantHandler.java @@ -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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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 result = ChartDataBuild.transMixChartDataAntV(xAxis, xAxis, new ArrayList<>(), yAxis, view, data, isDrill); + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/scatter/ScatterHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/scatter/ScatterHandler.java new file mode 100644 index 0000000000..7ce7b0f7ad --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/scatter/ScatterHandler.java @@ -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 buildNormalResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, List 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 result = ChartDataBuild.transScatterDataAntV(xAxis, yAxis, view, data, extBubble, isDrill); + return result; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableInfoHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableInfoHandler.java new file mode 100644 index 0000000000..6cb1677cd4 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TableInfoHandler.java @@ -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 customFilter(ChartViewDTO view, List filterList, K formatResult) { + var chartExtRequest = view.getChartExtRequest(); + Map mapAttr = view.getCustomAttr(); + Map mapSize = (Map) 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 calcChartResult(ChartViewDTO view, AxisFormatResult formatResult, CustomFilterResult filterResult, Map sqlMap, SQLMeta sqlMeta, CalciteProvider provider) { + var chartExtRequest = view.getChartExtRequest(); + var dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry 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 tmpData = (List) 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 data = (List) 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; + } +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TablePivotHandler.java b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TablePivotHandler.java new file mode 100644 index 0000000000..2980fda8f5 --- /dev/null +++ b/core/core-backend/src/main/java/io/dataease/chart/charts/impl/table/TablePivotHandler.java @@ -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"; +} diff --git a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java index 44318e010c..e78c46ae06 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java +++ b/core/core-backend/src/main/java/io/dataease/chart/manage/ChartDataManage.java @@ -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 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 allFields, List 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 desensitizationList = new HashMap<>(); + List columnPermissionFields = permissionManage.filterColumnPermissions(transFields(allFields), desensitizationList, table.getId(), chartExtRequest.getUser()); + // row permission + List rowPermissionsTree = permissionManage.getRowPermissionsTree(table.getId(), chartExtRequest.getUser()); + //将没有权限的列删掉 + List dataeaseNames = columnPermissionFields.stream().map(DatasetTableFieldDTO::getDataeaseName).collect(Collectors.toList()); + dataeaseNames.add("*"); + var axisMap = formatResult.getAxisMap(); + axisMap.forEach((axis, fields) -> { + Iterator 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 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 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 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 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 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 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 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 sqlMap = datasetSQLManage.getUnionSQLForEdit(table, chartExtRequest); + String sql = (String) sqlMap.get("sql"); + Map dsMap = (Map) sqlMap.get("dsMap"); + List dsList = new ArrayList<>(); + for (Map.Entry 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 detailFieldList = new ArrayList<>(); + String detailFieldSql = null; + List detailData = new ArrayList<>(); + if (ObjectUtils.isEmpty(dsMap)) { + DEException.throwException(ResultCode.DATA_IS_WRONG.code(), Translator.get("i18n_datasource_delete")); + } + for (Map.Entry 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 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 sourceInfo = ChartDataBuild.transTableNormal(xAxis, yAxis, view, calcResult.getOriginData(), extStack, desensitizationList); + sourceInfo.put("sourceData", calcResult.getOriginData()); + view.setData(sourceInfo); + return view; + } + + // 构建结果 + Map map = new TreeMap<>(); + // 图表组件可再扩展 + Map 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 allFields, List viewFields) throws Exception { List xAxisBase = null; List xAxis = null; List xAxisExt = null; diff --git a/core/core-backend/src/main/java/io/dataease/chart/utils/ChartDataBuild.java b/core/core-backend/src/main/java/io/dataease/chart/utils/ChartDataBuild.java index 4c7eb56ca1..69eb672e74 100644 --- a/core/core-backend/src/main/java/io/dataease/chart/utils/ChartDataBuild.java +++ b/core/core-backend/src/main/java/io/dataease/chart/utils/ChartDataBuild.java @@ -699,28 +699,38 @@ public class ChartDataBuild { public static Map transChartData(List xAxis, List yAxis, ChartViewDTO view, List data, boolean isDrill) { Map map = new HashMap<>(); - List x = new ArrayList<>(); - List 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 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 dimensionList = new ArrayList<>(); List 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; } diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/bar/range-bar.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/bar/range-bar.ts index a6d81e77eb..7f24cb8390 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/bar/range-bar.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/bar/range-bar.ts @@ -394,7 +394,6 @@ export class RangeBar extends G2PlotChartView { this.configXAxis, this.configYAxis, this.configSlider, - this.configAnalyseHorizontal, this.configEmptyDataStrategy )(chart, options) } diff --git a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/AxisFormatResult.java b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/AxisFormatResult.java new file mode 100644 index 0000000000..523b9d0257 --- /dev/null +++ b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/AxisFormatResult.java @@ -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> axisMap; + private Map context; +} diff --git a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartAxis.java b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartAxis.java new file mode 100644 index 0000000000..1ad9a6d3b3 --- /dev/null +++ b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartAxis.java @@ -0,0 +1,13 @@ +package io.dataease.extensions.view.dto; + +public enum ChartAxis { + xAxis, + xAxisExt, + extStack, + extLabel, + extTooltip, + yAxis, + yAxisExt, + drill, + extBubble; +} diff --git a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartCalcDataResult.java b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartCalcDataResult.java new file mode 100644 index 0000000000..e65846c387 --- /dev/null +++ b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartCalcDataResult.java @@ -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 data; + private List originData; + private List assistData; + private List dynamicAssistFields; + private Map context; + // TODO 数据源插件化之后换成整个请求对象 + private String querySql; +} diff --git a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartViewFieldDTO.java b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartViewFieldDTO.java index 0f25bec208..d3c66aa2b5 100644 --- a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartViewFieldDTO.java +++ b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/ChartViewFieldDTO.java @@ -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; } diff --git a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/CustomFilterResult.java b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/CustomFilterResult.java new file mode 100644 index 0000000000..f8c4403762 --- /dev/null +++ b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/CustomFilterResult.java @@ -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 filterList; + private Map context; +} diff --git a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/FieldSource.java b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/FieldSource.java new file mode 100644 index 0000000000..6d5a806d86 --- /dev/null +++ b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/dto/FieldSource.java @@ -0,0 +1,5 @@ +package io.dataease.extensions.view.dto; + +public enum FieldSource { + DRILL +} diff --git a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/util/ChartDataUtil.java b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/util/ChartDataUtil.java new file mode 100644 index 0000000000..ed8375c773 --- /dev/null +++ b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/util/ChartDataUtil.java @@ -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 resultCustomSort(List xAxis, List data) { + List 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> 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>> iterator = map.entrySet().iterator(); + List list = new ArrayList<>(); + while (iterator.hasNext()) { + Map.Entry> 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 customSort(List custom, List data, int index) { + List res = new ArrayList<>(); + + List indexArr = new ArrayList<>(); + List 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 indexArrData = new ArrayList<>(); + for (int i = 0; i < data.size(); i++) { + indexArrData.add(i); + } + List indexResult = new ArrayList<>(); + for (int i = 0; i < indexArrData.size(); i++) { + if (!indexArr.contains(indexArrData.get(i))) { + indexResult.add(indexArrData.get(i)); + } + } + + List 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; + } +} diff --git a/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/util/FieldUtil.java b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/util/FieldUtil.java new file mode 100644 index 0000000000..9954b1fdfd --- /dev/null +++ b/sdk/extensions/extensions-view/src/main/java/io/dataease/extensions/view/util/FieldUtil.java @@ -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 transFields(List list) { + return list.stream().map(ele -> { + DatasetTableFieldDTO dto = new DatasetTableFieldDTO(); + BeanUtils.copyProperties(dto, ele); + return dto; + }).collect(Collectors.toList()); + } +}