feat(视图): 汇总表支持显示总计 #9589
This commit is contained in:
parent
0e0def7309
commit
4bd3dbcd75
@ -733,6 +733,8 @@ export default {
|
||||
table_show_col_tooltip: '开启列头提示',
|
||||
table_show_cell_tooltip: '开启单元格提示',
|
||||
table_show_header_tooltip: '开启表头提示',
|
||||
table_show_summary: '显示总计',
|
||||
table_summary_label: '总计标签',
|
||||
stripe: '斑马纹',
|
||||
start_angle: '起始角度',
|
||||
end_angle: '结束角度',
|
||||
|
||||
@ -256,6 +256,14 @@ declare interface ChartBasicStyle {
|
||||
* 对称柱状图方向
|
||||
*/
|
||||
layout?: 'horizontal' | 'vertical'
|
||||
/**
|
||||
* 汇总表显示总计
|
||||
*/
|
||||
showSummary: boolean
|
||||
/**
|
||||
* 汇总表总计标签
|
||||
*/
|
||||
summaryLabel: string
|
||||
}
|
||||
/**
|
||||
* 表头属性
|
||||
|
||||
@ -2,8 +2,9 @@
|
||||
import { SpreadSheet, Node } from '@antv/s2'
|
||||
import { PropType } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { S2Event } from '@antv/s2'
|
||||
import { S2Event, SortFuncParam } from '@antv/s2'
|
||||
import { SortUp, SortDown, Sort } from '@element-plus/icons-vue'
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
|
||||
const { t } = useI18n()
|
||||
const props = defineProps({
|
||||
@ -12,15 +13,45 @@ const props = defineProps({
|
||||
required: true
|
||||
},
|
||||
meta: {
|
||||
type: Object as PropType<Node>
|
||||
type: Object as PropType<Node>,
|
||||
required: true
|
||||
}
|
||||
})
|
||||
const sort = type => {
|
||||
const sortFunc = (sortParams: SortFuncParam) => {
|
||||
if (!sortParams.sortMethod) {
|
||||
return sortParams.data
|
||||
}
|
||||
const data = cloneDeep(sortParams.data)
|
||||
return data.sort((a, b) => {
|
||||
// 总计行放最后
|
||||
if (a['SUMMARY']) {
|
||||
return 1
|
||||
}
|
||||
const field = sortParams.sortFieldId
|
||||
const aValue = a[field]
|
||||
const bValue = b[field]
|
||||
if (aValue === bValue) {
|
||||
return 0
|
||||
}
|
||||
if (sortParams.sortMethod === 'asc') {
|
||||
if (typeof aValue === 'number') {
|
||||
return aValue - bValue
|
||||
}
|
||||
return aValue < bValue ? 1 : -1
|
||||
}
|
||||
if (typeof aValue === 'number') {
|
||||
return bValue - aValue
|
||||
}
|
||||
return aValue > bValue ? 1 : -1
|
||||
})
|
||||
}
|
||||
const sort = (type?) => {
|
||||
props.table.updateSortMethodMap(props.meta.field, type, true)
|
||||
props.table.emit(S2Event.RANGE_SORT, [
|
||||
{
|
||||
sortFieldId: props.meta.field,
|
||||
sortMethod: type
|
||||
sortMethod: type,
|
||||
sortFunc
|
||||
}
|
||||
])
|
||||
}
|
||||
|
||||
@ -957,6 +957,33 @@ onMounted(() => {
|
||||
<template #append>%</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="showProperty('showSummary')"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
>
|
||||
<el-checkbox
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="state.basicStyleForm.showSummary"
|
||||
@change="changeBasicStyle('showSummary')"
|
||||
>
|
||||
{{ t('chart.table_show_summary') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="showProperty('summaryLabel') && state.basicStyleForm.showSummary"
|
||||
:label="$t('chart.table_summary_label')"
|
||||
:class="'form-item-' + themes"
|
||||
class="form-item"
|
||||
>
|
||||
<el-input
|
||||
v-model="state.basicStyleForm.summaryLabel"
|
||||
type="text"
|
||||
:max-length="10"
|
||||
@blur="changeBasicStyle('summaryLabel')"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!--table2 end-->
|
||||
<!--gauge start-->
|
||||
<el-form-item
|
||||
|
||||
@ -1483,7 +1483,9 @@ export const DEFAULT_BASIC_STYLE: ChartBasicStyle = {
|
||||
topN: 5,
|
||||
topNLabel: '其他',
|
||||
gaugeAxisLine: true,
|
||||
gaugePercentLabel: true
|
||||
gaugePercentLabel: true,
|
||||
showSummary: false,
|
||||
summaryLabel: '总计'
|
||||
}
|
||||
|
||||
export const BASE_VIEW_CONFIG = {
|
||||
|
||||
@ -1,15 +1,11 @@
|
||||
import { S2ChartView, S2DrawOptions } from '@/views/chart/components/js/panel/types/impl/s2'
|
||||
import { S2Event, S2Options, TableSheet, TableColCell, ViewMeta, TableDataCell } from '@antv/s2'
|
||||
import { parseJson } from '@/views/chart/components/js/util'
|
||||
import { formatterItem, valueFormatter } from '@/views/chart/components/js/formatter'
|
||||
import {
|
||||
copyContent,
|
||||
getCurrentField,
|
||||
SortTooltip
|
||||
} from '@/views/chart/components/js/panel/common/common_table'
|
||||
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { formatterItem, valueFormatter } from '@/views/chart/components/js/formatter'
|
||||
import { copyContent, SortTooltip } from '@/views/chart/components/js/panel/common/common_table'
|
||||
import { S2ChartView, S2DrawOptions } from '@/views/chart/components/js/panel/types/impl/s2'
|
||||
import { parseJson } from '@/views/chart/components/js/util'
|
||||
import { S2Event, S2Options, TableColCell, TableDataCell, TableSheet, ViewMeta } from '@antv/s2'
|
||||
import { isNumber } from 'lodash-es'
|
||||
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
|
||||
|
||||
const { t } = useI18n()
|
||||
/**
|
||||
@ -17,12 +13,17 @@ const { t } = useI18n()
|
||||
*/
|
||||
export class TableNormal extends S2ChartView<TableSheet> {
|
||||
properties = TABLE_EDITOR_PROPERTY
|
||||
propertyInner = {
|
||||
propertyInner: EditorPropertyInner = {
|
||||
...TABLE_EDITOR_PROPERTY_INNER,
|
||||
'table-header-selector': [
|
||||
...TABLE_EDITOR_PROPERTY_INNER['table-header-selector'],
|
||||
'tableHeaderSort',
|
||||
'showTableHeader'
|
||||
],
|
||||
'basic-style-selector': [
|
||||
...TABLE_EDITOR_PROPERTY_INNER['basic-style-selector'],
|
||||
'showSummary',
|
||||
'summaryLabel'
|
||||
]
|
||||
}
|
||||
axis: AxisType[] = ['xAxis', 'yAxis', 'drill', 'filter']
|
||||
@ -160,6 +161,43 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
// header interaction
|
||||
this.configHeaderInteraction(chart, s2Options)
|
||||
}
|
||||
|
||||
// 总计
|
||||
if (customAttr.basicStyle.showSummary) {
|
||||
// 设置汇总行高度和表头一致
|
||||
const heightByField = {}
|
||||
heightByField[newData.length] = customAttr.tableHeader.tableTitleHeight
|
||||
s2Options.style.rowCfg = { heightByField }
|
||||
// 计算汇总加入到数据里,冻结最后一行
|
||||
s2Options.frozenTrailingRowCount = 1
|
||||
const yAxis = chart.yAxis
|
||||
const xAxis = chart.xAxis
|
||||
const summaryObj = newData.reduce(
|
||||
(p, n) => {
|
||||
yAxis.forEach(axis => {
|
||||
p[axis.dataeaseName] = (n[axis.dataeaseName] || 0) + (p[axis.dataeaseName] || 0)
|
||||
})
|
||||
return p
|
||||
},
|
||||
{ SUMMARY: true }
|
||||
)
|
||||
newData.push(summaryObj)
|
||||
s2Options.dataCell = viewMeta => {
|
||||
if (viewMeta.rowIndex !== newData.length - 1) {
|
||||
return new TableDataCell(viewMeta, viewMeta.spreadsheet)
|
||||
}
|
||||
if (viewMeta.colIndex === 0) {
|
||||
if (customAttr.tableHeader.showIndex) {
|
||||
viewMeta.fieldValue = customAttr.basicStyle.summaryLabel ?? '总计'
|
||||
} else {
|
||||
if (xAxis.length) {
|
||||
viewMeta.fieldValue = customAttr.basicStyle.summaryLabel ?? '总计'
|
||||
}
|
||||
}
|
||||
}
|
||||
return new SummaryCell(viewMeta, viewMeta.spreadsheet)
|
||||
}
|
||||
}
|
||||
// 开始渲染
|
||||
const newChart = new TableSheet(containerDom, s2DataConfig, s2Options)
|
||||
|
||||
@ -211,3 +249,13 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
super('table-normal', [])
|
||||
}
|
||||
}
|
||||
|
||||
class SummaryCell extends TableDataCell {
|
||||
getTextStyle() {
|
||||
return this.theme.colCell.bolderText
|
||||
}
|
||||
getBackgroundColor() {
|
||||
const { backgroundColor, backgroundColorOpacity } = this.theme.colCell.cell
|
||||
return { backgroundColor, backgroundColorOpacity }
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,6 +69,10 @@ export abstract class S2ChartView<P extends SpreadSheet> extends AntVAbstractCha
|
||||
let field
|
||||
switch (cell.cellType) {
|
||||
case 'dataCell':
|
||||
if (meta.valueField === SERIES_NUMBER_FIELD) {
|
||||
content = meta.fieldValue
|
||||
break
|
||||
}
|
||||
field = find(metaConfig, item => item.field === meta.valueField)
|
||||
if (meta.fieldValue === 0) {
|
||||
content = '0'
|
||||
|
||||
@ -116,7 +116,6 @@ const calcData = (view: Chart, callback, resetPageInfo = true) => {
|
||||
} else {
|
||||
delete view.chartExtRequest.pageSize
|
||||
}
|
||||
console.log(view)
|
||||
if (view.tableId || view['dataFrom'] === 'template') {
|
||||
isError.value = false
|
||||
const v = JSON.parse(JSON.stringify(view))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user