mirror of
https://github.com/dataease/dataease.git
synced 2026-05-14 04:12:11 +08:00
@@ -4,11 +4,14 @@ import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.dataease.api.chart.dto.PageInfo;
|
||||
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
|
||||
import io.dataease.chart.charts.impl.DefaultChartHandler;
|
||||
import io.dataease.constant.DeTypeConstants;
|
||||
import io.dataease.engine.constant.ExtFieldConstant;
|
||||
import io.dataease.engine.sql.SQLProvider;
|
||||
import io.dataease.engine.trans.Dimension2SQLObj;
|
||||
import io.dataease.engine.trans.ExtWhere2Str;
|
||||
import io.dataease.engine.trans.Quota2SQLObj;
|
||||
import io.dataease.engine.utils.Utils;
|
||||
import io.dataease.extensions.datasource.dto.DatasetTableFieldDTO;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceRequest;
|
||||
import io.dataease.extensions.datasource.dto.DatasourceSchemaDTO;
|
||||
import io.dataease.extensions.datasource.model.SQLMeta;
|
||||
@@ -16,9 +19,11 @@ import io.dataease.extensions.datasource.provider.Provider;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import io.dataease.extensions.view.util.ChartDataUtil;
|
||||
import io.dataease.extensions.view.util.FieldUtil;
|
||||
import io.dataease.utils.IDUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -110,7 +115,7 @@ public class TableNormalHandler extends DefaultChartHandler {
|
||||
|
||||
var tablePageMode = (String) filterResult.getContext().get("tablePageMode");
|
||||
var totalPageSql = "SELECT COUNT(*) FROM (" + SQLProvider.createQuerySQLNoSort(sqlMeta, true, view) + ") COUNT_TEMP";
|
||||
if (StringUtils.isNotEmpty(totalPageSql) && StringUtils.equalsIgnoreCase(tablePageMode, "page")) {
|
||||
if (StringUtils.equalsIgnoreCase(tablePageMode, "page")) {
|
||||
totalPageSql = provider.rebuildSQL(totalPageSql, sqlMeta, crossDs, dsMap);
|
||||
datasourceRequest.setQuery(totalPageSql);
|
||||
datasourceRequest.setTotalPageFlag(true);
|
||||
@@ -131,7 +136,6 @@ public class TableNormalHandler extends DefaultChartHandler {
|
||||
List<String[]> data = (List<String[]>) provider.fetchResultField(datasourceRequest).get("data");
|
||||
//自定义排序
|
||||
data = ChartDataUtil.resultCustomSort(xAxis, yAxis, view.getSortPriority(), data);
|
||||
|
||||
var yoyFiltered = filterResult.getContext().get("yoyFiltered") != null;
|
||||
if (yoyFiltered) {
|
||||
// 这里没加分页,因为加了分页参数可能会把原始数据挤出去
|
||||
@@ -208,6 +212,56 @@ public class TableNormalHandler extends DefaultChartHandler {
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// 自定义汇总
|
||||
var basicStyle = (Map<String, Object>) view.getCustomAttr().get("basicStyle");
|
||||
var showSummary = BooleanUtils.isTrue((Boolean) basicStyle.get("showSummary"));
|
||||
if (showSummary) {
|
||||
var fieldList = (List) basicStyle.get("seriesSummary");
|
||||
if (CollectionUtils.isNotEmpty(fieldList)) {
|
||||
var customCalcFields = new ArrayList<ChartViewFieldDTO>();
|
||||
var seriesList = JsonUtil.parseList(JsonUtil.toJSONString(fieldList).toString(), new TypeReference<List<ChartViewFieldDTO>>(){});
|
||||
seriesList.forEach(field -> {
|
||||
if (!BooleanUtils.isTrue(field.getShow()) || !"custom".equalsIgnoreCase(field.getSummary())) {
|
||||
return;
|
||||
}
|
||||
if (StringUtils.isBlank(field.getOriginName())) {
|
||||
return;
|
||||
}
|
||||
field.setSummary("");
|
||||
field.setDeType(DeTypeConstants.DE_FLOAT);
|
||||
field.setId(IDUtils.snowID());
|
||||
field.setExtField(ExtFieldConstant.EXT_CALC);
|
||||
customCalcFields.add(field);
|
||||
});
|
||||
if (!customCalcFields.isEmpty()) {
|
||||
var xFields = sqlMeta.getXFields();
|
||||
// 清空维度值,获取完结果再设置回去
|
||||
sqlMeta.setXFields(Collections.emptyList());
|
||||
List<DatasetTableFieldDTO> tmpList = FieldUtil.transFields(allFields);
|
||||
tmpList.addAll(customCalcFields);
|
||||
Quota2SQLObj.quota2sqlObj(sqlMeta, customCalcFields, tmpList, crossDs, dsMap, Utils.getParams(FieldUtil.transFields(allFields)), view.getCalParams(), pluginManage);
|
||||
String customSumSql = SQLProvider.createQuerySQL(sqlMeta, false, !StringUtils.equalsIgnoreCase(dsMap.values().iterator().next().getType(), "es"), view);
|
||||
customSumSql = provider.rebuildSQL(customSumSql, sqlMeta, crossDs, dsMap);
|
||||
var customSumReq = new DatasourceRequest();
|
||||
customSumReq.setIsCross(crossDs);
|
||||
customSumReq.setDsList(dsMap);
|
||||
customSumReq.setQuery(customSumSql);
|
||||
var customSumData = (List<String[]>) provider.fetchResultField(customSumReq).get("data");
|
||||
if (CollectionUtils.isNotEmpty(customSumData)) {
|
||||
var customSumResult = new HashMap<String, Double>();
|
||||
// 只取第一行结果
|
||||
var customSumArr = customSumData.get(0);
|
||||
for (int i = 0; i < customSumArr.length; i++) {
|
||||
if (customCalcFields.get(i) != null) {
|
||||
customSumResult.put(customCalcFields.get(i).getField(), Double.valueOf(customSumArr[i]));
|
||||
}
|
||||
}
|
||||
result.put("customSumResult", customSumResult);
|
||||
}
|
||||
sqlMeta.setXFields(xFields);
|
||||
}
|
||||
}
|
||||
}
|
||||
return calcResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,6 +306,7 @@ declare interface ChartBasicStyle {
|
||||
show: boolean
|
||||
field: string
|
||||
summary: string
|
||||
originName?: string
|
||||
}>
|
||||
/**
|
||||
* 符号地图符号大小最小值
|
||||
|
||||
@@ -33,6 +33,7 @@ declare interface Chart {
|
||||
tableRow: []
|
||||
}
|
||||
customCalc: any
|
||||
customSumResult?: Record<string, any>
|
||||
}
|
||||
xAxis?: Axis[]
|
||||
xAxisExt?: Axis[]
|
||||
|
||||
@@ -9,7 +9,6 @@ import YAxisSelector from '@/views/chart/components/editor/editor-style/componen
|
||||
import DualYAxisSelector from '@/views/chart/components/editor/editor-style/components/DualYAxisSelector.vue'
|
||||
import TitleSelector from '@/views/chart/components/editor/editor-style/components/TitleSelector.vue'
|
||||
import LegendSelector from '@/views/chart/components/editor/editor-style/components/LegendSelector.vue'
|
||||
import SummarySelector from '@/views/chart/components/editor/editor-style/components/SummarySelector.vue'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import CollapseSwitchItem from '@/components/collapse-switch-item/src/CollapseSwitchItem.vue'
|
||||
@@ -22,6 +21,7 @@ import BackgroundOverallCommon from '@/components/visualization/component-backgr
|
||||
import TableHeaderSelector from '@/views/chart/components/editor/editor-style/components/table/TableHeaderSelector.vue'
|
||||
import TableCellSelector from '@/views/chart/components/editor/editor-style/components/table/TableCellSelector.vue'
|
||||
import TableTotalSelector from '@/views/chart/components/editor/editor-style/components/table/TableTotalSelector.vue'
|
||||
import SummarySelector from '@/views/chart/components/editor/editor-style/components/table/SummarySelector.vue'
|
||||
import MiscStyleSelector from '@/views/chart/components/editor/editor-style/components/MiscStyleSelector.vue'
|
||||
import IndicatorValueSelector from '@/views/chart/components/editor/editor-style/components/IndicatorValueSelector.vue'
|
||||
import IndicatorNameSelector from '@/views/chart/components/editor/editor-style/components/IndicatorNameSelector.vue'
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { computed, onMounted, PropType, reactive, watch } from 'vue'
|
||||
import { computed, onMounted, PropType, reactive, watch, ref, nextTick, inject } from 'vue'
|
||||
import { DEFAULT_BASIC_STYLE } from '@/views/chart/components/editor/util/chart'
|
||||
import { cloneDeep, defaultsDeep, filter, find } from 'lodash-es'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import CustomAggrEdit from './CustomAggrEdit.vue'
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { batchOptStatus } = storeToRefs(dvMainStore)
|
||||
const { t } = useI18n()
|
||||
@@ -30,6 +32,7 @@ const state = reactive({
|
||||
show: boolean
|
||||
field: string
|
||||
summary: string
|
||||
originName?: string
|
||||
}
|
||||
})
|
||||
|
||||
@@ -37,7 +40,12 @@ const emit = defineEmits(['onBasicStyleChange'])
|
||||
const changeBasicStyle = (prop?: string, requestData = false) => {
|
||||
emit('onBasicStyleChange', { data: state.basicStyleForm, requestData }, prop)
|
||||
}
|
||||
|
||||
const changeSummaryType = () => {
|
||||
if (state.currentAxisSummary.summary === 'custom' && !state.currentAxisSummary.originName) {
|
||||
return
|
||||
}
|
||||
changeBasicStyle('seriesSummary')
|
||||
}
|
||||
watch(
|
||||
[
|
||||
() => props.chart.customAttr.basicStyle.showSummary,
|
||||
@@ -65,15 +73,38 @@ const summaryTypes = [
|
||||
{ key: 'sum', name: t('chart.sum') },
|
||||
{ key: 'avg', name: t('chart.avg') },
|
||||
{ key: 'max', name: t('chart.max') },
|
||||
{ key: 'min', name: t('chart.min') }
|
||||
// { key: 'stddev_pop', name: t('chart.stddev_pop') },
|
||||
// { key: 'var_pop', name: t('chart.var_pop') }
|
||||
{ key: 'min', name: t('chart.min') },
|
||||
{ key: 'custom', name: t('commons.custom') }
|
||||
]
|
||||
|
||||
function onSelectAxis(value) {
|
||||
state.currentAxisSummary = find(state.basicStyleForm.seriesSummary, s => s.field === value)
|
||||
}
|
||||
|
||||
const calcEdit = ref()
|
||||
const editCalcField = ref(false)
|
||||
const dimension = inject('dimension', () => [])
|
||||
const quota = inject('quota', () => [])
|
||||
const editField = () => {
|
||||
editCalcField.value = true
|
||||
nextTick(() => {
|
||||
calcEdit.value.initEdit(
|
||||
state.currentAxisSummary,
|
||||
quota().filter(ele => ele.id !== '-1')
|
||||
)
|
||||
})
|
||||
}
|
||||
const closeEditCalc = () => {
|
||||
editCalcField.value = false
|
||||
}
|
||||
const confirmEditCalc = () => {
|
||||
calcEdit.value.setFieldForm()
|
||||
const obj = cloneDeep(calcEdit.value.fieldForm)
|
||||
state.currentAxisSummary.originName = obj.originName
|
||||
setFieldDefaultValue(state.currentAxisSummary)
|
||||
closeEditCalc()
|
||||
changeSummaryType()
|
||||
}
|
||||
const init = () => {
|
||||
const basicStyle = cloneDeep(props.chart.customAttr.basicStyle)
|
||||
|
||||
@@ -112,7 +143,14 @@ const init = () => {
|
||||
state.currentAxisSummary = undefined
|
||||
}
|
||||
}
|
||||
|
||||
const setFieldDefaultValue = field => {
|
||||
field.extField = 2
|
||||
field.chartId = props.chart.id
|
||||
field.datasetGroupId = props.chart.tableId
|
||||
field.lastSyncTime = null
|
||||
field.columnIndex = dimension().length + quota().length
|
||||
field.deExtractType = field.deType
|
||||
}
|
||||
onMounted(() => {
|
||||
init()
|
||||
})
|
||||
@@ -173,21 +211,41 @@ onMounted(() => {
|
||||
|
||||
<div class="indented-container">
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||
<el-select
|
||||
v-model="state.currentAxisSummary.summary"
|
||||
:class="'form-item-' + themes"
|
||||
class="form-item"
|
||||
:effect="themes"
|
||||
:disabled="!state.currentAxisSummary.show"
|
||||
@change="changeBasicStyle('seriesSummary')"
|
||||
>
|
||||
<el-option v-for="c in summaryTypes" :key="c.key" :value="c.key" :label="c.name" />
|
||||
</el-select>
|
||||
<el-col :span="state.currentAxisSummary.summary === 'custom' ? 19 : 22" :offset="2">
|
||||
<el-select
|
||||
v-model="state.currentAxisSummary.summary"
|
||||
:class="'form-item-' + themes"
|
||||
class="form-item"
|
||||
:effect="themes"
|
||||
:disabled="!state.currentAxisSummary.show"
|
||||
@change="changeSummaryType"
|
||||
>
|
||||
<el-option v-for="c in summaryTypes" :key="c.key" :value="c.key" :label="c.name" />
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col v-if="state.currentAxisSummary.summary === 'custom'" :span="2" :offset="1">
|
||||
<el-icon style="cursor: pointer">
|
||||
<Setting @click="editField()" />
|
||||
</el-icon>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</template>
|
||||
</el-form>
|
||||
</div>
|
||||
<!--图表计算字段-->
|
||||
<el-dialog
|
||||
v-model="editCalcField"
|
||||
width="1000px"
|
||||
title="自定义总计"
|
||||
:close-on-click-modal="false"
|
||||
>
|
||||
<custom-aggr-edit ref="calcEdit" />
|
||||
<template #footer>
|
||||
<el-button secondary @click="closeEditCalc()">{{ t('dataset.cancel') }} </el-button>
|
||||
<el-button type="primary" @click="confirmEditCalc()">{{ t('dataset.confirm') }} </el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -354,7 +354,12 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
s2Options.style.rowCfg = { heightByField }
|
||||
// 计算汇总加入到数据里,冻结最后一行
|
||||
s2Options.frozenTrailingRowCount = 1
|
||||
const summaryObj = getSummaryRow(data, yAxis, basicStyle.seriesSummary) as any
|
||||
const summaryObj = getSummaryRow(
|
||||
data,
|
||||
yAxis,
|
||||
basicStyle.seriesSummary,
|
||||
chart.data.customSumResult
|
||||
) as any
|
||||
data.push(summaryObj)
|
||||
}
|
||||
s2Options.dataCell = viewMeta => {
|
||||
|
||||
@@ -2389,7 +2389,7 @@ const getWrapTextHeight = (wrapText, textStyle, spreadsheet, maxLines) => {
|
||||
}
|
||||
|
||||
// 导出获取汇总行的函数
|
||||
export function getSummaryRow(data, axis, sumCon = []) {
|
||||
export function getSummaryRow(data, axis, sumCon = [], customSumResult = {}) {
|
||||
const summaryObj = { SUMMARY: true }
|
||||
for (let i = 0; i < axis.length; i++) {
|
||||
const a = axis[i].dataeaseName
|
||||
@@ -2473,6 +2473,9 @@ export function getSummaryRow(data, axis, sumCon = []) {
|
||||
.toNumber() // 计算总体标准差
|
||||
}
|
||||
break
|
||||
case 'custom':
|
||||
summaryObj[a] = customSumResult[a]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package io.dataease.extensions.view.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonGetter;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
@@ -34,4 +36,11 @@ public class ChartViewFieldDTO extends ChartViewFieldBaseDTO implements Serializ
|
||||
*/
|
||||
@JsonIgnore
|
||||
private FieldSource source;
|
||||
|
||||
/**
|
||||
* 显隐
|
||||
*/
|
||||
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
|
||||
private Boolean show;
|
||||
private String field;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user