feat(图表): 明细表和汇总表支持隐藏字段 #10700

This commit is contained in:
wisonic 2024-10-16 18:02:33 +08:00
parent 4cc26895b4
commit 9aab070261
10 changed files with 105 additions and 11 deletions

View File

@ -281,6 +281,8 @@ const dialogInit = (canvasStyle, view, item, opt, params = { scale: 0.5 }) => {
if (opt === 'details') {
if (!viewInfo.value.type?.includes('table')) {
assign(viewInfo.value, DETAIL_CHART_ATTR)
viewInfo.value.xAxis.forEach(i => (i.hide = false))
viewInfo.value.yAxis.forEach(i => (i.hide = false))
} else {
assign(viewInfo.value, DETAIL_TABLE_ATTR)
}

View File

@ -1540,7 +1540,8 @@ export default {
map_symbol_hexagon: '六角形',
map_symbol_octagon: '八角形',
map_symbol_hexagram: '菱形',
tip: '提示'
tip: '提示',
hide: '隐藏'
},
dataset: {
scope_edit: '仅编辑时生效',

View File

@ -164,6 +164,10 @@ declare interface Axis extends ChartViewField {
* 自定义排序项
*/
customSort: string[]
/**
* 是否隐藏
*/
hide: boolean
}
declare interface ChartViewField {
/**

View File

@ -58,7 +58,8 @@ const emit = defineEmits([
'onCustomSort',
'onDimensionItemChange',
'onNameEdit',
'valueFormatter'
'valueFormatter',
'onToggleHide'
])
const { item } = toRefs(props)
@ -97,6 +98,9 @@ const clickItem = param => {
case 'formatter':
valueFormatter()
break
case 'toggleHide':
toggleHide()
break
default:
break
}
@ -104,7 +108,7 @@ const clickItem = param => {
const beforeClickItem = type => {
return {
type: type
type
}
}
@ -192,6 +196,15 @@ const showSort = () => {
}
return !isChartMix || isDimensionOrDimensionStack
}
const toggleHide = () => {
item.value.index = props.index
item.value.hide = !item.value.hide
item.value.axisType = props.type
emit('onToggleHide', item.value)
}
const showHideIcon = computed(() => {
return ['table-info', 'table-normal'].includes(props.chart.type) && item.value.hide
})
onMounted(() => {
getItemTagType()
})
@ -251,7 +264,9 @@ onMounted(() => {
<span class="item-name">{{ item.chartShowName ? item.chartShowName : item.name }}</span>
</span>
</el-tooltip>
<el-icon style="margin-left: 8px">
<Icon><Hide v-show="showHideIcon" class="svg-icon inner-class" /></Icon>
</el-icon>
<el-tooltip :effect="toolTip" placement="top">
<template #content>
<span>{{ t('chart.delete') }}</span>
@ -593,6 +608,17 @@ onMounted(() => {
</el-icon>
<span>{{ t('chart.show_name_set') }}</span>
</el-dropdown-item>
<el-dropdown-item
class="menu-item-padding"
v-if="['table-normal', 'table-info'].includes(chart.type)"
:command="beforeClickItem('toggleHide')"
>
<el-icon>
<icon v-if="item.hide === true" name="view"><View class="svg-icon" /></icon>
<icon v-else name="hide"><Hide class="svg-icon" /></icon>
</el-icon>
<span>{{ item.hide === true ? t('chart.show') : t('chart.hide') }}</span>
</el-dropdown-item>
<el-dropdown-item
class="menu-item-padding"
v-if="showValueFormatter"

View File

@ -72,7 +72,8 @@ const emit = defineEmits([
'onNameEdit',
'editItemFilter',
'editItemCompare',
'valueFormatter'
'valueFormatter',
'onToggleHide'
])
const { item, chart } = toRefs(props)
@ -162,6 +163,9 @@ const clickItem = param => {
case 'formatter':
valueFormatter()
break
case 'toggleHide':
toggleHide()
break
default:
break
}
@ -169,7 +173,7 @@ const clickItem = param => {
const beforeClickItem = type => {
return {
type: type
type
}
}
@ -285,7 +289,15 @@ const valueFormatter = () => {
item.value.formatterType = props.type
emit('valueFormatter', item.value)
}
const toggleHide = () => {
item.value.index = props.index
item.value.hide = !item.value.hide
item.value.axisType = props.type
emit('onToggleHide', item.value)
}
const showHideIcon = computed(() => {
return ['tale-info', 'table-normal'].includes(props.chart.type) && item.value.hide
})
onMounted(() => {
isEnableCompare()
getItemTagType()
@ -352,6 +364,15 @@ onMounted(() => {
-{{ t('chart.' + item.compareCalc.type) }}
</span>
</span>
<el-icon style="margin-left: 8px">
<Icon>
<Hide
v-show="showHideIcon"
:class="`field-icon-${fieldType[[2, 3].includes(item.deType) ? 2 : 0]}`"
class="svg-icon inner-class"
/>
</Icon>
</el-icon>
<el-tooltip :effect="toolTip" placement="top">
<template #content>
<span>{{ t('chart.delete') }}</span>
@ -734,6 +755,17 @@ onMounted(() => {
</el-icon>
<span>{{ t('chart.show_name_set') }}</span>
</el-dropdown-item>
<el-dropdown-item
class="menu-item-padding"
v-if="['table-normal', 'table-info'].includes(chart.type)"
:command="beforeClickItem('toggleHide')"
>
<el-icon>
<icon v-if="item.hide === true" name="view"><View class="svg-icon" /></icon>
<icon v-else name="hide"><Hide class="svg-icon" /></icon>
</el-icon>
<span>{{ item.hide === true ? t('chart.show') : t('chart.hide') }}</span>
</el-dropdown-item>
<el-dropdown-item class="menu-item-padding" :command="beforeClickItem('remove')">
<el-icon>
<icon name="icon_delete-trash_outlined"

View File

@ -1398,7 +1398,20 @@ const saveQuotaEditCompare = () => {
}
closeQuotaEditCompare()
}
const onToggleHide = item => {
recordSnapshotInfo('render')
switch (item.axisType) {
case 'dimension':
view.value.xAxis[item.index].hide = item.hide
break
case 'quota':
view.value.yAxis[item.index].hide = item.hide
break
default:
break
}
renderChart(view.value)
}
const valueFormatter = item => {
recordSnapshotInfo('render')
state.valueFormatterItem = JSON.parse(JSON.stringify(item))
@ -1964,6 +1977,7 @@ const deleteChartFieldItem = id => {
@onNameEdit="showRename"
@onCustomSort="onCustomSort"
@valueFormatter="valueFormatter"
@onToggleHide="onToggleHide"
/>
</template>
</draggable>
@ -2366,6 +2380,7 @@ const deleteChartFieldItem = id => {
@editItemFilter="showQuotaEditFilter"
@editItemCompare="showQuotaEditCompare"
@valueFormatter="valueFormatter"
@onToggleHide="onToggleHide"
/>
</template>
</draggable>

View File

@ -105,6 +105,9 @@ export class TableInfo extends S2ChartView<TableSheet> {
}
fields.forEach(ele => {
const f = axisMap[ele.dataeaseName]
if (f?.hide === true) {
return
}
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
@ -153,7 +156,9 @@ export class TableInfo extends S2ChartView<TableSheet> {
s2Options.style = this.configStyle(chart, s2DataConfig)
// 自适应列宽模式下URL 字段的宽度固定为 120
if (customAttr.basicStyle.tableColumnMode === 'adapt') {
const urlFields = fields.filter(field => field.deType === 7)
const urlFields = fields.filter(
field => field.deType === 7 && !axisMap[field.dataeaseName]?.hide
)
s2Options.style.colCfg.widthByFieldValue = urlFields?.reduce((p, n) => {
p[n.chartShowName ?? n.name] = 120
return p
@ -236,7 +241,9 @@ export class TableInfo extends S2ChartView<TableSheet> {
return
}
// 第一次渲染初始化把图片字段固定为 120 进行计算
const urlFields = fields.filter(field => field.deType === 7).map(f => f.dataeaseName)
const urlFields = fields
.filter(field => field.deType === 7 && !axisMap[field.dataeaseName]?.hide)
.map(f => f.dataeaseName)
const totalWidthWithImg = ev.colLeafNodes.reduce((p, n) => {
return p + (urlFields.includes(n.field) ? 120 : n.width)
}, 0)

View File

@ -93,6 +93,9 @@ export class TableNormal extends S2ChartView<TableSheet> {
// add drill list
fields.forEach(ele => {
const f = axisMap[ele.dataeaseName]
if (f?.hide === true) {
return
}
columns.push(ele.dataeaseName)
meta.push({
field: ele.dataeaseName,
@ -139,7 +142,9 @@ export class TableNormal extends S2ChartView<TableSheet> {
renderTooltip: sheet => new SortTooltip(sheet)
}
}
// 列宽设置
s2Options.style = this.configStyle(chart, s2DataConfig)
// 行列冻结
if (customAttr.tableCell.tableFreeze) {
s2Options.frozenColCount = customAttr.tableCell.tableColumnFreezeHead ?? 0
s2Options.frozenRowCount = customAttr.tableCell.tableRowFreezeHead ?? 0

View File

@ -485,7 +485,7 @@ export function getStyle(chart: Chart, dataConfig: S2DataConfig): Style {
delete style.layoutWidthType
style.colCfg.width = node => {
const width = node.spreadsheet.container.cfg.el.offsetWidth
const fieldsSize = chart.data?.fields?.length
const fieldsSize = node.spreadsheet.dataCfg.meta.length
if (!fieldsSize) {
return 0
}

View File

@ -25,6 +25,8 @@ public class ChartViewFieldDTO extends ChartViewFieldBaseDTO implements Serializ
private boolean isAgg;
private boolean hide;
/**
* 字段来源
*/