diff --git a/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java b/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java index 2d90dfbcbf..221ff0d218 100644 --- a/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java +++ b/backend/src/main/java/io/dataease/dto/chart/ChartViewFieldDTO.java @@ -44,4 +44,6 @@ public class ChartViewFieldDTO implements Serializable { private String datePattern; private Integer extField; + + private String chartType; } diff --git a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java index 206eaf5eee..db33b148e6 100644 --- a/backend/src/main/java/io/dataease/service/chart/ChartViewService.java +++ b/backend/src/main/java/io/dataease/service/chart/ChartViewService.java @@ -427,6 +427,8 @@ public class ChartViewService { } else if (StringUtils.containsIgnoreCase(view.getType(), "text") || StringUtils.containsIgnoreCase(view.getType(), "gauge")) { mapChart = transNormalChartData(xAxis, yAxis, view, data, isDrill); + } else if (StringUtils.containsIgnoreCase(view.getType(), "chart-mix")) { + mapChart = transMixChartData(xAxis, yAxis, view, data, isDrill); } else { mapChart = transChartData(xAxis, yAxis, view, data, isDrill); } @@ -561,6 +563,67 @@ public class ChartViewService { return map; } + // 组合图形 + private Map transMixChartData(List xAxis, List yAxis, ChartViewWithBLOBs 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(y.getChartType()); + series1.setData(new ArrayList<>()); + series.add(series1); + } + for (int i1 = 0; i1 < data.size(); i1++) { + String[] d = data.get(i1); + + StringBuilder a = new StringBuilder(); + for (int i = xAxis.size(); i < xAxis.size() + yAxis.size(); i++) { + 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]); + dimensionList.add(chartDimensionDTO); + } + axisChartDataDTO.setDimensionList(dimensionList); + + int j = i - xAxis.size(); + ChartQuotaDTO chartQuotaDTO = new ChartQuotaDTO(); + chartQuotaDTO.setId(yAxis.get(j).getId()); + quotaList.add(chartQuotaDTO); + axisChartDataDTO.setQuotaList(quotaList); + try { + axisChartDataDTO.setValue(new BigDecimal(StringUtils.isEmpty(d[i]) ? "0" : d[i])); + } catch (Exception e) { + axisChartDataDTO.setValue(new BigDecimal(0)); + } + series.get(j).getData().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); + return map; + } + // 常规图形 private Map transNormalChartData(List xAxis, List yAxis, ChartViewWithBLOBs view, List data, boolean isDrill) { Map map = new HashMap<>(); diff --git a/frontend/src/icons/svg/chart-mix.svg b/frontend/src/icons/svg/chart-mix.svg new file mode 100644 index 0000000000..b9f42e5e71 --- /dev/null +++ b/frontend/src/icons/svg/chart-mix.svg @@ -0,0 +1 @@ + diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 6c1cf3590d..84bd044f92 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -848,7 +848,8 @@ export default { system_case: 'System', custom_case: 'Custom', last_layer: 'This Is The Last Layer', - radar_size: 'Size' + radar_size: 'Size', + chart_mix: 'Mix' }, dataset: { sheet_warn: 'There are multiple sheet pages, and the first one is extracted by default', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index 7067972a8a..53387d65b8 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -847,7 +847,8 @@ export default { system_case: '系統方案', custom_case: '自定義', last_layer: '當前已經是最後一級', - radar_size: '大小' + radar_size: '大小', + chart_mix: '組合圖' }, dataset: { sheet_warn: '有多個sheet頁面,默認抽取第一個', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index b8bdc5c0f5..804bf19ee3 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -847,7 +847,8 @@ export default { system_case: '系统方案', custom_case: '自定义', last_layer: '当前已经是最后一级', - radar_size: '大小' + radar_size: '大小', + chart_mix: '组合图' }, dataset: { sheet_warn: '有多个 Sheet 页,默认抽取第一个', diff --git a/frontend/src/views/chart/chart/common/common.js b/frontend/src/views/chart/chart/common/common.js index e1e496e758..44a942b3a9 100644 --- a/frontend/src/views/chart/chart/common/common.js +++ b/frontend/src/views/chart/chart/common/common.js @@ -51,7 +51,7 @@ export function componentStyle(chart_option, chart) { chart_option.legend.icon = customStyle.legend.icon chart_option.legend.textStyle = customStyle.legend.textStyle } - if (customStyle.xAxis && (chart.type.includes('bar') || chart.type.includes('line') || chart.type.includes('scatter'))) { + if (customStyle.xAxis && (chart.type.includes('bar') || chart.type.includes('line') || chart.type.includes('scatter') || chart.type === 'chart-mix')) { chart_option.xAxis.show = customStyle.xAxis.show chart_option.xAxis.position = customStyle.xAxis.position chart_option.xAxis.name = customStyle.xAxis.name @@ -61,8 +61,12 @@ export function componentStyle(chart_option, chart) { chart_option.xAxis.axisLabel.showMaxLabel = true chart_option.xAxis.axisLabel.showMinLabel = true + + if (!customStyle.xAxis.show) { + chart_option.xAxis.axisLabel.show = false + } } - if (customStyle.yAxis && (chart.type.includes('bar') || chart.type.includes('line') || chart.type.includes('scatter'))) { + if (customStyle.yAxis && (chart.type.includes('bar') || chart.type.includes('line') || chart.type.includes('scatter') || chart.type === 'chart-mix')) { chart_option.yAxis.show = customStyle.yAxis.show chart_option.yAxis.position = customStyle.yAxis.position chart_option.yAxis.name = customStyle.yAxis.name @@ -70,8 +74,12 @@ export function componentStyle(chart_option, chart) { chart_option.yAxis.splitLine = customStyle.yAxis.splitLine chart_option.yAxis.nameTextStyle = customStyle.yAxis.nameTextStyle - chart_option.xAxis.axisLabel.showMaxLabel = true - chart_option.xAxis.axisLabel.showMinLabel = true + chart_option.yAxis.axisLabel.showMaxLabel = true + chart_option.yAxis.axisLabel.showMinLabel = true + + if (!customStyle.yAxis.show) { + chart_option.yAxis.axisLabel.show = false + } } if (customStyle.split && chart.type.includes('radar')) { chart_option.radar.name = customStyle.split.name diff --git a/frontend/src/views/chart/chart/mix/mix.js b/frontend/src/views/chart/chart/mix/mix.js new file mode 100644 index 0000000000..9237249e76 --- /dev/null +++ b/frontend/src/views/chart/chart/mix/mix.js @@ -0,0 +1,73 @@ +import { hexColorToRGBA } from '@/views/chart/chart/util' +import { componentStyle } from '../common/common' + +export function baseMixOption(chart_option, chart) { + // 处理shape attr + let customAttr = {} + if (chart.customAttr) { + customAttr = JSON.parse(chart.customAttr) + if (customAttr.color) { + chart_option.color = customAttr.color.colors + } + // tooltip + if (customAttr.tooltip) { + const tooltip = JSON.parse(JSON.stringify(customAttr.tooltip)) + const reg = new RegExp('\n', 'g') + tooltip.formatter = tooltip.formatter.replace(reg, '
') + chart_option.tooltip = tooltip + } + } + // 处理data + if (chart.data) { + chart_option.title.text = chart.title + chart_option.xAxis.data = chart.data.x + for (let i = 0; i < chart.data.series.length; i++) { + const y = chart.data.series[i] + y.type = y.type ? y.type : 'bar' + // color + y.itemStyle = { + color: hexColorToRGBA(customAttr.color.colors[i % 9], customAttr.color.alpha) + } + // size + if (customAttr.size) { + // bar + if (y.type === 'bar') { + if (customAttr.size.barDefault) { + y.barWidth = null + y.barGap = null + } else { + y.barWidth = customAttr.size.barWidth + y.barGap = customAttr.size.barGap + } + } + // line + if (y.type === 'line') { + y.symbol = customAttr.size.lineSymbol + y.symbolSize = customAttr.size.lineSymbolSize + y.lineStyle = { + width: customAttr.size.lineWidth, + type: customAttr.size.lineType + } + y.smooth = customAttr.size.lineSmooth + y.areaStyle = { + opacity: customAttr.size.lineArea ? 0.6 : 0 + } + } + // scatter + if (y.type === 'scatter') { + y.symbol = customAttr.size.scatterSymbol ? customAttr.size.scatterSymbol : 'circle' + y.symbolSize = customAttr.size.scatterSymbolSize ? customAttr.size.scatterSymbolSize : 20 + } + } + // label + if (customAttr.label) { + y.label = customAttr.label + } + chart_option.legend.data.push(y.name) + chart_option.series.push(y) + } + } + // console.log(chart_option); + componentStyle(chart_option, chart) + return chart_option +} diff --git a/frontend/src/views/chart/components/ChartComponent.vue b/frontend/src/views/chart/components/ChartComponent.vue index 7429daa706..8b2463aff9 100644 --- a/frontend/src/views/chart/components/ChartComponent.vue +++ b/frontend/src/views/chart/components/ChartComponent.vue @@ -6,7 +6,18 @@