From 4bd3dbcd7516aab5dac6344931be284978563a4b Mon Sep 17 00:00:00 2001 From: wisonic Date: Mon, 8 Jul 2024 19:16:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E8=A7=86=E5=9B=BE):=20=E6=B1=87=E6=80=BB?= =?UTF-8?q?=E8=A1=A8=E6=94=AF=E6=8C=81=E6=98=BE=E7=A4=BA=E6=80=BB=E8=AE=A1?= =?UTF-8?q?=20#9589?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/core-frontend/src/locales/zh-CN.ts | 2 + .../src/models/chart/chart-attr.d.ts | 8 +++ .../components/editor/common/TableTooltip.vue | 39 +++++++++-- .../components/BasicStyleSelector.vue | 27 +++++++ .../chart/components/editor/util/chart.ts | 4 +- .../js/panel/charts/table/table-normal.ts | 70 ++++++++++++++++--- .../components/js/panel/types/impl/s2.ts | 4 ++ .../views/components/ChartComponentS2.vue | 1 - 8 files changed, 138 insertions(+), 17 deletions(-) diff --git a/core/core-frontend/src/locales/zh-CN.ts b/core/core-frontend/src/locales/zh-CN.ts index c1e0b56671..4a0f3732f1 100644 --- a/core/core-frontend/src/locales/zh-CN.ts +++ b/core/core-frontend/src/locales/zh-CN.ts @@ -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: '结束角度', diff --git a/core/core-frontend/src/models/chart/chart-attr.d.ts b/core/core-frontend/src/models/chart/chart-attr.d.ts index b725a79615..a056b401cd 100644 --- a/core/core-frontend/src/models/chart/chart-attr.d.ts +++ b/core/core-frontend/src/models/chart/chart-attr.d.ts @@ -256,6 +256,14 @@ declare interface ChartBasicStyle { * 对称柱状图方向 */ layout?: 'horizontal' | 'vertical' + /** + * 汇总表显示总计 + */ + showSummary: boolean + /** + * 汇总表总计标签 + */ + summaryLabel: string } /** * 表头属性 diff --git a/core/core-frontend/src/views/chart/components/editor/common/TableTooltip.vue b/core/core-frontend/src/views/chart/components/editor/common/TableTooltip.vue index 48640d00f2..0bf1d5fc43 100644 --- a/core/core-frontend/src/views/chart/components/editor/common/TableTooltip.vue +++ b/core/core-frontend/src/views/chart/components/editor/common/TableTooltip.vue @@ -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 + type: Object as PropType, + 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 } ]) } diff --git a/core/core-frontend/src/views/chart/components/editor/editor-style/components/BasicStyleSelector.vue b/core/core-frontend/src/views/chart/components/editor/editor-style/components/BasicStyleSelector.vue index 11a9ada0f6..fd8a3694bf 100644 --- a/core/core-frontend/src/views/chart/components/editor/editor-style/components/BasicStyleSelector.vue +++ b/core/core-frontend/src/views/chart/components/editor/editor-style/components/BasicStyleSelector.vue @@ -957,6 +957,33 @@ onMounted(() => { + + + {{ t('chart.table_show_summary') }} + + + + + { 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 { // 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 { super('table-normal', []) } } + +class SummaryCell extends TableDataCell { + getTextStyle() { + return this.theme.colCell.bolderText + } + getBackgroundColor() { + const { backgroundColor, backgroundColorOpacity } = this.theme.colCell.cell + return { backgroundColor, backgroundColorOpacity } + } +} diff --git a/core/core-frontend/src/views/chart/components/js/panel/types/impl/s2.ts b/core/core-frontend/src/views/chart/components/js/panel/types/impl/s2.ts index 3188b96972..05cedb33a6 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/types/impl/s2.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/types/impl/s2.ts @@ -69,6 +69,10 @@ export abstract class S2ChartView

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' diff --git a/core/core-frontend/src/views/chart/components/views/components/ChartComponentS2.vue b/core/core-frontend/src/views/chart/components/views/components/ChartComponentS2.vue index 234193682c..3917c5d975 100644 --- a/core/core-frontend/src/views/chart/components/views/components/ChartComponentS2.vue +++ b/core/core-frontend/src/views/chart/components/views/components/ChartComponentS2.vue @@ -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))