Merge pull request #9336 from ulleo/dev

feat(图表): 区间条形图支持标签显示间隔值
This commit is contained in:
ulleo 2024-04-25 15:26:21 +08:00 committed by GitHub
commit 7e89b0472d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 186 additions and 10 deletions

View File

@ -1,7 +1,11 @@
package io.dataease.service.chart.util;
import io.dataease.auth.api.dto.CurrentUserDto;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.controller.request.chart.ChartDrillRequest;
import io.dataease.dto.chart.*;
import io.dataease.i18n.Lang;
import io.dataease.i18n.Translator;
import io.dataease.plugins.common.base.domain.ChartViewWithBLOBs;
import io.dataease.plugins.common.dto.chart.ChartViewFieldDTO;
import io.dataease.plugins.xpack.auth.dto.request.ColumnPermissionItem;
@ -1390,20 +1394,24 @@ public class ChartDataBuild {
values.add(row[xAxis.size() - 2]);
values.add(row[xAxis.size() - 1]);
obj.put("values", values);
Date date1 = null, date2 = null;
try {
Date date = sdf.parse(row[xAxis.size() - 2]);
if (date != null) {
dates.add(date);
date1 = sdf.parse(row[xAxis.size() - 2]);
if (date1 != null) {
dates.add(date1);
}
} catch (Exception ignore) {
}
try {
Date date = sdf.parse(row[xAxis.size() - 1]);
if (date != null) {
dates.add(date);
date2 = sdf.parse(row[xAxis.size() - 1]);
if (date2 != null) {
dates.add(date2);
}
} catch (Exception ignore) {
}
//间隔时间
obj.put("gap", getTimeGap(date1, date2, xAxis1.getDateStyle()));
} else {
values.add(new BigDecimal(row[xAxis.size() - 2]));
values.add(new BigDecimal(row[xAxis.size() - 1]));
@ -1411,6 +1419,9 @@ public class ChartDataBuild {
numbers.add(new BigDecimal(row[xAxis.size() - 2]));
numbers.add(new BigDecimal(row[xAxis.size() - 1]));
//间隔差
obj.put("gap", new BigDecimal(row[xAxis.size() - 1]).subtract(new BigDecimal(row[xAxis.size() - 2])));
}
dataList.add(obj);
@ -1436,6 +1447,114 @@ public class ChartDataBuild {
}
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;
CurrentUserDto user = AuthUtils.getUser();
String language = null;
if (user != null) {
language = user.getLanguage();
}
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 "";
}
}
public static Map<String, Object> transBidirectionalBarData(List<ChartViewFieldDTO> xAxis, List<ChartViewFieldDTO> yAxis, ChartViewDTO view, List<String[]> data, boolean isDrill) {
Map<String, Object> map = new HashMap<>();

View File

@ -292,3 +292,9 @@ i18n_field_circular_ref=Field has Circular Reference
\u8868\u5355\u7BA1\u7406=From Manage
\u6211\u7684\u586B\u62A5=My Job
\u8868\u5355\u521B\u5EFA=Form Create
i18n_year=Year
i18n_month=Month
i18n_day=Day
i18n_hour=Hour
i18n_minute=Minute
i18n_second=Second

View File

@ -282,3 +282,9 @@ i18n_field_circular_ref=\u5B57\u6BB5\u5B58\u5728\u5FAA\u73AF\u5F15\u7528
\u8868\u5355\u7BA1\u7406=\u8868\u5355\u7BA1\u7406
\u6211\u7684\u586B\u62A5=\u6211\u7684\u586B\u62A5
\u8868\u5355\u521B\u5EFA=\u8868\u5355\u521B\u5EFA
i18n_year=\u5E74
i18n_month=\u6708
i18n_day=\u5929
i18n_hour=\u5C0F\u65F6
i18n_minute=\u5206\u949F
i18n_second=\u79D2

View File

@ -287,3 +287,9 @@ i18n_field_circular_ref=\u5B57\u6BB5\u5B58\u5728\u5FAA\u74B0\u5F15\u7528
\u8868\u5355\u7BA1\u7406=\u8868\u55AE\u7BA1\u7406
\u6211\u7684\u586B\u62A5=\u6211\u7684\u586B\u5831
\u8868\u5355\u521B\u5EFA=\u8868\u55AE\u5275\u5EFA
i18n_year=\u5E74
i18n_month=\u6708
i18n_day=\u5929
i18n_hour=\u5C0F\u6642
i18n_minute=\u5206\u9418
i18n_second=\u79D2

View File

@ -1289,6 +1289,7 @@ export default {
label_shadow_color: 'Shadow Color',
content_formatter: 'Content Format',
label_reserve_decimal_count: 'Reserve Decimal',
show_gap: 'Show Gap',
inside: 'Inside',
tooltip: 'Tips',
tooltip_item: 'Data Item',

View File

@ -1286,6 +1286,7 @@ export default {
label: '標簽',
label_position: '標簽位置',
label_reserve_decimal_count: '保留小數',
show_gap: '顯示間隔值',
label_bg: '標簽背景',
label_shadow: '標簽陰影',
label_shadow_color: '陰影顏色',

View File

@ -1285,6 +1285,7 @@ export default {
label_shadow: '标签阴影',
label_shadow_color: '阴影颜色',
label_reserve_decimal_count: '保留小数',
show_gap: '显示间隔值',
content_formatter: '内容格式',
inside: '内',
tooltip: '提示',

View File

@ -174,6 +174,9 @@ export function getLabel(chart) {
}
// label value formatter
if (chart.type && chart.type !== 'waterfall') {
if (chart.type === 'bar-time-range') {
label.content = ''
}
label.formatter = function(param) {
let xAxis, yAxis, extStack, xaxisExt
let res = param.value
@ -266,6 +269,12 @@ export function getLabel(chart) {
} else if (chart.type === 'scatter' && xAxis && xAxis.length > 0 && xAxis[0].groupType === 'q') {
// 针对散点图
res = param.field
} else if (chart.type === 'bar-time-range') {
if (l.showGap) {
res = param.gap
} else {
res = param.values[0] + ' ~ ' + param.values[1]
}
} else {
for (let i = 0; i < yAxis.length; i++) {
const f = yAxis[i]
@ -363,7 +372,10 @@ export function getTooltip(chart) {
if (chart.type && chart.type !== 'waterfall') {
if (chart.type === 'bar-group-stack') {
tooltip.fields = []
} else if (chart.type === 'bar-time-range') {
tooltip.fields = ['gap', 'category', 'values', 'group', 'field']
}
tooltip.formatter = function(param) {
let res = param.value
@ -492,7 +504,10 @@ export function getTooltip(chart) {
}
} else if (chart.type === 'bar-time-range') {
obj = { values: param.values, name: param.category }
res = param.values[0] + ' - ' + param.values[1]
res = param.values[0] + ' ~ ' + param.values[1]
if (t.showGap) {
res = res + ' (' + param.gap + ')'
}
} else {
res = param.value
}

View File

@ -1117,7 +1117,6 @@ export const TYPE_CONFIGS = [
icon: 'bar-time-range',
properties: [
'color-selector',
'label-selector-ant-v',
'tooltip-selector-ant-v',
'x-axis-selector-ant-v',
@ -1141,11 +1140,13 @@ export const TYPE_CONFIGS = [
'show',
'fontSize',
'color',
'position-h'
'position-h',
'showGap'
],
'tooltip-selector-ant-v': [
'show',
'textStyle'
'textStyle',
'showGap'
],
'x-axis-selector-ant-v': [
'show',

View File

@ -139,6 +139,16 @@
>{{ option.name }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item
v-show="showProperty('showGap')"
:label="$t('chart.show_gap')"
class="form-item"
>
<el-checkbox
v-model="labelForm.showGap"
@change="changeLabelAttr('showGap')"
/>
</el-form-item>
</div>
<el-form-item
v-show="showProperty('conversion')"

View File

@ -61,6 +61,16 @@
@change="changeTooltipAttr('backgroundColor')"
/>
</el-form-item>
<el-form-item
v-show="showProperty('showGap')"
:label="$t('chart.show_gap')"
class="form-item"
>
<el-checkbox
v-model="tooltipForm.showGap"
@change="changeTooltipAttr('showGap')"
/>
</el-form-item>
</div>
</el-form>
</el-col>