Merge pull request #12544 from dataease/pr@dev-v2@refactor_stack_bar_split_total_label

refactor(图表): 堆叠柱状图指标标签和总计标签分开控制
This commit is contained in:
wisonic-s 2024-09-29 20:41:54 +08:00 committed by GitHub
commit 52831b72ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 114 additions and 65 deletions

View File

@ -860,6 +860,10 @@ declare interface ChartLabelAttr {
* 总计标签格式化设置
*/
totalFormatter: BaseFormatter
/**
* 柱状图堆叠指标
*/
showStackQuota: boolean
}
/**
* 提示设置

View File

@ -432,9 +432,12 @@ watch(
@onChangeMiscStyleForm="onChangeMiscStyleForm"
/>
</el-collapse-item>
<el-collapse-item
:effect="themes"
<collapse-switch-item
:themes="themes"
v-if="showProperties('label-selector')"
v-model="chart.customAttr.label.show"
:change-model="chart.customAttr.label"
@modelChange="val => onLabelChange({ data: val }, 'show')"
:title="t('chart.label')"
name="label"
>
@ -446,7 +449,7 @@ watch(
:all-fields="props.allFields"
@onLabelChange="onLabelChange"
/>
</el-collapse-item>
</collapse-switch-item>
<collapse-switch-item
v-if="showProperties('tooltip-selector')"
v-model="chart.customAttr.tooltip.show"

View File

@ -12,6 +12,7 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
import Icon from '../../../../../../components/icon-custom/src/Icon.vue'
import { iconFieldMap } from '@/components/icon-group/field-list'
import { parseJson } from '../../../js/util'
const { t } = useI18n()
@ -242,6 +243,7 @@ const init = () => {
if (chart.customAttr) {
const customAttr = chart.customAttr
if (customAttr.label) {
configCompat(customAttr.label)
state.labelForm = defaultsDeep(customAttr.label, cloneDeep(COMPUTED_DEFAULT_LABEL.value))
if (chartType.value === 'liquid' && state.labelForm.fontSize < fontSizeList.value[0].value) {
state.labelForm.fontSize = fontSizeList.value[0].value
@ -253,6 +255,11 @@ const init = () => {
initPosition()
}
}
const configCompat = (labelAttr: DeepPartial<ChartLabelAttr>) => {
if (labelAttr.showStackQuota === undefined) {
labelAttr.showStackQuota = labelAttr.show
}
}
const checkLabelContent = contentProp => {
if (chartType.value === 'funnel') {
return false
@ -444,15 +451,6 @@ const conversionPrecision = [
</script>
<template>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
size="small"
:effect="themes"
v-model="state.labelForm.show"
@change="changeLabelAttr('show')"
:label="t('chart.show')"
/>
</el-form-item>
<el-form
ref="labelForm"
:disabled="!state.labelForm.show"
@ -460,6 +458,36 @@ const conversionPrecision = [
label-position="top"
>
<el-row v-show="showEmpty" style="margin-bottom: 12px"> 无其他可设置的属性</el-row>
<div>
<el-form-item
v-if="showProperty('showStackQuota')"
class="form-item"
:class="'form-item-' + themes"
style="display: inline-block; margin-right: 8px"
>
<el-checkbox
size="small"
:effect="themes"
v-model="state.labelForm.showStackQuota"
@change="changeLabelAttr('showStackQuota')"
:label="t('chart.quota')"
/>
</el-form-item>
<el-form-item
v-if="showProperty('showTotal')"
class="form-item"
:class="'form-item-' + themes"
style="display: inline-block"
>
<el-checkbox
size="small"
:effect="themes"
v-model="state.labelForm.showTotal"
@change="changeLabelAttr('showTotal')"
:label="t('chart.total_show')"
/>
</el-form-item>
</div>
<div v-if="!isGroupBar">
<el-space>
<el-form-item
@ -1518,16 +1546,6 @@ const conversionPrecision = [
</el-row>
</div>
</el-form>
<el-form-item v-if="showProperty('showTotal')" class="form-item" :class="'form-item-' + themes">
<el-checkbox
size="small"
:effect="themes"
:disabled="false"
v-model="state.labelForm.showTotal"
@change="changeLabelAttr('showTotal')"
:label="t('chart.total_show')"
/>
</el-form-item>
</template>
<style lang="less" scoped>

View File

@ -339,7 +339,8 @@ export const DEFAULT_LABEL: ChartLabelAttr = {
showTotal: false,
totalFontSize: 12,
totalColor: '#FFF',
totalFormatter: formatterItem
totalFormatter: formatterItem,
showStackQuota: false
}
export const DEFAULT_TOOLTIP: ChartTooltipAttr = {
show: true,

View File

@ -18,7 +18,11 @@ import {
BAR_EDITOR_PROPERTY,
BAR_EDITOR_PROPERTY_INNER
} from '@/views/chart/components/js/panel/charts/bar/common'
import { getPadding, setGradientColor } from '@/views/chart/components/js/panel/common/common_antv'
import {
getLabel,
getPadding,
setGradientColor
} from '@/views/chart/components/js/panel/common/common_antv'
import { useI18n } from '@/hooks/web/useI18n'
import { DEFAULT_LABEL } from '@/views/chart/components/editor/util/chart'
import { clearExtremum, extremumEvt } from '@/views/chart/components/js/extremumUitl'
@ -271,25 +275,55 @@ export class StackBar extends Bar {
'showTotal',
'totalColor',
'totalFontSize',
'totalFormatter'
'totalFormatter',
'showStackQuota'
],
'tooltip-selector': ['fontSize', 'color', 'backgroundColor', 'tooltipFormatter', 'show']
}
protected configLabel(chart: Chart, options: ColumnOptions): ColumnOptions {
const baseOptions = super.configLabel(chart, options)
if (!baseOptions.label) {
return baseOptions
let label = getLabel(chart)
if (!label) {
return options
}
options = { ...options, label }
const { label: labelAttr } = parseJson(chart.customAttr)
baseOptions.label.style.fill = labelAttr.color
const label = {
...baseOptions.label,
formatter: function (param: Datum) {
return valueFormatter(param.value, labelAttr.labelFormatter)
if (labelAttr.showStackQuota || labelAttr.showStackQuota === undefined) {
label.style.fill = labelAttr.color
label = {
...label,
formatter: function (param: Datum) {
return valueFormatter(param.value, labelAttr.labelFormatter)
}
}
} else {
label = false
}
if (labelAttr.showTotal) {
const formatterCfg = labelAttr.labelFormatter ?? formatterItem
each(groupBy(options.data, 'field'), (values, key) => {
const total = values.reduce((a, b) => a + b.value, 0)
const value = valueFormatter(total, formatterCfg)
if (!options.annotations) {
options = {
...options,
annotations: []
}
}
options.annotations.push({
type: 'text',
position: [key, total],
content: `${value}`,
style: {
textAlign: 'center',
fontSize: labelAttr.fontSize,
fill: labelAttr.color
},
offsetY: -(parseInt(labelAttr.fontSize as unknown as string) / 2)
})
})
}
return {
...baseOptions,
...options,
label
}
}
@ -348,35 +382,6 @@ export class StackBar extends Bar {
return options
}
protected configTotalLabel(chart: Chart, options: ColumnOptions): ColumnOptions {
const { label } = parseJson(chart.customAttr)
if (label.showTotal) {
const formatterCfg = label.labelFormatter ?? formatterItem
each(groupBy(options.data, 'field'), (values, key) => {
const total = values.reduce((a, b) => a + b.value, 0)
const value = valueFormatter(total, formatterCfg)
if (!options.annotations) {
options = {
...options,
annotations: []
}
}
options.annotations.push({
type: 'text',
position: [key, total],
content: `${value}`,
style: {
textAlign: 'center',
fontSize: label.fontSize,
fill: label.color
},
offsetY: -(parseInt(label.fontSize as unknown as string) / 2)
})
})
}
return options
}
public setupSeriesColor(chart: ChartObj, data?: any[]): ChartBasicStyle['seriesColor'] {
return setUpStackSeriesColor(chart, data)
}
@ -394,8 +399,7 @@ export class StackBar extends Bar {
this.configYAxis,
this.configSlider,
this.configAnalyse,
this.configData,
this.configTotalLabel
this.configData
)(chart, options, {}, this)
}
@ -508,6 +512,25 @@ export class GroupStackBar extends StackBar {
}
}
protected configLabel(chart: Chart, options: ColumnOptions): ColumnOptions {
const baseOptions = super.configLabel(chart, options)
if (!baseOptions.label) {
return baseOptions
}
const { label: labelAttr } = parseJson(chart.customAttr)
baseOptions.label.style.fill = labelAttr.color
const label = {
...baseOptions.label,
formatter: function (param: Datum) {
return valueFormatter(param.value, labelAttr.labelFormatter)
}
}
return {
...baseOptions,
label
}
}
protected configTooltip(chart: Chart, options: ColumnOptions): ColumnOptions {
const tooltipAttr = parseJson(chart.customAttr).tooltip
if (!tooltipAttr.show) {