mirror of
https://github.com/dataease/dataease.git
synced 2026-05-15 05:22:13 +08:00
feat(仪表板、数据大屏): 仪表板大屏支持通用设置添加对数值格式的统一处理 (#17575)
This commit is contained in:
@@ -17,6 +17,8 @@ import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { merge } from 'lodash-es'
|
||||
import CanvasBackground from '@/components/visualization/component-background/CanvasBackground.vue'
|
||||
import SeniorStyleSetting from '@/components/dashboard/subject-setting/dashboard-style/SeniorStyleSetting.vue'
|
||||
import ValueFormatterSetting from '@/components/dashboard/subject-setting/dashboard-style/ValueFormatterSetting.vue'
|
||||
import { formatterViewInfo } from '@/views/chart/components/js/formatter'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const { canvasStyleData, componentData, canvasViewInfo } = storeToRefs(dvMainStore)
|
||||
@@ -51,12 +53,18 @@ const onColorChange = val => {
|
||||
const onTextChange = val => {
|
||||
themeAttrChange('customStyle', 'text', val)
|
||||
}
|
||||
|
||||
const onFormatterItemChange = val => {
|
||||
themeAttrChange('formatterCfg', 'formatterCfg', val)
|
||||
}
|
||||
const themeAttrChange = (custom, property, value) => {
|
||||
if (canvasAttrInit) {
|
||||
Object.keys(canvasViewInfo.value).forEach(function (viewId) {
|
||||
const viewInfo = canvasViewInfo.value[viewId]
|
||||
try {
|
||||
if (custom === 'customAttr') {
|
||||
if (custom === 'formatterCfg') {
|
||||
formatterViewInfo(viewInfo, value)
|
||||
} else if (custom === 'customAttr') {
|
||||
merge(viewInfo['customAttr'], value)
|
||||
} else {
|
||||
Object.keys(value).forEach(function (key) {
|
||||
@@ -154,6 +162,12 @@ const saveSelfSubject = () => {
|
||||
>
|
||||
<filter-style-simple-selector />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item :title="t('visualization.number_formatter')" name="formatterItem">
|
||||
<ValueFormatterSetting
|
||||
:formatter-cfg="canvasStyleData.component.formatterItem"
|
||||
@onFormatterItemChange="onFormatterItemChange"
|
||||
></ValueFormatterSetting>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item
|
||||
:title="t('components.advanced_style_settings')"
|
||||
name="seniorStyleSetting"
|
||||
|
||||
@@ -210,9 +210,7 @@
|
||||
class="radio-span"
|
||||
@change="themeChange"
|
||||
>
|
||||
<el-radio label="all" :effect="themes">
|
||||
{{ t('visualization.view') }}
|
||||
</el-radio>
|
||||
<el-radio label="all" :effect="themes"> {{ t('visualization.view') }} 22 </el-radio>
|
||||
<el-radio label="custom" :effect="themes">
|
||||
{{ resourceType }}
|
||||
</el-radio>
|
||||
|
||||
@@ -0,0 +1,238 @@
|
||||
<script lang="tsx" setup>
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { reactive, toRefs } from 'vue'
|
||||
import {
|
||||
isEnLocal,
|
||||
formatterType,
|
||||
getUnitTypeList,
|
||||
onChangeFormatCfgUnitLanguage,
|
||||
valueFormatter,
|
||||
initFormatCfgUnit
|
||||
} from '@/views/chart/components/js/formatter'
|
||||
import { ElFormItem } from 'element-plus-secondary'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const emit = defineEmits(['onFormatterItemChange'])
|
||||
|
||||
const props = defineProps({
|
||||
formatterCfg: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
themes: {
|
||||
type: String,
|
||||
default: 'light'
|
||||
}
|
||||
})
|
||||
|
||||
const { formatterCfg } = toRefs(props)
|
||||
|
||||
const state = reactive({
|
||||
typeList: formatterType,
|
||||
exampleResult: '20000000'
|
||||
})
|
||||
|
||||
function changeUnitLanguage(cfg: BaseFormatter, lang) {
|
||||
onChangeFormatCfgUnitLanguage(cfg, lang)
|
||||
getExampleValue()
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
if (!formatterCfg.value) {
|
||||
formatterCfg.value = formatterCfg
|
||||
|
||||
initFormatCfgUnit(formatterCfg.value)
|
||||
}
|
||||
}
|
||||
|
||||
const onFormatChange = () => {
|
||||
getExampleValue()
|
||||
emit('onFormatterItemChange', formatterCfg.value)
|
||||
}
|
||||
const getExampleValue = () => {
|
||||
state.exampleResult = valueFormatter(20000000, formatterCfg.value)
|
||||
}
|
||||
|
||||
init()
|
||||
getExampleValue()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<el-form
|
||||
ref="form"
|
||||
:effect="themes"
|
||||
:model="formatterCfg"
|
||||
class="formatter-form"
|
||||
label-position="top"
|
||||
>
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
:label="t('chart.value_formatter_type')"
|
||||
>
|
||||
<el-radio-group
|
||||
class="radio-span"
|
||||
:effect="themes"
|
||||
v-model="formatterCfg.type"
|
||||
@change="onFormatChange"
|
||||
>
|
||||
<el-radio
|
||||
:effect="themes"
|
||||
v-for="radio in state.typeList"
|
||||
:key="radio.value"
|
||||
:label="radio.value"
|
||||
>{{ t('chart.' + radio.name) }}</el-radio
|
||||
>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-if="formatterCfg.type !== 'auto'"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
:label="t('chart.value_formatter_decimal_count')"
|
||||
>
|
||||
<el-input-number
|
||||
controls-position="right"
|
||||
v-model="formatterCfg.decimalCount"
|
||||
:effect="themes"
|
||||
size="small"
|
||||
:min="0"
|
||||
:max="10"
|
||||
@change="onFormatChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<template v-if="formatterCfg.type !== 'percent'">
|
||||
<el-row :gutter="8">
|
||||
<el-col :span="12" v-if="!isEnLocal">
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
:label="t('chart.value_formatter_unit_language')"
|
||||
>
|
||||
<el-select
|
||||
v-model="formatterCfg.unitLanguage"
|
||||
size="small"
|
||||
:placeholder="t('chart.pls_select_field')"
|
||||
:effect="themes"
|
||||
@change="v => changeUnitLanguage(formatterCfg, v)"
|
||||
>
|
||||
<el-option
|
||||
:effect="themes"
|
||||
size="small"
|
||||
:label="t('chart.value_formatter_unit_language_ch')"
|
||||
value="ch"
|
||||
/>
|
||||
<el-option
|
||||
size="small"
|
||||
:effect="themes"
|
||||
:label="t('chart.value_formatter_unit_language_en')"
|
||||
value="en"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="isEnLocal ? 24 : 12">
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
:label="t('chart.value_formatter_unit')"
|
||||
>
|
||||
<el-select
|
||||
:effect="themes"
|
||||
size="small"
|
||||
v-model="formatterCfg.unit"
|
||||
:placeholder="t('chart.pls_select_field')"
|
||||
@change="onFormatChange"
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option
|
||||
:effect="themes"
|
||||
size="small"
|
||||
v-for="item in getUnitTypeList(formatterCfg.unitLanguage)"
|
||||
:key="item.value"
|
||||
:label="item.name"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-form-item
|
||||
:effect="themes"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
:label="t('chart.value_formatter_suffix')"
|
||||
>
|
||||
<el-input
|
||||
v-model="formatterCfg.suffix"
|
||||
:effect="themes"
|
||||
size="small"
|
||||
clearable
|
||||
:placeholder="t('commons.input_content')"
|
||||
@change="onFormatChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes" :effect="themes">
|
||||
<el-checkbox
|
||||
:effect="themes"
|
||||
size="small"
|
||||
v-model="formatterCfg.thousandSeparator"
|
||||
@change="onFormatChange"
|
||||
:label="t('chart.value_formatter_thousand_separator')"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<div style="line-height: 22px">
|
||||
<span style="color: #646a73">{{ t('chart.value_formatter_example') }}</span>
|
||||
<span style="margin-left: 12px">{{ state.exampleResult }}</span>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.el-form-item {
|
||||
margin-bottom: 10px !important;
|
||||
}
|
||||
.formatter-form {
|
||||
margin-bottom: 16px;
|
||||
:deep(.ed-form-item) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
:deep(.ed-form-item__label) {
|
||||
color: #1f2329;
|
||||
margin-bottom: 8px !important;
|
||||
font-size: 14px !important;
|
||||
font-weight: 400 !important;
|
||||
}
|
||||
|
||||
:deep(.ed-checkbox) {
|
||||
color: #1f2329;
|
||||
}
|
||||
}
|
||||
|
||||
.el-select-dropdown__item :deep(span) {
|
||||
font-size: 14px !important;
|
||||
}
|
||||
.exp-style {
|
||||
color: #c0c4cc;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.form-item-dark {
|
||||
:deep(.ed-form-item__label) {
|
||||
color: #6a6a6a;
|
||||
font-size: 12px !important;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -15,6 +15,8 @@ import SeniorStyleSetting from '@/components/dashboard/subject-setting/dashboard
|
||||
import Icon from '../icon-custom/src/Icon.vue'
|
||||
import CanvasBaseSetting from '@/components/visualization/CanvasBaseSetting.vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import ValueFormatterSetting from '@/components/dashboard/subject-setting/dashboard-style/ValueFormatterSetting.vue'
|
||||
import { formatterViewInfo } from '@/views/chart/components/js/formatter'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const { canvasStyleData, canvasViewInfo } = storeToRefs(dvMainStore)
|
||||
@@ -35,6 +37,10 @@ const init = () => {
|
||||
})
|
||||
}
|
||||
|
||||
const onFormatterItemChange = val => {
|
||||
themeAttrChange('formatterCfg', 'formatterCfg', val)
|
||||
}
|
||||
|
||||
const onColorChange = val => {
|
||||
themeAttrChange('customAttr', 'color', val)
|
||||
}
|
||||
@@ -53,7 +59,9 @@ const themeAttrChange = (custom, property, value) => {
|
||||
Object.keys(canvasViewInfo.value).forEach(function (viewId) {
|
||||
try {
|
||||
const viewInfo = canvasViewInfo.value[viewId]
|
||||
if (custom === 'customAttr') {
|
||||
if (custom === 'formatterCfg') {
|
||||
formatterViewInfo(viewInfo, value)
|
||||
} else if (custom === 'customAttr') {
|
||||
if (viewInfo.type === 'flow-map') {
|
||||
const { customAttr } = viewInfo
|
||||
const tmpValue = cloneDeep(value)
|
||||
@@ -172,6 +180,17 @@ onMounted(() => {
|
||||
>
|
||||
<overall-setting style="padding-bottom: 8px" themes="dark" />
|
||||
</el-collapse-item>
|
||||
<el-collapse-item
|
||||
effect="dark"
|
||||
:title="t('visualization.number_formatter')"
|
||||
name="formatterItem"
|
||||
>
|
||||
<ValueFormatterSetting
|
||||
:formatter-cfg="canvasStyleData.component.formatterItem"
|
||||
themes="dark"
|
||||
@onFormatterItemChange="onFormatterItemChange"
|
||||
></ValueFormatterSetting>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item
|
||||
effect="dark"
|
||||
:title="t('visualization.advanced_style_settings')"
|
||||
|
||||
@@ -2945,6 +2945,7 @@ export default {
|
||||
column_name: 'Field name'
|
||||
},
|
||||
visualization: {
|
||||
number_formatter: 'Number Content Format',
|
||||
jump_dialog_background: 'Jump pop-up background color',
|
||||
jump_dialog_button: 'Jump pop-up button color',
|
||||
sqlbot_query_tips: 'Smart Data Query',
|
||||
|
||||
@@ -2864,6 +2864,7 @@ export default {
|
||||
column_name: '欄位名稱'
|
||||
},
|
||||
visualization: {
|
||||
number_formatter: '數字內容格式',
|
||||
jump_dialog_background: '跳轉彈框背景色',
|
||||
jump_dialog_button: '跳轉彈框按鈕色',
|
||||
sqlbot_query_tips: '智能問數',
|
||||
|
||||
@@ -2870,6 +2870,7 @@ export default {
|
||||
column_name: '字段名称'
|
||||
},
|
||||
visualization: {
|
||||
number_formatter: '数字内容格式',
|
||||
jump_dialog_background: '跳转弹框背景色',
|
||||
jump_dialog_button: '跳转弹框按钮色',
|
||||
sqlbot_query_tips: '智能问数',
|
||||
|
||||
@@ -46,6 +46,7 @@ import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { isDesktop } from '@/utils/ModelUtil'
|
||||
import { ShorthandMode } from '@/Types'
|
||||
import { formatterItem } from '@/views/chart/components/js/formatter'
|
||||
const { t } = useI18n()
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const { wsCache } = useCache()
|
||||
@@ -340,6 +341,9 @@ export function historyAdaptor(
|
||||
canvasStyleResult['dialogBackgroundColor'] = canvasStyleResult['dialogBackgroundColor'] || '#fff'
|
||||
canvasStyleResult['dialogButton'] = canvasStyleResult['dialogButton'] || '#020408'
|
||||
|
||||
canvasStyleResult['component']['formatterItem'] =
|
||||
canvasStyleResult['component']['formatterItem'] || deepCopy(formatterItem)
|
||||
|
||||
canvasDataResult.forEach(componentItem => {
|
||||
historyItemAdaptor(componentItem, reportFilterInfo, attachInfo, canvasVersion, canvasInfo)
|
||||
})
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import { find } from 'lodash-es'
|
||||
import { find, merge } from 'lodash-es'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { getLocale } from '@/utils/utils'
|
||||
import { parseJson } from '@/views/chart/components/js/util'
|
||||
@@ -255,3 +255,65 @@ export const calcNiceMinValue = (chart, options, tmpOptions) => {
|
||||
}
|
||||
return { ...tmpOptions, ...axis }
|
||||
}
|
||||
|
||||
/**
|
||||
* 适配图表数字格式化属性
|
||||
* @param viewInfo
|
||||
* @param value
|
||||
*/
|
||||
export const formatterViewInfo = (viewInfo, value) => {
|
||||
viewInfo.xAxis.forEach(function (item) {
|
||||
item['formatterCfg'] = merge(item['formatterCfg'], value)
|
||||
})
|
||||
viewInfo.xAxisExt.forEach(function (item) {
|
||||
item['formatterCfg'] = merge(item['formatterCfg'], value)
|
||||
})
|
||||
viewInfo.yAxis.forEach(function (item) {
|
||||
item['formatterCfg'] = merge(item['formatterCfg'], value)
|
||||
})
|
||||
viewInfo.extStack.forEach(function (item) {
|
||||
item['formatterCfg'] = merge(item['formatterCfg'], value)
|
||||
})
|
||||
viewInfo.extBubble.forEach(function (item) {
|
||||
item['formatterCfg'] = merge(item['formatterCfg'], value)
|
||||
})
|
||||
viewInfo.extLabel.forEach(function (item) {
|
||||
item['formatterCfg'] = merge(item['formatterCfg'], value)
|
||||
})
|
||||
viewInfo.extTooltip.forEach(function (item) {
|
||||
item['formatterCfg'] = merge(item['formatterCfg'], value)
|
||||
})
|
||||
//customAttr
|
||||
viewInfo['customAttr']['label']['labelFormatter'] = merge(
|
||||
viewInfo['customAttr']['label']['labelFormatter'],
|
||||
value
|
||||
)
|
||||
viewInfo['customAttr']['label']['quotaLabelFormatter'] = merge(
|
||||
viewInfo['customAttr']['label']['quotaLabelFormatter'],
|
||||
value
|
||||
)
|
||||
viewInfo['customAttr']['label']['totalFormatter'] = merge(
|
||||
viewInfo['customAttr']['label']['totalFormatter'],
|
||||
value
|
||||
)
|
||||
viewInfo['customAttr']['tooltip']['tooltipFormatter'] = merge(
|
||||
viewInfo['customAttr']['tooltip']['tooltipFormatter'],
|
||||
value
|
||||
)
|
||||
viewInfo['customAttr']['tooltip']['seriesTooltipFormatter'].forEach(function (item) {
|
||||
item['formatterCfg'] = merge(item['formatterCfg'], value)
|
||||
})
|
||||
//customStyle
|
||||
viewInfo['customStyle']['xAxis']['axisLabelFormatter'] = merge(
|
||||
viewInfo['customStyle']['xAxis']['axisLabelFormatter'],
|
||||
value
|
||||
)
|
||||
viewInfo['customStyle']['yAxis']['axisLabelFormatter'] = merge(
|
||||
viewInfo['customStyle']['yAxis']['axisLabelFormatter'],
|
||||
value
|
||||
)
|
||||
viewInfo['customStyle']['yAxisExt']['axisLabelFormatter'] = merge(
|
||||
viewInfo['customStyle']['yAxisExt']['axisLabelFormatter'],
|
||||
value
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user