Merge remote-tracking branch 'origin/dev-v3' into dev-v3

This commit is contained in:
wangjiahao
2026-06-04 14:15:52 +08:00
10 changed files with 99 additions and 18 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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<TimeRange>,
@@ -25,7 +46,7 @@ const props = defineProps({
})
},
timeGranularityMultiple: {
type: String,
type: String as PropType<DatePickType>,
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<DynamicConfig>(() => {
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(
<div class="setting-label" v-if="dynamicTime">{{ t('template_manage.preview') }}</div>
<div :class="dynamicTime ? 'setting-value' : 'w100'">
<component
:config="timeRange"
:config="dynamicConfig"
:timeGranularityMultiple="timeGranularityMultiple"
ref="inputCom"
:is="filterTypeCom"

View File

@@ -109,6 +109,8 @@ function getCustomRange(relativeToCurrentRange: string): [Date, Date] {
new Date(dayjs().subtract(2, 'day').startOf('day').format('YYYY/MM/DD HH:mm:ss')),
getThisEnd('day')
]
case 'LastMonthFull':
return [getLastStart('month'), getLastEnd('month')]
case 'monthBeginning':
return [getThisStart('month'), getThisEnd('day')]
case 'yearBeginning':

View File

@@ -190,7 +190,7 @@ interface TimeRange {
dynamicWindow: boolean
maximumSingleQuery: number
regularOrTrends: string
regularOrTrendsValue: string
regularOrTrendsValue: string | Date | [Date, Date]
relativeToCurrent: string
relativeToCurrentRange: string
timeNum: number
@@ -199,6 +199,7 @@ interface TimeRange {
timeNumRange: number
relativeToCurrentTypeRange: ManipulateType
aroundRange: string
timeGranularity?: string
timeGranularityMultiple?: string
}
export {

View File

@@ -2860,6 +2860,7 @@ export default {
last_6_months: 'Last 6 months',
last_12_months: 'Last 12 months',
last_3_days: 'Last 3 days',
last_month_full: 'Last month (start to end of month)',
month_to_date: 'Month to date',
year_to_date: 'Year to date',
year_to_last_month_end: 'Year to end of last month',

View File

@@ -2790,6 +2790,7 @@ export default {
last_6_months: '最近6 個月',
last_12_months: '最近12 個月',
last_3_days: '最近3 天',
last_month_full: '上月(月初至月末)',
month_to_date: '月初至今',
year_to_date: '年初至今',
year_to_last_month_end: '年初至上月底',

View File

@@ -2796,6 +2796,7 @@ export default {
last_6_months: '最近 6 个 月',
last_12_months: '最近 12 个 月',
last_3_days: '最近 3 天',
last_month_full: '上月(月初至月末)',
month_to_date: '月初至今',
year_to_date: '年初至今',
year_to_last_month_end: '年初至上月末',

View File

@@ -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 += '.'

View File

@@ -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
}
}
}