feat(视图-表格): 明细表/汇总表支持表头排序#6754

This commit is contained in:
wisonic-s 2024-01-27 13:55:50 +08:00
parent 2d9a611ab2
commit 0854ef64ca
3 changed files with 187 additions and 5 deletions

View File

@ -1,11 +1,71 @@
import { TableSheet, S2Event, PivotSheet, DataCell, EXTRA_FIELD, TOTAL_VALUE } from '@antv/s2'
import { TableSheet, S2Event, PivotSheet, DataCell, EXTRA_FIELD, TOTAL_VALUE, BaseTooltip, getAutoAdjustPosition,
getTooltipDefaultOptions,
setTooltipContainerStyle } from '@antv/s2'
import { getCustomTheme, getSize } from '@/views/chart/chart/common/common_table'
import { DEFAULT_COLOR_CASE, DEFAULT_TOTAL } from '@/views/chart/chart/chart'
import { formatterItem, valueFormatter } from '@/views/chart/chart/formatter'
import { handleTableEmptyStrategy, hexColorToRGBA } from '@/views/chart/chart/util'
import { maxBy, minBy, find } from 'lodash-es'
import TableTooltip from '@/views/chart/components/table/TableTooltip.vue'
class SortTooltip extends BaseTooltip {
vueCom
constructor(spreadsheet, vueCom) {
super(spreadsheet)
this.vueCom = vueCom
}
export function baseTableInfo(s2, container, chart, action, tableData, pageInfo) {
show(showOptions) {
const { iconName } = showOptions
if (iconName) {
this.showSortTooltip(showOptions)
return
}
super.show(showOptions)
}
showSortTooltip(showOptions) {
const { position, options, meta, event } = showOptions
const { enterable } = getTooltipDefaultOptions(options)
const { autoAdjustBoundary, adjustPosition } =
this.spreadsheet.options.tooltip || {}
this.visible = true
this.options = showOptions
const container = this.getContainer()
// 用 vue 手动 patch
const vNode = this.vueCom.$createElement(TableTooltip, {
props: {
table: this.spreadsheet,
meta
}
})
this.spreadsheet.tooltip.container.innerHTML = ''
const childElement = document.createElement('div')
this.spreadsheet.tooltip.container.appendChild(childElement)
this.vueCom.__patch__(childElement, vNode, false, true)
const { x, y } = getAutoAdjustPosition({
spreadsheet: this.spreadsheet,
position,
tooltipContainer: container,
autoAdjustBoundary
})
this.position = adjustPosition?.({ position: { x, y }, event }) ?? {
x,
y
}
setTooltipContainerStyle(container, {
style: {
left: `${this.position?.x}px`,
top: `${this.position?.y}px`,
pointerEvents: enterable ? 'all' : 'none'
},
visible: true
})
}
}
export function baseTableInfo(s2, container, chart, action, tableData, pageInfo, vueCom) {
const containerDom = document.getElementById(container)
// fields
@ -87,12 +147,44 @@ export function baseTableInfo(s2, container, chart, action, tableData, pageInfo)
}
const customAttr = JSON.parse(chart.customAttr)
const sortIconMap = {
'asc': 'SortUp',
'desc': 'SortDown'
}
// options
const s2Options = {
width: containerDom.offsetWidth,
height: containerDom.offsetHeight,
showSeriesNumber: customAttr.size.showIndex,
style: getSize(chart),
tooltip: {
renderTooltip: sheet => new SortTooltip(sheet, vueCom)
},
headerActionIcons: [
{
iconNames: ['GroupAsc', 'SortUp', 'SortDown'],
belongsCell: 'colCell',
displayCondition: (meta, iconName) => {
const sortMethodMap = meta.spreadsheet.store.get('sortMethodMap')
const sortType = sortMethodMap?.[meta.field]
if (sortType) {
return iconName === sortIconMap[sortType]
}
return iconName === 'GroupAsc'
},
onClick: (props) => {
const { meta, event } = props
meta.spreadsheet.showTooltip({
position: {
x: event.clientX,
y: event.clientY
},
event,
...props
})
}
}
],
conditions: getConditions(chart),
frozenColCount: customAttr.size.tableColumnFreezeHead ?? 0,
frozenRowCount: customAttr.size.tableRowFreezeHead ?? 0
@ -150,7 +242,7 @@ export function baseTableInfo(s2, container, chart, action, tableData, pageInfo)
return s2
}
export function baseTableNormal(s2, container, chart, action, tableData) {
export function baseTableNormal(s2, container, chart, action, tableData, vueCom) {
const containerDom = document.getElementById(container)
if (!containerDom) return
@ -281,12 +373,44 @@ export function baseTableNormal(s2, container, chart, action, tableData) {
}
const customAttr = JSON.parse(chart.customAttr)
const sortIconMap = {
'asc': 'SortUp',
'desc': 'SortDown'
}
// options
const s2Options = {
width: containerDom.offsetWidth,
height: containerDom.offsetHeight,
showSeriesNumber: customAttr.size.showIndex,
style: getSize(chart),
tooltip: {
renderTooltip: sheet => new SortTooltip(sheet, vueCom)
},
headerActionIcons: [
{
iconNames: ['GroupAsc', 'SortUp', 'SortDown'],
belongsCell: 'colCell',
displayCondition: (meta, iconName) => {
const sortMethodMap = meta.spreadsheet.store.get('sortMethodMap')
const sortType = sortMethodMap?.[meta.field]
if (sortType) {
return iconName === sortIconMap[sortType]
}
return iconName === 'GroupAsc'
},
onClick: (props) => {
const { meta, event } = props
meta.spreadsheet.showTooltip({
position: {
x: event.clientX,
y: event.clientY
},
event,
...props
})
}
}
],
conditions: getConditions(chart),
frozenColCount: customAttr.size.tableColumnFreezeHead ?? 0,
frozenRowCount: customAttr.size.tableRowFreezeHead ?? 0

View File

@ -296,9 +296,9 @@ export default {
}
}
if (chart.type === 'table-info') {
this.myChart = baseTableInfo(this.myChart, this.chartId, chart, this.antVAction, this.tableData, this.currentPage)
this.myChart = baseTableInfo(this.myChart, this.chartId, chart, this.antVAction, this.tableData, this.currentPage, this)
} else if (chart.type === 'table-normal') {
this.myChart = baseTableNormal(this.myChart, this.chartId, chart, this.antVAction, this.tableData)
this.myChart = baseTableNormal(this.myChart, this.chartId, chart, this.antVAction, this.tableData, this)
} else if (chart.type === 'table-pivot') {
this.myChart = baseTablePivot(this.myChart, this.chartId, chart, this.antVAction, this.tableHeaderClick, this.tableData)
} else {

View File

@ -0,0 +1,58 @@
<template>
<el-col>
<el-row>
<i class="el-icon-sort-up" />
<span
class="sort-btn"
@click="() => sort('asc')"
>{{ __t('chart.asc') }}</span>
</el-row>
<el-row>
<i class="el-icon-sort-down" />
<span
class="sort-btn"
@click="() => sort('desc')"
>{{ __t('chart.desc') }}</span>
</el-row>
<el-row>
<i class="el-icon-sort" />
<span
class="sort-btn"
@click="() => sort()"
>{{ __t('chart.default') }}</span>
</el-row>
</el-col>
</template>
<script>
import i18n from '@/lang'
export default {
name: 'TableTooltip',
props: {
table: {
type: Object,
required: true
},
meta: {
type: Object,
required: true
}
},
methods: {
sort(type) {
this.table.updateSortMethodMap(this.meta.field, type, true)
this.table.emit('sort:range-sort', {
sortFieldId: this.meta.field,
sortMethod: type
})
},
__t(key) {
return i18n.t(key)
}
}
}
</script>
<style scoped>
.sort-btn {
cursor: pointer;
}
</style>