mirror of
https://github.com/dataease/dataease.git
synced 2026-05-24 06:18:10 +08:00
@@ -5,11 +5,11 @@ import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
*
|
||||
* 组件图表表
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2023-08-20
|
||||
* @since 2024-05-07
|
||||
*/
|
||||
@TableName("core_chart_view")
|
||||
public class CoreChartView implements Serializable {
|
||||
@@ -191,10 +191,21 @@ public class CoreChartView implements Serializable {
|
||||
*/
|
||||
private Boolean jumpActive;
|
||||
|
||||
/**
|
||||
* 复制来源
|
||||
*/
|
||||
private Long copyFrom;
|
||||
|
||||
/**
|
||||
* 复制ID
|
||||
*/
|
||||
private Long copyId;
|
||||
|
||||
/**
|
||||
* 区间条形图开启时间纬度开启聚合
|
||||
*/
|
||||
private Boolean aggregate;
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
@@ -491,6 +502,14 @@ public class CoreChartView implements Serializable {
|
||||
this.copyId = copyId;
|
||||
}
|
||||
|
||||
public Boolean getAggregate() {
|
||||
return aggregate;
|
||||
}
|
||||
|
||||
public void setAggregate(Boolean aggregate) {
|
||||
this.aggregate = aggregate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CoreChartView{" +
|
||||
@@ -531,6 +550,7 @@ public class CoreChartView implements Serializable {
|
||||
", jumpActive = " + jumpActive +
|
||||
", copyFrom = " + copyFrom +
|
||||
", copyId = " + copyId +
|
||||
", aggregate = " + aggregate +
|
||||
"}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,11 @@ import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* 组件图表表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author fit2cloud
|
||||
* @since 2023-08-20
|
||||
* @since 2024-05-07
|
||||
*/
|
||||
@Mapper
|
||||
public interface CoreChartViewMapper extends BaseMapper<CoreChartView> {
|
||||
|
||||
@@ -34,6 +34,7 @@ import io.dataease.utils.JsonUtil;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.collections4.MapUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.slf4j.Logger;
|
||||
@@ -127,6 +128,35 @@ public class ChartDataManage {
|
||||
List<ChartViewFieldDTO> yAxisExt = new ArrayList<>(view.getYAxisExt());
|
||||
yAxis.addAll(yAxisExt);
|
||||
}
|
||||
boolean skipBarRange = false;
|
||||
boolean barRangeDate = false;
|
||||
if (StringUtils.equalsIgnoreCase(view.getType(), "bar-range")) { //针对区间条形图进行处理
|
||||
yAxis.clear();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
List<ChartViewFieldDTO> extStack = new ArrayList<>(view.getExtStack());
|
||||
List<ChartViewFieldDTO> extBubble = new ArrayList<>(view.getExtBubble());
|
||||
if (ObjectUtils.isNotEmpty(view.getExtLabel()) && enableExtData(view.getType())) {
|
||||
@@ -753,6 +783,8 @@ public class ChartDataManage {
|
||||
mapChart = ChartDataBuild.transLabelChartData(xAxis, yAxis, view, data, isDrill);
|
||||
} else if (StringUtils.containsIgnoreCase(view.getType(), "quadrant")) {
|
||||
mapChart = ChartDataBuild.transQuadrantDataAntV(xAxis, yAxis, view, data, extBubble, isDrill);
|
||||
} else if (StringUtils.equalsIgnoreCase(view.getType(), "bar-range")) {
|
||||
mapChart = ChartDataBuild.transTimeBarDataAntV(skipBarRange, barRangeDate, xAxisBase, xAxis, yAxis, view, data, isDrill);
|
||||
} else {
|
||||
mapChart = ChartDataBuild.transChartDataAntV(xAxis, yAxis, view, data, isDrill);
|
||||
}
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
package io.dataease.chart.utils;
|
||||
|
||||
import io.dataease.api.chart.dto.*;
|
||||
import io.dataease.i18n.Lang;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -1323,4 +1327,268 @@ public class ChartDataBuild {
|
||||
return map;
|
||||
}
|
||||
|
||||
public static Map<String, Object> transTimeBarDataAntV(boolean skipBarRange, boolean isDate, List<ChartViewFieldDTO> xAxisBase, List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewDTO view, List<String[]> data, boolean isDrill) {
|
||||
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
if (skipBarRange) {
|
||||
map.put("data", new ArrayList<>());
|
||||
return map;
|
||||
}
|
||||
|
||||
List<Date> dates = new ArrayList<>();
|
||||
List<BigDecimal> numbers = new ArrayList<>();
|
||||
|
||||
ChartViewFieldDTO dateAxis1 = null;
|
||||
|
||||
SimpleDateFormat sdf = null;
|
||||
if (isDate) {
|
||||
if (BooleanUtils.isTrue(view.getAggregate())) {
|
||||
dateAxis1 = yAxis.get(0);
|
||||
} else {
|
||||
dateAxis1 = xAxis.get(xAxisBase.size());
|
||||
}
|
||||
sdf = new SimpleDateFormat(getDateFormat(dateAxis1.getDateStyle(), dateAxis1.getDatePattern()));
|
||||
}
|
||||
|
||||
List<Object> dataList = new ArrayList<>();
|
||||
for (int i1 = 0; i1 < data.size(); i1++) {
|
||||
String[] row = data.get(i1);
|
||||
|
||||
StringBuilder xField = new StringBuilder();
|
||||
if (isDrill) {
|
||||
xField.append(row[xAxis.size() - 1]);
|
||||
} else {
|
||||
for (int i = 0; i < xAxisBase.size(); i++) {
|
||||
if (i == xAxisBase.size() - 1) {
|
||||
xField.append(row[i]);
|
||||
} else {
|
||||
xField.append(row[i]).append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Map<String, Object> obj = new HashMap<>();
|
||||
obj.put("field", xField.toString());
|
||||
obj.put("category", xField.toString());
|
||||
|
||||
List<ChartDimensionDTO> dimensionList = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < xAxisBase.size(); i++) {
|
||||
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
|
||||
chartDimensionDTO.setId(xAxis.get(i).getId());
|
||||
chartDimensionDTO.setValue(row[i]);
|
||||
dimensionList.add(chartDimensionDTO);
|
||||
}
|
||||
if (isDrill) {
|
||||
int index = xAxis.size() - 1;
|
||||
ChartDimensionDTO chartDimensionDTO = new ChartDimensionDTO();
|
||||
chartDimensionDTO.setId(xAxis.get(index).getId());
|
||||
chartDimensionDTO.setValue(row[index]);
|
||||
dimensionList.add(chartDimensionDTO);
|
||||
}
|
||||
obj.put("dimensionList", dimensionList);
|
||||
|
||||
|
||||
List<Object> values = new ArrayList<>();
|
||||
|
||||
if (row[xAxisBase.size()] == null || row[xAxisBase.size() + 1] == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isDate) {
|
||||
int index;
|
||||
if (BooleanUtils.isTrue(view.getAggregate())) {
|
||||
index = xAxis.size();
|
||||
} else {
|
||||
index = xAxisBase.size();
|
||||
}
|
||||
|
||||
values.add(row[index]);
|
||||
values.add(row[index + 1]);
|
||||
obj.put("values", values);
|
||||
Date date1 = null, date2 = null;
|
||||
try {
|
||||
date1 = sdf.parse(row[index]);
|
||||
if (date1 != null) {
|
||||
dates.add(date1);
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
try {
|
||||
date2 = sdf.parse(row[index + 1]);
|
||||
if (date2 != null) {
|
||||
dates.add(date2);
|
||||
}
|
||||
} catch (Exception ignore) {
|
||||
}
|
||||
//间隔时间
|
||||
obj.put("gap", getTimeGap(date1, date2, dateAxis1.getDateStyle()));
|
||||
|
||||
} else {
|
||||
values.add(new BigDecimal(row[xAxis.size()]));
|
||||
values.add(new BigDecimal(row[xAxis.size() + 1]));
|
||||
obj.put("values", values);
|
||||
|
||||
numbers.add(new BigDecimal(row[xAxis.size()]));
|
||||
numbers.add(new BigDecimal(row[xAxis.size() + 1]));
|
||||
|
||||
//间隔差
|
||||
obj.put("gap", new BigDecimal(row[xAxis.size() + 1]).subtract(new BigDecimal(row[xAxis.size()])));
|
||||
}
|
||||
|
||||
dataList.add(obj);
|
||||
}
|
||||
|
||||
if (isDate) {
|
||||
Date minDate = dates.stream().min(Date::compareTo).orElse(null);
|
||||
if (minDate != null) {
|
||||
map.put("minTime", sdf.format(minDate));
|
||||
}
|
||||
Date maxDate = dates.stream().max(Date::compareTo).orElse(null);
|
||||
if (maxDate != null) {
|
||||
map.put("maxTime", sdf.format(maxDate));
|
||||
}
|
||||
} else {
|
||||
map.put("min", numbers.stream().min(BigDecimal::compareTo).orElse(null));
|
||||
map.put("max", numbers.stream().max(BigDecimal::compareTo).orElse(null));
|
||||
}
|
||||
|
||||
map.put("isDate", isDate);
|
||||
map.put("data", dataList);
|
||||
return map;
|
||||
|
||||
}
|
||||
|
||||
private static String getDateFormat(String dateStyle, String datePattern) {
|
||||
String split;
|
||||
if (StringUtils.equalsIgnoreCase(datePattern, "date_split")) {
|
||||
split = "/";
|
||||
} else {
|
||||
split = "-";
|
||||
}
|
||||
switch (dateStyle) {
|
||||
case "y":
|
||||
return "yyyy";
|
||||
case "y_M":
|
||||
return "yyyy" + split + "MM";
|
||||
case "y_M_d":
|
||||
return "yyyy" + split + "MM" + split + "dd";
|
||||
case "H_m_s":
|
||||
return "HH:mm:ss";
|
||||
case "y_M_d_H":
|
||||
return "yyyy" + split + "MM" + split + "dd" + " HH";
|
||||
case "y_M_d_H_m":
|
||||
return "yyyy" + split + "MM" + split + "dd" + " HH:mm";
|
||||
case "y_M_d_H_m_s":
|
||||
return "yyyy" + split + "MM" + split + "dd" + " HH:mm:ss";
|
||||
default:
|
||||
return "yyyy-MM-dd HH:mm:ss";
|
||||
}
|
||||
}
|
||||
|
||||
private static String getTimeGap(Date from, Date to, String dateStyle) {
|
||||
if (from == null || to == null) {
|
||||
return "";
|
||||
}
|
||||
Calendar fromCalender = Calendar.getInstance();
|
||||
fromCalender.setTime(from);
|
||||
|
||||
Calendar toCalender = Calendar.getInstance();
|
||||
toCalender.setTime(to);
|
||||
|
||||
long yearGap = 0;
|
||||
long monthGap = 0;
|
||||
long dayGap = (toCalender.getTimeInMillis() - fromCalender.getTimeInMillis()) / (1000 * 3600 * 24);
|
||||
long hourGap = ((toCalender.getTimeInMillis() - fromCalender.getTimeInMillis()) / (1000 * 3600)) % 24;
|
||||
long minuteGap = ((toCalender.getTimeInMillis() - fromCalender.getTimeInMillis()) / (1000 * 60)) % 60;
|
||||
long secondGap = ((toCalender.getTimeInMillis() - fromCalender.getTimeInMillis()) / 1000) % 60;
|
||||
|
||||
String language = "zh-CN"; //国际化
|
||||
Lang lang = Lang.getLangWithoutDefault(language);
|
||||
boolean isEnUs = Lang.en_US.equals(lang);
|
||||
String splitter = isEnUs ? " " : "";
|
||||
|
||||
String yearGapStr = "";
|
||||
String monthGapStr = "";
|
||||
|
||||
String dayGapStr = "";
|
||||
if (dayGap != 0) {
|
||||
dayGapStr = dayGap + splitter + Translator.get("i18n_day") + (isEnUs && dayGap != 1 ? "s" : "");
|
||||
}
|
||||
String hourGapStr = "";
|
||||
if (hourGap != 0) {
|
||||
hourGapStr = hourGap + splitter + Translator.get("i18n_hour") + (isEnUs && hourGap != 1 ? "s" : "");
|
||||
}
|
||||
String minuteGapStr = "";
|
||||
if (minuteGap != 0) {
|
||||
minuteGapStr = minuteGap + splitter + Translator.get("i18n_minute") + (isEnUs && minuteGap != 1 ? "s" : "");
|
||||
}
|
||||
String secondGapStr = "";
|
||||
if (secondGap != 0) {
|
||||
secondGapStr = secondGap + splitter + Translator.get("i18n_second") + (isEnUs && secondGap != 1 ? "s" : "");
|
||||
}
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
|
||||
switch (dateStyle) {
|
||||
case "y":
|
||||
yearGap = toCalender.get(Calendar.YEAR) - fromCalender.get(Calendar.YEAR);
|
||||
yearGapStr = yearGap == 0 ? "" : (yearGap + splitter + Translator.get("i18n_year") + (isEnUs && yearGap != 1 ? "s" : ""));
|
||||
return yearGapStr;
|
||||
case "y_M":
|
||||
yearGap = ((toCalender.get(Calendar.YEAR) - fromCalender.get(Calendar.YEAR)) * 12L + (toCalender.get(Calendar.MONTH) - fromCalender.get(Calendar.MONTH))) / 12;
|
||||
monthGap = ((toCalender.get(Calendar.YEAR) - fromCalender.get(Calendar.YEAR)) * 12L + (toCalender.get(Calendar.MONTH) - fromCalender.get(Calendar.MONTH))) % 12;
|
||||
|
||||
yearGapStr = yearGap == 0 ? "" : (yearGap + splitter + Translator.get("i18n_year") + (isEnUs && yearGap != 1 ? "s" : ""));
|
||||
monthGapStr = monthGap == 0 ? "" : (monthGap + splitter + Translator.get("i18n_month") + (isEnUs && monthGap != 1 ? "s" : ""));
|
||||
|
||||
if (!yearGapStr.isEmpty()) {
|
||||
list.add(yearGapStr);
|
||||
}
|
||||
if (!monthGapStr.isEmpty()) {
|
||||
list.add(monthGapStr);
|
||||
}
|
||||
return StringUtils.join(list, splitter);
|
||||
case "y_M_d":
|
||||
return dayGapStr;
|
||||
case "y_M_d_H":
|
||||
if (!dayGapStr.isEmpty()) {
|
||||
list.add(dayGapStr);
|
||||
}
|
||||
if (!hourGapStr.isEmpty()) {
|
||||
list.add(hourGapStr);
|
||||
}
|
||||
return StringUtils.join(list, splitter);
|
||||
case "y_M_d_H_m":
|
||||
if (!dayGapStr.isEmpty()) {
|
||||
list.add(dayGapStr);
|
||||
}
|
||||
if (!hourGapStr.isEmpty()) {
|
||||
list.add(hourGapStr);
|
||||
}
|
||||
if (!minuteGapStr.isEmpty()) {
|
||||
list.add(minuteGapStr);
|
||||
}
|
||||
return StringUtils.join(list, splitter);
|
||||
case "H_m_s":
|
||||
case "y_M_d_H_m_s":
|
||||
if (!dayGapStr.isEmpty()) {
|
||||
list.add(dayGapStr);
|
||||
}
|
||||
if (!hourGapStr.isEmpty()) {
|
||||
list.add(hourGapStr);
|
||||
}
|
||||
if (!minuteGapStr.isEmpty()) {
|
||||
list.add(minuteGapStr);
|
||||
}
|
||||
if (!secondGapStr.isEmpty()) {
|
||||
list.add(secondGapStr);
|
||||
}
|
||||
return StringUtils.join(list, splitter);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,3 +51,10 @@ i18n_error_login_type=error login type
|
||||
i18n_schema_is_empty=Schema is empty!
|
||||
i18n_table_name_repeat=Has duplicate name:
|
||||
i18n_sql_not_empty=SQL cannot be empty!
|
||||
|
||||
i18n_year=Year
|
||||
i18n_month=Month
|
||||
i18n_day=Day
|
||||
i18n_hour=Hour
|
||||
i18n_minute=Minute
|
||||
i18n_second=Second
|
||||
|
||||
@@ -64,3 +64,10 @@ i18n_sql_not_empty=sql \u4E0D\u80FD\u4E3A\u7A7A
|
||||
i18n_menu.parameter=\u7CFB\u7EDF\u53C2\u6570
|
||||
i18n_user_old_pwd_error=\u539F\u59CB\u5BC6\u7801\u9519\u8BEF
|
||||
i18n_menu.toolbox-log=\u64CD\u4F5C\u65E5\u5FD7
|
||||
|
||||
i18n_year=\u5E74
|
||||
i18n_month=\u6708
|
||||
i18n_day=\u5929
|
||||
i18n_hour=\u5C0F\u65F6
|
||||
i18n_minute=\u5206\u949F
|
||||
i18n_second=\u79D2
|
||||
|
||||
@@ -31,7 +31,7 @@ i18n_union_field_can_not_empty=\u95DC\u806F\u5B57\u6BB5\u4E0D\u80FD\u70BA\u7A7A
|
||||
i18n_table_duplicate=\u76F8\u540C\u7BC0\u9EDE\u9700\u91CD\u65B0\u62D6\u5165\u624D\u80FD\u7E7C\u7E8C\u65B0\u5EFA\u6578\u64DA\u96C6
|
||||
i18n_no_column_permission=\u6C92\u6709\u5217\u6B0A\u9650
|
||||
i18n_fetch_error=SQL\u57F7\u884C\u5931\u6557\uFF0C\u8ACB\u6AA2\u67E5\u8868\u3001\u5B57\u6BB5\u3001\u95DC\u806F\u95DC\u7CFB\u7B49\u4FE1\u606F\u662F\u5426\u6B63\u78BA\u4E26\u91CD\u65B0\u7DE8\u8F2F\u3002
|
||||
i18n_no_datasource_permission=\u65e0\u6570\u636e\u6e90\u8bbf\u95ee\u6743\u9650
|
||||
i18n_no_datasource_permission=\u65E0\u6570\u636E\u6E90\u8BBF\u95EE\u6743\u9650
|
||||
|
||||
i18n_field_circular_ref=\u5B57\u6BB5\u5B58\u5728\u5FAA\u74B0\u5F15\u7528
|
||||
|
||||
@@ -51,4 +51,11 @@ i18n_login_name_pwd_err=\u7528\u6236\u540D\u6216\u5BC6\u78BC\u932F\u8AA4
|
||||
i18n_error_login_type=\u767B\u9304\u985E\u578B\u932F\u8AA4
|
||||
i18n_schema_is_empty=schema\u70BA\u7A7A\uFF01
|
||||
i18n_table_name_repeat=\u540D\u7A31\u91CD\u8907:
|
||||
i18n_sql_not_empty=sql\u4e0d\u80fd\u70ba\u7a7a
|
||||
i18n_sql_not_empty=sql\u4E0D\u80FD\u70BA\u7A7A
|
||||
|
||||
i18n_year=\u5E74
|
||||
i18n_month=\u6708
|
||||
i18n_day=\u5929
|
||||
i18n_hour=\u5C0F\u6642
|
||||
i18n_minute=\u5206\u9418
|
||||
i18n_second=\u79D2
|
||||
|
||||
Reference in New Issue
Block a user