diff --git a/core/core-frontend/src/views/chart/components/editor/editor-style/components/MiscSelector.vue b/core/core-frontend/src/views/chart/components/editor/editor-style/components/MiscSelector.vue index 9840040bf5..2002ed3146 100644 --- a/core/core-frontend/src/views/chart/components/editor/editor-style/components/MiscSelector.vue +++ b/core/core-frontend/src/views/chart/components/editor/editor-style/components/MiscSelector.vue @@ -3,7 +3,7 @@ import icon_info_outlined from '@/assets/svg/icon_info_outlined.svg' import { computed, onMounted, reactive, watch } from 'vue' import { useI18n } from '@/hooks/web/useI18n' import { DEFAULT_MISC } from '@/views/chart/components/editor/util/chart' -import { ElMessage, ElRow } from 'element-plus-secondary' +import { ElRow } from 'element-plus-secondary' import { fieldType } from '@/utils/attr' import { cloneDeep, defaultsDeep } from 'lodash-es' import { useEmitt } from '@/hooks/web/useEmitt' @@ -25,6 +25,14 @@ useEmitt({ name: 'word-cloud-default-data-range', callback: args => wordCloudDefaultDataRange(args) }) +useEmitt({ + name: 'gauge-default-data', + callback: args => gaugeDefaultDataRange(args) +}) +useEmitt({ + name: 'liquid-default-data', + callback: args => gaugeDefaultDataRange(args) +}) const emit = defineEmits(['onMiscChange']) watch( @@ -59,7 +67,10 @@ const state = reactive({ minField: {}, maxField: {}, liquidMaxField: {}, - quotaData: [] + quotaData: [], + // 是否已处理没有 y 轴字段的情况 + liquidProcessedNoYAxis: false, + gaugeProcessedNoYAxis: false }) const liquidShapeOptions = [ @@ -71,9 +82,6 @@ const liquidShapeOptions = [ ] const changeMisc = (prop = '', refresh = false) => { - if (state.miscForm.gaugeMax <= state.miscForm.gaugeMin) { - ElMessage.error(t('chart.max_more_than_mix')) - } emit('onMiscChange', { data: state.miscForm, requestData: refresh }, prop) } @@ -93,13 +101,93 @@ const initField = () => { if (state.miscForm.liquidMaxField.id) { state.liquidMaxField = getQuotaField(state.miscForm.liquidMaxField.id) } + initDynamicDefaultField() +} + +const initDynamicDefaultField = () => { + if (state.quotaData.length > 0) { + // 查找 quotaData 中是否存在 chart.yAxis[0].id + const yAxisId = props.chart.yAxis?.[0]?.id + const yAxisExists = state.quotaData.find(ele => ele.id === yAxisId) + // 如果不存在 + if (!yAxisExists && (state.miscForm.liquidMaxField.id || state.miscForm.gaugeMaxField.id)) { + if (props.chart.type === 'liquid' && !state.liquidProcessedNoYAxis) { + state.liquidProcessedNoYAxis = true + state.miscForm.liquidMaxField.id = '' + state.miscForm.liquidMaxField.summary = '' + state.liquidMaxField = getQuotaField(state.miscForm.liquidMaxField.id) + changeMisc('liquidMaxField', false) + } else { + if (!state.gaugeProcessedNoYAxis) { + state.gaugeProcessedNoYAxis = true + state.miscForm.gaugeMaxField.id = '' + state.miscForm.gaugeMaxField.summary = '' + state.maxField = {} + changeMisc('gaugeMaxField', false) + } + } + } else { + if (props.chart.type === 'liquid') { + if (state.miscForm.liquidMaxType === 'dynamic') { + state.miscForm.liquidMax = undefined + // 查找 quotaData 中是否存在 liquidMaxField.id + const liquidMaxFieldExists = state.quotaData.find( + ele => ele.id === state.miscForm.liquidMaxField.id + ) + if (!liquidMaxFieldExists) { + if (yAxisId) { + state.liquidProcessedNoYAxis = false + // 根据查找结果设置 liquidMaxField.id + state.miscForm.liquidMaxField.id = yAxisExists ? yAxisId : state.quotaData[0]?.id + // 设置 summary 和 maxField + state.miscForm.liquidMaxField.summary = 'sum' + state.maxField = getQuotaField(state.miscForm.liquidMaxField.id) + // 触发 changeMisc 事件 + if (yAxisExists) { + changeMisc('liquidMaxField', true) + } + } + } + } + if (!state.miscForm.liquidMax && state.miscForm.liquidMaxType === 'fix') { + state.miscForm.liquidMax = cloneDeep(defaultMaxValue.liquidMax) + } + } else { + if (state.miscForm.gaugeMaxType === 'dynamic') { + state.miscForm.gaugeMax = undefined + + // 查找 quotaData 中是否存在 gaugeMaxField.id + const gaugeMaxFieldExists = state.quotaData.find( + ele => ele.id === state.miscForm.gaugeMaxField.id + ) + if (!gaugeMaxFieldExists) { + if (yAxisId) { + state.gaugeProcessedNoYAxis = false + // 根据查找结果设置 gaugeMaxField.id + state.miscForm.gaugeMaxField.id = yAxisExists ? yAxisId : state.quotaData[0]?.id + // 设置 summary 和 maxField + state.miscForm.gaugeMaxField.summary = 'sum' + state.maxField = getQuotaField(state.miscForm.gaugeMaxField.id) + if (yAxisExists) { + // 触发 changeMisc 事件 + changeMisc('gaugeMaxField', true) + } + } + } + } + if (!state.miscForm.gaugeMax && state.miscForm.gaugeMaxType === 'fix') { + state.miscForm.gaugeMax = cloneDeep(defaultMaxValue.gaugeMax) + } + } + } + } } const changeQuotaField = (type: string, resetSummary?: boolean) => { if (type === 'min') { if (state.miscForm.gaugeMinType === 'dynamic') { if (!state.miscForm.gaugeMinField.id) { - state.miscForm.gaugeMinField.id = state.quotaData[0]?.id + state.miscForm.gaugeMinField.id = props.chart.yAxis?.[0]?.id } if (!state.miscForm.gaugeMinField.summary) { state.miscForm.gaugeMinField.summary = 'count' @@ -122,14 +210,21 @@ const changeQuotaField = (type: string, resetSummary?: boolean) => { } } else if (type === 'max') { if (props.chart.type === 'liquid') { + if (state.miscForm.liquidMaxType === 'dynamic') { + state.miscForm.liquidMax = undefined + } else { + if (!state.miscForm.liquidMax) { + state.miscForm.liquidMax = cloneDeep(defaultMaxValue.liquidMax) + } + } if (!state.miscForm.liquidMaxField.id) { - state.miscForm.liquidMaxField.id = state.quotaData[0]?.id + state.miscForm.liquidMaxField.id = props.chart.yAxis?.[0]?.id } if (!state.miscForm.liquidMaxField.summary) { - state.miscForm.liquidMaxField.summary = 'count' + state.miscForm.liquidMaxField.summary = 'sum' } if (resetSummary) { - state.miscForm.liquidMaxField.summary = 'count' + state.miscForm.liquidMaxField.summary = 'sum' } if (state.miscForm.liquidMaxField.id && state.miscForm.liquidMaxField.summary) { state.maxField = getQuotaField(state.miscForm.liquidMaxField.id) @@ -137,20 +232,24 @@ const changeQuotaField = (type: string, resetSummary?: boolean) => { } } else { if (state.miscForm.gaugeMaxType === 'dynamic') { + state.miscForm.gaugeMax = undefined if (!state.miscForm.gaugeMaxField.id) { - state.miscForm.gaugeMaxField.id = state.quotaData[0]?.id + state.miscForm.gaugeMaxField.id = props.chart.yAxis?.[0]?.id } if (!state.miscForm.gaugeMaxField.summary) { - state.miscForm.gaugeMaxField.summary = 'count' + state.miscForm.gaugeMaxField.summary = 'sum' } if (resetSummary) { - state.miscForm.gaugeMaxField.summary = 'count' + state.miscForm.gaugeMaxField.summary = 'sum' } if (state.miscForm.gaugeMaxField.id && state.miscForm.gaugeMaxField.summary) { state.maxField = getQuotaField(state.miscForm.gaugeMaxField.id) changeMisc('gaugeMaxField', true) } } else { + if (!state.miscForm.gaugeMax) { + state.miscForm.gaugeMax = cloneDeep(defaultMaxValue.gaugeMax) + } if (state.miscForm.gaugeMinType === 'dynamic') { if (state.miscForm.gaugeMinField.id && state.miscForm.gaugeMinField.summary) { changeMisc('gaugeMaxField', true) @@ -187,6 +286,39 @@ const wordCloudDefaultDataRange = args => { state.miscForm.wordCloudAxisValueRange.min = args.data.min state.miscForm.wordCloudAxisValueRange.fieldId = props.chart.yAxis?.[0]?.id } +const defaultMaxValue = { + gaugeMax: undefined, + liquidMax: undefined +} +const gaugeDefaultDataRange = args => { + if (args.data.type === 'gauge') { + defaultMaxValue.gaugeMax = cloneDeep(args.data.max) + if (!state.miscForm.gaugeMax) { + state.miscForm.gaugeMax = cloneDeep(defaultMaxValue.gaugeMax) + } + } + if (args.data.type === 'liquid') { + defaultMaxValue.liquidMax = cloneDeep(args.data.max) + if (!state.miscForm.liquidMax) { + state.miscForm.liquidMax = cloneDeep(defaultMaxValue.liquidMax) + } + } +} +/** + * 校验最大值的输入 + */ +const changeMaxValidate = prop => { + if (prop === 'gaugeMax') { + if (!state.miscForm.gaugeMax) { + state.miscForm.gaugeMax = cloneDeep(defaultMaxValue.gaugeMax) + } + } else { + if (!state.miscForm.liquidMax) { + state.miscForm.liquidMax = cloneDeep(defaultMaxValue.liquidMax) + } + } + changeMisc(prop) +} onMounted(() => { initField() init() @@ -357,7 +489,7 @@ onMounted(() => { v-model="state.miscForm.gaugeMax" size="small" controls-position="right" - @change="changeMisc('gaugeMax')" + @blur="changeMaxValidate('gaugeMax')" /> { :min="1" size="small" controls-position="right" - @change="changeMisc('liquidMax')" + @blur="changeMaxValidate('liquidMax')" /> diff --git a/core/core-frontend/src/views/chart/components/editor/util/chart.ts b/core/core-frontend/src/views/chart/components/editor/util/chart.ts index e05d565426..650bb1058e 100644 --- a/core/core-frontend/src/views/chart/components/editor/util/chart.ts +++ b/core/core-frontend/src/views/chart/components/editor/util/chart.ts @@ -232,12 +232,12 @@ export const DEFAULT_MISC: ChartMiscAttr = { summary: '' }, gaugeMin: 0, - gaugeMaxType: 'fix', + gaugeMaxType: 'dynamic', gaugeMaxField: { id: '', summary: '' }, - gaugeMax: 1, + gaugeMax: undefined, gaugeStartAngle: 225, gaugeEndAngle: -45, nameFontSize: 18, @@ -258,8 +258,8 @@ export const DEFAULT_MISC: ChartMiscAttr = { nameFontShadow: false, treemapWidth: 80, treemapHeight: 80, - liquidMax: 1, - liquidMaxType: 'fix', + liquidMax: undefined, + liquidMaxType: 'dynamic', liquidMaxField: { id: '', summary: '' diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/liquid/liquid.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/liquid/liquid.ts index 53524a18ee..2525383284 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/liquid/liquid.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/liquid/liquid.ts @@ -53,8 +53,8 @@ export class Liquid extends G2PlotChartView { } async drawChart(drawOptions: G2PlotDrawOptions): Promise { - const { chart, container } = drawOptions - if (!chart.data?.series) { + const { chart, container, action } = drawOptions + if (!chart.data?.series || !chart.yAxis.length) { return } const initOptions: LiquidOptions = { @@ -62,8 +62,17 @@ export class Liquid extends G2PlotChartView { } const options = this.setupOptions(chart, initOptions) const { Liquid: G2Liquid } = await import('@antv/g2plot/esm/plots/liquid') - // 开始渲染 - return new G2Liquid(container, options) + const newChart = new G2Liquid(container, options) + newChart.on('afterrender', () => { + action({ + from: 'liquid', + data: { + type: 'liquid', + max: chart.data?.series[chart.data?.series.length - 1]?.data[0] + } + }) + }) + return newChart } protected configTheme(chart: Chart, options: LiquidOptions): LiquidOptions { @@ -100,10 +109,11 @@ export class Liquid extends G2PlotChartView { let max, radius, shape if (customAttr.misc) { const misc = customAttr.misc + const defaultLiquidMax = chart.data?.series[chart.data?.series.length - 1]?.data[0] if (misc.liquidMaxType === 'dynamic') { - max = chart.data?.series[chart.data?.series.length - 1]?.data[0] + max = defaultLiquidMax } else { - max = misc.liquidMax ? misc.liquidMax : DEFAULT_MISC.liquidMax + max = misc.liquidMax ? misc.liquidMax : defaultLiquidMax } radius = (misc.liquidSize ? misc.liquidSize : DEFAULT_MISC.liquidSize) / 100 shape = misc.liquidShape ?? DEFAULT_MISC.liquidShape diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/others/gauge.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/others/gauge.ts index 36cd77b799..ec6f35f207 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/others/gauge.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/others/gauge.ts @@ -67,8 +67,8 @@ export class Gauge extends G2PlotChartView { } async drawChart(drawOptions: G2PlotDrawOptions): Promise { - const { chart, container, scale } = drawOptions - if (!chart.data?.series) { + const { chart, container, scale, action } = drawOptions + if (!chart.data?.series || !chart.yAxis.length) { return } // options @@ -99,7 +99,17 @@ export class Gauge extends G2PlotChartView { } const options = this.setupOptions(chart, initOptions, { scale }) const { Gauge: G2Gauge } = await import('@antv/g2plot/esm/plots/gauge') - return new G2Gauge(container, options) + const newChart = new G2Gauge(container, options) + newChart.on('afterrender', () => { + action({ + from: 'gauge', + data: { + type: 'gauge', + max: chart.data?.series[chart.data?.series.length - 1]?.data[0] + } + }) + }) + return newChart } protected configMisc( @@ -116,13 +126,13 @@ export class Gauge extends G2PlotChartView { min = chart.data?.series[chart.data?.series.length - 2]?.data[0] max = chart.data?.series[chart.data?.series.length - 1]?.data[0] } else if (misc.gaugeMinType !== 'dynamic' && misc.gaugeMaxType === 'dynamic') { - min = misc.gaugeMin ? misc.gaugeMin : DEFAULT_MISC.gaugeMin + min = misc.gaugeMin || misc.gaugeMin === 0 ? misc.gaugeMin : DEFAULT_MISC.gaugeMin max = chart.data?.series[chart.data?.series.length - 1]?.data[0] } else if (misc.gaugeMinType === 'dynamic' && misc.gaugeMaxType !== 'dynamic') { min = chart.data?.series[chart.data?.series.length - 1]?.data[0] max = misc.gaugeMax ? misc.gaugeMax : DEFAULT_MISC.gaugeMax } else { - min = misc.gaugeMin ? misc.gaugeMin : DEFAULT_MISC.gaugeMin + min = misc.gaugeMin || misc.gaugeMin === 0 ? misc.gaugeMin : DEFAULT_MISC.gaugeMin max = misc.gaugeMax ? misc.gaugeMax : DEFAULT_MISC.gaugeMax } startAngle = (misc.gaugeStartAngle * Math.PI) / 180 diff --git a/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue b/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue index dfb4f1650e..35174072d9 100644 --- a/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue +++ b/core/core-frontend/src/views/chart/components/views/components/ChartComponentG2Plot.vue @@ -317,13 +317,24 @@ const pointClickTrans = () => { } } -const action = param => { +const actionDefault = param => { if (param.from === 'map') { emitter.emit('map-default-range', param) - return } if (param.from === 'word-cloud') { emitter.emit('word-cloud-default-data-range', param) + } + if (param.from === 'gauge') { + emitter.emit('gauge-default-data', param) + } + if (param.from === 'liquid') { + emitter.emit('liquid-default-data', param) + } +} + +const action = param => { + if (param.from) { + actionDefault(param) return } state.pointParam = param.data