forked from github/dataease
Merge pull request #12544 from dataease/pr@dev-v2@refactor_stack_bar_split_total_label
refactor(图表): 堆叠柱状图指标标签和总计标签分开控制
This commit is contained in:
commit
52831b72ea
@ -860,6 +860,10 @@ declare interface ChartLabelAttr {
|
||||
* 总计标签格式化设置
|
||||
*/
|
||||
totalFormatter: BaseFormatter
|
||||
/**
|
||||
* 柱状图堆叠指标
|
||||
*/
|
||||
showStackQuota: boolean
|
||||
}
|
||||
/**
|
||||
* 提示设置
|
||||
|
@ -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"
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user