feat(图表): 指标卡支持设置名称和值间距

This commit is contained in:
wisonic-s 2024-04-18 17:11:42 +08:00
parent de383e3357
commit 4710fb18a4
8 changed files with 219 additions and 95 deletions

View File

@ -7,7 +7,7 @@ import { deepCopy } from '@/utils/utils'
import { cloneDeep, defaultsDeep, defaultTo } from 'lodash-es'
import {
BASE_VIEW_CONFIG,
CHART_CONT_FAMILY_MAP,
CHART_FONT_FAMILY_MAP,
DEFAULT_INDICATOR_NAME_STYLE,
DEFAULT_INDICATOR_STYLE
} from '@/views/chart/components/editor/util/chart'
@ -170,7 +170,7 @@ const formattedResult = computed(() => {
const emit = defineEmits(['onChartClick', 'onDrillFilters', 'onJumpClick'])
const contentStyle = ref({
const contentStyle = ref<CSSProperties>({
display: 'flex',
'flex-direction': 'column',
'align-items': 'center',
@ -182,7 +182,7 @@ const indicatorClass = ref<CSSProperties>({
color: thresholdColor.value,
'font-size': DEFAULT_INDICATOR_STYLE.fontSize + 'px',
'font-family': defaultTo(
CHART_CONT_FAMILY_MAP[DEFAULT_INDICATOR_STYLE.fontFamily],
CHART_FONT_FAMILY_MAP[DEFAULT_INDICATOR_STYLE.fontFamily],
DEFAULT_INDICATOR_STYLE.fontFamily
),
'font-weight': DEFAULT_INDICATOR_STYLE.isBolder ? 'bold' : 'normal',
@ -196,7 +196,7 @@ const indicatorSuffixClass = ref<CSSProperties>({
color: DEFAULT_INDICATOR_STYLE.suffixColor,
'font-size': DEFAULT_INDICATOR_STYLE.suffixFontSize + 'px',
'font-family': defaultTo(
CHART_CONT_FAMILY_MAP[DEFAULT_INDICATOR_STYLE.suffixFontFamily],
CHART_FONT_FAMILY_MAP[DEFAULT_INDICATOR_STYLE.suffixFontFamily],
DEFAULT_INDICATOR_STYLE.suffixFontFamily
),
'font-weight': DEFAULT_INDICATOR_STYLE.suffixIsBolder ? 'bold' : 'normal',
@ -212,11 +212,15 @@ const suffixContent = ref('')
const indicatorNameShow = ref(false)
const indicatorNameWrapperStyle = reactive<CSSProperties>({
'margin-top': DEFAULT_INDICATOR_NAME_STYLE.nameValueSpacing + 'px'
})
const indicatorNameClass = ref<CSSProperties>({
color: DEFAULT_INDICATOR_NAME_STYLE.color,
'font-size': DEFAULT_INDICATOR_NAME_STYLE.fontSize + 'px',
'font-family': defaultTo(
CHART_CONT_FAMILY_MAP[DEFAULT_INDICATOR_NAME_STYLE.fontFamily],
CHART_FONT_FAMILY_MAP[DEFAULT_INDICATOR_NAME_STYLE.fontFamily],
DEFAULT_INDICATOR_NAME_STYLE.fontFamily
),
'font-weight': DEFAULT_INDICATOR_NAME_STYLE.isBolder ? 'bold' : 'normal',
@ -237,16 +241,16 @@ const renderChart = async view => {
const chart = deepCopy({
...defaultsDeep(view, TEMP_DEFAULT_CHART),
data: chartData.value
})
}) as ChartObj
recursionTransObj(customAttrTrans, chart.customAttr, scale.value, terminal.value)
recursionTransObj(customStyleTrans, chart.customStyle, scale.value, terminal.value)
if (chart.customAttr) {
const customAttr = chart.customAttr
const { indicator, indicatorName, basicStyle } = chart.customAttr
if (customAttr.indicator) {
switch (customAttr.indicator.hPosition) {
if (indicator) {
switch (indicator.hPosition) {
case 'left':
contentStyle.value['align-items'] = 'flex-start'
break
@ -256,7 +260,7 @@ const renderChart = async view => {
default:
contentStyle.value['align-items'] = 'center'
}
switch (customAttr.indicator.vPosition) {
switch (indicator.vPosition) {
case 'top':
contentStyle.value['justify-content'] = 'flex-start'
break
@ -267,73 +271,68 @@ const renderChart = async view => {
contentStyle.value['justify-content'] = 'center'
}
indicatorColor.value = customAttr.indicator.color
let suffixColor = customAttr.indicator.suffixColor
indicatorColor.value = indicator.color
let suffixColor = indicator.suffixColor
if (
customAttr.basicStyle &&
customAttr.basicStyle.alpha !== undefined &&
!batchOptStatus.value
) {
indicatorColor.value = hexColorToRGBA(
customAttr.basicStyle.colors[0],
customAttr.basicStyle.alpha
)
suffixColor = hexColorToRGBA(customAttr.basicStyle.colors[1], customAttr.basicStyle.alpha)
if (basicStyle?.alpha !== undefined && !batchOptStatus.value) {
indicatorColor.value = hexColorToRGBA(basicStyle.colors[0], basicStyle.alpha)
suffixColor = hexColorToRGBA(basicStyle.colors[1], basicStyle.alpha)
}
indicatorClass.value = {
color: thresholdColor.value,
'font-size': customAttr.indicator.fontSize + 'px',
'font-size': indicator.fontSize + 'px',
'font-family': defaultTo(
CHART_CONT_FAMILY_MAP[customAttr.indicator.fontFamily],
CHART_FONT_FAMILY_MAP[indicator.fontFamily],
DEFAULT_INDICATOR_STYLE.fontFamily
),
'font-weight': customAttr.indicator.isBolder ? 'bold' : 'normal',
'font-style': customAttr.indicator.isItalic ? 'italic' : 'normal',
'letter-spacing': customAttr.indicator.letterSpace + 'px',
'text-shadow': customAttr.indicator.fontShadow ? '2px 2px 4px' : 'none',
'font-weight': indicator.isBolder ? 'bold' : 'normal',
'font-style': indicator.isItalic ? 'italic' : 'normal',
'letter-spacing': indicator.letterSpace + 'px',
'text-shadow': indicator.fontShadow ? '2px 2px 4px' : 'none',
'font-synthesis': 'weight style'
}
indicatorSuffixClass.value = {
color: suffixColor,
'font-size': customAttr.indicator.suffixFontSize + 'px',
'font-size': indicator.suffixFontSize + 'px',
'font-family': defaultTo(
CHART_CONT_FAMILY_MAP[customAttr.indicator.suffixFontFamily],
CHART_FONT_FAMILY_MAP[indicator.suffixFontFamily],
DEFAULT_INDICATOR_STYLE.suffixFontFamily
),
'font-weight': customAttr.indicator.suffixIsBolder ? 'bold' : 'normal',
'font-style': customAttr.indicator.suffixIsItalic ? 'italic' : 'normal',
'letter-spacing': customAttr.indicator.suffixLetterSpace + 'px',
'text-shadow': customAttr.indicator.suffixFontShadow ? '2px 2px 4px' : 'none',
'font-weight': indicator.suffixIsBolder ? 'bold' : 'normal',
'font-style': indicator.suffixIsItalic ? 'italic' : 'normal',
'letter-spacing': indicator.suffixLetterSpace + 'px',
'text-shadow': indicator.suffixFontShadow ? '2px 2px 4px' : 'none',
'font-synthesis': 'weight style'
}
showSuffix.value = customAttr.indicator.suffixEnable
suffixContent.value = defaultTo(customAttr.indicator.suffix, '')
showSuffix.value = indicator.suffixEnable
suffixContent.value = defaultTo(indicator.suffix, '')
}
if (customAttr.indicatorName && customAttr.indicatorName.show) {
let nameColor = customAttr.indicatorName.color
if (indicatorName?.show) {
let nameColor = indicatorName.color
if (customAttr.basicStyle && customAttr.basicStyle.alpha !== undefined) {
nameColor = hexColorToRGBA(customAttr.basicStyle.colors[2], customAttr.basicStyle.alpha)
if (basicStyle?.alpha !== undefined) {
nameColor = hexColorToRGBA(basicStyle.colors[2], basicStyle.alpha)
}
indicatorNameShow.value = true
indicatorNameClass.value = {
color: nameColor,
'font-size': customAttr.indicatorName.fontSize + 'px',
'font-size': indicatorName.fontSize + 'px',
'font-family': defaultTo(
CHART_CONT_FAMILY_MAP[customAttr.indicatorName.fontFamily],
CHART_FONT_FAMILY_MAP[indicatorName.fontFamily],
DEFAULT_INDICATOR_NAME_STYLE.fontFamily
),
'font-weight': customAttr.indicatorName.isBolder ? 'bold' : 'normal',
'font-style': customAttr.indicatorName.isItalic ? 'italic' : 'normal',
'letter-spacing': customAttr.indicatorName.letterSpace + 'px',
'text-shadow': customAttr.indicatorName.fontShadow ? '2px 2px 4px' : 'none',
'font-weight': indicatorName.isBolder ? 'bold' : 'normal',
'font-style': indicatorName.isItalic ? 'italic' : 'normal',
'letter-spacing': indicatorName.letterSpace + 'px',
'text-shadow': indicatorName.fontShadow ? '2px 2px 4px' : 'none',
'font-synthesis': 'weight style'
}
indicatorNameWrapperStyle['margin-top'] =
(indicatorName.nameValueSpacing ?? DEFAULT_INDICATOR_NAME_STYLE.nameValueSpacing) + 'px'
} else {
indicatorNameShow.value = false
}
@ -363,9 +362,6 @@ const calcData = (view, callback) => {
callback?.()
})
} else {
if (view.type === 'map') {
renderChart(view)
}
callback?.()
}
}
@ -382,7 +378,7 @@ defineExpose({
<span :style="indicatorClass">{{ formattedResult }}</span>
<span :style="indicatorSuffixClass" v-if="showSuffix">{{ suffixContent }}</span>
</div>
<div v-if="indicatorNameShow">
<div :style="indicatorNameWrapperStyle" v-if="indicatorNameShow">
<span :style="indicatorNameClass">{{ resultName }}</span>
</div>
</div>

View File

@ -982,6 +982,7 @@ export default {
dimension_font_family: '名称字体',
dimension_text_style: '名称样式',
dimension_letter_space: '名称字间距',
name_value_spacing: '名称/值间距',
font_family: '字体',
letter_space: '字间距',
font_shadow: '字体阴影',

View File

@ -38,6 +38,14 @@ declare interface ChartAttr {
* 象限设置
*/
quadrant: QuadrantAttr
/**
* 指标值
*/
indicator: ChartIndicatorStyle
/**
* 指标名称
*/
indicatorName: ChartIndicatorNameStyle
}
/**
* 基础样式设置
@ -735,3 +743,127 @@ declare interface QuadrantLineStyle {
*/
opacity: number
}
/**
* 指标卡值样式
*/
declare interface ChartIndicatorStyle {
/**
* 是否显示
*/
show: boolean
/**
* 字体大小
*/
fontSize: number
/**
* 字体颜色
*/
color: string
/**
* 水平位置
*/
hPosition: 'left' | 'center' | 'right'
/**
* 垂直位置
*/
vPosition: 'top' | 'center' | 'bottom'
/**
* 是否斜体
*/
isItalic: boolean
/**
* 是否加粗
*/
isBolder: boolean
/**
* 字体类型
*/
fontFamily: string
/**
* 字间距
*/
letterSpace: number
/**
* 是否显示字体阴影
*/
fontShadow: boolean
/**
* 是否显示后缀
*/
suffixEnable: boolean
/**
* 后缀内容
*/
suffix: string
/**
* 后缀字体大小
*/
suffixFontSize: number
/**
* 后缀字体颜色
*/
suffixColor: string
/**
* 后缀是否斜体
*/
suffixIsItalic: boolean
/**
* 后缀是否加粗
*/
suffixIsBolder: boolean
/**
* 后缀字体类型
*/
suffixFontFamily: string
/**
* 后缀字间距
*/
suffixLetterSpace: number
/**
* 后置是否显示阴影
*/
suffixFontShadow: boolean
}
/**
* 指标卡名称样式
*/
declare interface ChartIndicatorNameStyle {
/**
* 是否显示
*/
show: boolean
/**
* 字体大小
*/
fontSize: number
/**
* 字体颜色
*/
color: string
/**
* 是否斜体
*/
isItalic: boolean
/**
* 是否加粗
*/
isBolder: boolean
/**
* 字体类型
*/
fontFamily: string
/**
* 字间距
*/
letterSpace: number
/**
* 是否显示字体阴影
*/
fontShadow: boolean
/**
* 指标/名称间距
*/
nameValueSpacing: number
}

View File

@ -32,39 +32,6 @@ declare interface ChartStyle {
}
}
declare interface ChartIndicatorStyle {
show: boolean
fontSize: string
color: string
hPosition: 'left' | 'center' | 'right'
vPosition: 'top' | 'center' | 'bottom'
isItalic: boolean
isBolder: boolean
fontFamily: string
letterSpace: string
fontShadow: boolean
suffixEnable: boolean
suffix: string
suffixFontSize: string
suffixColor: string
suffixIsItalic: boolean
suffixIsBolder: boolean
suffixFontFamily: string
suffixLetterSpace: string
suffixFontShadow: boolean
}
declare interface ChartIndicatorNameStyle {
show: boolean
fontSize: string
color: string
isItalic: boolean
isBolder: boolean
fontFamily: string
letterSpace: string
fontShadow: boolean
}
/**
* 标题样式设置
*/

View File

@ -128,7 +128,7 @@ export const customAttrTrans = {
label: ['fontSize'],
tooltip: ['fontSize'],
indicator: ['fontSize', 'suffixFontSize'],
indicatorName: ['fontSize']
indicatorName: ['fontSize', 'nameValueSpacing']
}
export const customStyleTrans = {
text: ['fontSize'],

View File

@ -9,7 +9,6 @@ import {
DEFAULT_BASIC_STYLE
} from '@/views/chart/components/editor/util/chart'
import { cloneDeep, defaultsDeep } from 'lodash-es'
import { ElIcon } from 'element-plus-secondary'
import Icon from '@/components/icon-custom/src/Icon.vue'
import { hexColorToRGBA } from '@/views/chart/components/js/util'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
@ -251,6 +250,24 @@ defineExpose({ getFormData })
{{ t('chart.font_shadow') }}
</el-checkbox>
</el-form-item>
<el-form-item
class="form-item name-value-spacing-input"
:class="'form-item-' + themes"
:label="t('chart.name_value_spacing')"
>
<el-input-number
step-strictly
v-model="state.indicatorNameForm.nameValueSpacing"
size="small"
:min="0"
:max="100"
:value-on-clear="0"
:precision="0"
:step="1"
:effect="themes"
@change="changeTitleStyle('nameValueSpacing')"
/>
</el-form-item>
</el-form>
</div>
</template>
@ -366,4 +383,14 @@ defineExpose({ getFormData })
color: var(--N600-Dark, #a6a6a6);
}
}
.name-value-spacing-input {
display: flex !important;
:deep(label) {
line-height: 28px !important;
margin-bottom: 0 !important;
}
:deep(.ed-input__inner) {
text-align: center !important;
}
}
</style>

View File

@ -367,35 +367,36 @@ export const DEFAULT_TITLE_STYLE: ChartTextStyle = {
export const DEFAULT_INDICATOR_STYLE: ChartIndicatorStyle = {
show: true,
fontSize: '20',
fontSize: 20,
color: '#5470C6ff',
hPosition: 'center',
vPosition: 'center',
isItalic: false,
isBolder: true,
fontFamily: 'Microsoft YaHei',
letterSpace: '0',
letterSpace: 0,
fontShadow: false,
suffixEnable: true,
suffix: '',
suffixFontSize: '14',
suffixFontSize: 14,
suffixColor: '#5470C6ff',
suffixIsItalic: false,
suffixIsBolder: true,
suffixFontFamily: 'Microsoft YaHei',
suffixLetterSpace: '0',
suffixLetterSpace: 0,
suffixFontShadow: false
}
export const DEFAULT_INDICATOR_NAME_STYLE: ChartIndicatorNameStyle = {
show: true,
fontSize: '18',
fontSize: 18,
color: '#ffffffff',
isItalic: false,
isBolder: true,
fontFamily: 'Microsoft YaHei',
letterSpace: '0',
fontShadow: false
letterSpace: 0,
fontShadow: false,
nameValueSpacing: 0
}
export const DEFAULT_TITLE_STYLE_BASE: ChartTextStyle = {
@ -1002,7 +1003,7 @@ export const CHART_FONT_FAMILY = [
{ name: '楷体', value: 'KaiTi' }
]
export const CHART_CONT_FAMILY_MAP = {
export const CHART_FONT_FAMILY_MAP = {
'Microsoft YaHei': 'Microsoft YaHei',
SimSun: 'SimSun, "Songti SC", STSong',
SimHei: 'SimHei, Helvetica',

View File

@ -19,7 +19,7 @@ import {
import { useEmitt } from '@/hooks/web/useEmitt'
import { hexColorToRGBA } from '@/views/chart/components/js/util.js'
import {
CHART_CONT_FAMILY_MAP,
CHART_FONT_FAMILY_MAP,
DEFAULT_TITLE_STYLE
} from '@/views/chart/components/editor/util/chart'
import DrillPath from '@/views/chart/components/views/components/DrillPath.vue'
@ -250,7 +250,7 @@ const initTitle = () => {
state.title_class.fontWeight = customStyle.text.isBolder ? 'bold' : 'normal'
state.title_class.fontFamily = customStyle.text.fontFamily
? CHART_CONT_FAMILY_MAP[customStyle.text.fontFamily]
? CHART_FONT_FAMILY_MAP[customStyle.text.fontFamily]
: DEFAULT_TITLE_STYLE.fontFamily
state.title_class.letterSpacing =
(customStyle.text.letterSpace