From 5330197a11ea70ae713c694f7e2588aa720ff1bf Mon Sep 17 00:00:00 2001 From: jianneng-fit2cloud Date: Thu, 4 Jun 2026 10:33:15 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix(=E5=9B=BE=E8=A1=A8):=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=95=B0=E5=80=BC=E6=A0=BC=E5=BC=8F=E5=8C=96=E9=81=87?= =?UTF-8?q?=E5=88=B0=E7=A7=91=E5=AD=A6=E8=AE=A1=E6=95=B0=E6=B3=95=E6=97=B6?= =?UTF-8?q?=EF=BC=8C=E6=95=B0=E5=80=BC=E6=97=A0=E6=B3=95=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=A0=BC=E5=BC=8F=E5=8C=96=E6=98=BE=E7=A4=BA=E7=A9=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/core-frontend/src/views/chart/components/js/formatter.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/core/core-frontend/src/views/chart/components/js/formatter.ts b/core/core-frontend/src/views/chart/components/js/formatter.ts index 729407f5e0..a6ec55349d 100644 --- a/core/core-frontend/src/views/chart/components/js/formatter.ts +++ b/core/core-frontend/src/views/chart/components/js/formatter.ts @@ -110,6 +110,10 @@ function retain(value, n) { if (!n) return Math.round(value) const tran = Math.round(value * Math.pow(10, n)) / Math.pow(10, n) let tranV = tran.toString() + // 遇到科学计数法时用 toFixed(n) 转成普通小数字符串 + if (/e/i.test(tranV)) { + tranV = tran.toFixed(n) + } const newVal = tranV.indexOf('.') if (newVal < 0) { tranV += '.' From 7b4f4b24f374bd21a92c5e0461176e8c2d248de1 Mon Sep 17 00:00:00 2001 From: dataeaseShu Date: Thu, 4 Jun 2026 10:47:01 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat(=E6=9F=A5=E8=AF=A2=E7=BB=84=E4=BB=B6):?= =?UTF-8?q?=20add=20last-month=20full-range=20dynamic=20option?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../v-query/DynamicTimeFiltering.vue | 2 +- .../v-query/DynamicTimeRangeFiltering.vue | 4 +- .../v-query/RangeFilterTime.vue | 39 ++++++++++++++++--- .../v-query/time-format-dayjs.ts | 2 + .../custom-component/v-query/time-format.ts | 3 +- core/core-frontend/src/locales/en.ts | 1 + core/core-frontend/src/locales/tw.ts | 1 + core/core-frontend/src/locales/zh-CN.ts | 1 + 8 files changed, 44 insertions(+), 9 deletions(-) diff --git a/core/core-frontend/src/custom-component/v-query/DynamicTimeFiltering.vue b/core/core-frontend/src/custom-component/v-query/DynamicTimeFiltering.vue index 62e53255e5..fd7f7528c7 100644 --- a/core/core-frontend/src/custom-component/v-query/DynamicTimeFiltering.vue +++ b/core/core-frontend/src/custom-component/v-query/DynamicTimeFiltering.vue @@ -6,7 +6,7 @@ import type { ManipulateType } from 'dayjs' import { getThisStart, getThisEnd, getLastStart, getAroundStart } from './time-format-dayjs' interface SelectConfig { intervalType: string - regularOrTrendsValue: Date + regularOrTrendsValue: string | Date | [Date, Date] regularOrTrends: string relativeToCurrent: string timeNum: number diff --git a/core/core-frontend/src/custom-component/v-query/DynamicTimeRangeFiltering.vue b/core/core-frontend/src/custom-component/v-query/DynamicTimeRangeFiltering.vue index c85845b551..5e4f8cb2ea 100644 --- a/core/core-frontend/src/custom-component/v-query/DynamicTimeRangeFiltering.vue +++ b/core/core-frontend/src/custom-component/v-query/DynamicTimeRangeFiltering.vue @@ -6,13 +6,13 @@ import type { ManipulateType } from 'dayjs' import { getAround, getCustomRange, getAroundStart } from './time-format-dayjs' interface SelectConfig { regularOrTrends: string - regularOrTrendsValue: [Date, Date] + regularOrTrendsValue: string | Date | [Date, Date] intervalType: string relativeToCurrentRange: string timeNum: number relativeToCurrentType: ManipulateType around: string - timeGranularity: DatePickType + timeGranularity?: DatePickType timeNumRange: number relativeToCurrentTypeRange: ManipulateType aroundRange: string diff --git a/core/core-frontend/src/custom-component/v-query/RangeFilterTime.vue b/core/core-frontend/src/custom-component/v-query/RangeFilterTime.vue index 163af40690..f215783953 100644 --- a/core/core-frontend/src/custom-component/v-query/RangeFilterTime.vue +++ b/core/core-frontend/src/custom-component/v-query/RangeFilterTime.vue @@ -5,6 +5,27 @@ import { useI18n } from '@/hooks/web/useI18n' import DynamicTime from './DynamicTimeFiltering.vue' import DynamicTimeRange from './DynamicTimeRangeFiltering.vue' import { ManipulateType } from 'dayjs' +import { type DatePickType } from 'element-plus-secondary' + +type OptionItem = { + label: string + value: string +} + +type DynamicConfig = { + regularOrTrends: string + regularOrTrendsValue: string | Date | [Date, Date] + intervalType: string + relativeToCurrent: string + relativeToCurrentRange: string + timeNum: number + relativeToCurrentType: ManipulateType + around: string + timeNumRange: number + relativeToCurrentTypeRange: ManipulateType + aroundRange: string + timeGranularity?: DatePickType +} const props = defineProps({ timeRange: { type: Object as PropType, @@ -25,7 +46,7 @@ const props = defineProps({ }) }, timeGranularityMultiple: { - type: String, + type: String as PropType, default: 'yearrange' } }) @@ -51,7 +72,7 @@ const intervalTypeList = [ ] const regularOrTrendsTitle = computed(() => { - return intervalTypeList.find(ele => ele.value === timeRange.value.intervalType).label + return intervalTypeList.find(ele => ele.value === timeRange.value.intervalType)?.label || '' }) const { timeRange } = toRefs(props) const dynamicTime = computed(() => { @@ -62,6 +83,10 @@ const filterTypeCom = computed(() => { return intervalType === 'timeInterval' ? DynamicTimeRange : DynamicTime }) +const dynamicConfig = computed(() => { + return timeRange.value as unknown as DynamicConfig +}) + const aroundList = [ { label: t('dynamic_time.before'), @@ -98,7 +123,7 @@ const relativeToCurrentTypeListTips = computed(() => { return (relativeToCurrentTypeList.value[relativeToCurrentTypeList.value.length - 1] || {}).label }) const relativeToCurrentList = computed(() => { - let list = [] + let list: OptionItem[] = [] if (!timeRange.value) return list switch (props.timeGranularityMultiple) { case 'yearrange': @@ -188,7 +213,7 @@ const relativeToCurrentList = computed(() => { }) const relativeToCurrentListRange = computed(() => { - let list = [] + let list: OptionItem[] = [] if (!timeRange.value) return list switch (props.timeGranularityMultiple) { case 'yearrange': @@ -265,6 +290,10 @@ const relativeToCurrentListRange = computed(() => { { label: t('common.month_to_yesterday'), value: 'monthToYesterday' + }, + { + label: t('v_query.last_month_full'), + value: 'LastMonthFull' } ] break @@ -465,7 +494,7 @@ watch(
{{ t('template_manage.preview') }}
Date: Thu, 4 Jun 2026 12:22:04 +0800 Subject: [PATCH 3/3] =?UTF-8?q?fix(=E5=9B=BE=E8=A1=A8):=20=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E9=9B=B7=E8=BE=BE=E5=9B=BE=E6=95=B0=E6=8D=AE=E8=8C=83?= =?UTF-8?q?=E5=9B=B4=E8=AE=A1=E7=AE=97=E5=92=8C=E5=9D=90=E6=A0=87=E8=BD=B4?= =?UTF-8?q?=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../js/panel/charts/g2/distribution/radar.ts | 60 ++++++++++++++++--- 1 file changed, 51 insertions(+), 9 deletions(-) diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/distribution/radar.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/distribution/radar.ts index 4bc620da2b..e8e089189b 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/g2/distribution/radar.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/g2/distribution/radar.ts @@ -201,8 +201,16 @@ export class Radar extends G2ChartView { }) } if (radarAreaColor) { + const areaBaseline = Number(options.scale?.y?.domainMin) options.children.push({ type: 'area', + encode: { + x: 'field', + y: 'value', + // 面积层默认以 0 为基线,自动轴最小值不是 0 时会画到坐标外 + y1: Number.isFinite(areaBaseline) ? { type: 'constant', value: areaBaseline } : undefined, + color: 'category' + }, style: { opacity: 0.5 }, @@ -304,22 +312,56 @@ export class Radar extends G2ChartView { } } defaultsDeep(options, axis) + options.inset = misc.showName ? 24 : 8 const axisValue = misc.axisValue - if (!axisValue?.auto) { + const data = Array.isArray(options.data) ? options.data : [] + const dataRange = data.reduce( + (range, item) => { + const value = Number(item?.value) + if (Number.isFinite(value)) { + range.min = Math.min(range.min, value) + range.max = Math.max(range.max, value) + } + return range + }, + { min: Infinity, max: -Infinity } + ) + const tickMethod = (min, max, count = 5) => { + if (min === max) { + return [min] + } + const splitCount = Math.max(1, count) + const step = (max - min) / splitCount + const ticks = [] + for (let i = 0; i <= splitCount; i++) { + ticks.push(min + step * i) + } + return ticks + } + if (axisValue?.auto !== false) { + if (Number.isFinite(dataRange.min) && Number.isFinite(dataRange.max)) { + const dataMin = dataRange.min + const dataMax = dataRange.max + const splitCount = Math.max(1, Number(misc.splitNumber) || 5) + const padding = (dataMax - dataMin || Math.abs(dataMax) || 1) / splitCount + options.scale.y = { + ...options.scale.y, + // G2 的 nice 会同时扩展最小值,这里只固定最小值并给最大值留出一格空间 + nice: false, + domainMin: dataMin, + domainMax: dataMax + padding, + tickCount: splitCount, + tickMethod + } + } + } else { const yScale = { scale: { y: { domainMin: axisValue.min, domainMax: axisValue.max, tickCount: axisValue.splitCount, - tickMethod: (min, max, count) => { - const step = (max - min) / count - const ticks = [] - for (let i = 0; i <= count; i++) { - ticks.push(min + step * i) - } - return ticks - } + tickMethod } } }