diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-info.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-info.ts index 043f127649..590aaedd8e 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-info.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-info.ts @@ -20,7 +20,9 @@ import { CustomTableColCell, getRowIndex, calculateHeaderHeight, - SortTooltip + SortTooltip, + configSummaryRow, + summaryRowStyle } from '@/views/chart/components/js/panel/common/common_table' const { t } = useI18n() @@ -68,7 +70,9 @@ export class TableInfo extends S2ChartView { 'alpha', 'tablePageMode', 'showHoverStyle', - 'autoWrap' + 'autoWrap', + 'showSummary', + 'summaryLabel' ], 'table-cell-selector': [ ...TABLE_EDITOR_PROPERTY_INNER['table-cell-selector'], @@ -240,8 +244,12 @@ export class TableInfo extends S2ChartView { return new CustomTableColCell(node, sheet, config) } } + // 总计 + configSummaryRow(chart, s2Options, newData, tableHeader, basicStyle, basicStyle.showSummary) // 开始渲染 const newChart = new TableSheet(containerDom, s2DataConfig, s2Options) + // 总计紧贴在单元格后面 + summaryRowStyle(newChart, newData, tableCell, tableHeader, basicStyle.showSummary) // 开启自动换行 if (basicStyle.autoWrap) { // 调整表头宽度时,计算表头高度 diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-normal.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-normal.ts index e545f72417..8e6e56ee2a 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-normal.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-normal.ts @@ -1,9 +1,10 @@ import { useI18n } from '@/hooks/web/useI18n' import { formatterItem, valueFormatter } from '@/views/chart/components/js/formatter' import { + configSummaryRow, copyContent, - CustomDataCell, - SortTooltip + SortTooltip, + summaryRowStyle } 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' @@ -189,56 +190,11 @@ export class TableNormal extends S2ChartView { } // 总计 - if (basicStyle.showSummary) { - // 设置汇总行高度和表头一致 - const heightByField = {} - heightByField[newData.length] = 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] = - (parseFloat(n[axis.dataeaseName]) || 0) + (parseFloat(p[axis.dataeaseName]) || 0) - }) - return p - }, - { SUMMARY: true } - ) - newData.push(summaryObj) - s2Options.dataCell = viewMeta => { - if (viewMeta.rowIndex !== newData.length - 1) { - return new CustomDataCell(viewMeta, viewMeta.spreadsheet) - } - if (viewMeta.colIndex === 0) { - if (tableHeader.showIndex) { - viewMeta.fieldValue = basicStyle.summaryLabel ?? '总计' - } else { - if (xAxis.length) { - viewMeta.fieldValue = basicStyle.summaryLabel ?? '总计' - } - } - } - return new SummaryCell(viewMeta, viewMeta.spreadsheet) - } - } + configSummaryRow(chart, s2Options, newData, tableHeader, basicStyle, basicStyle.showSummary) // 开始渲染 const newChart = new TableSheet(containerDom, s2DataConfig, s2Options) // 总计紧贴在单元格后面 - if (basicStyle.showSummary) { - newChart.on(S2Event.LAYOUT_BEFORE_RENDER, () => { - const totalHeight = - tableHeader.tableTitleHeight * 2 + tableCell.tableItemHeight * (newData.length - 1) - if (totalHeight < newChart.options.height) { - // 6 是阴影高度 - newChart.options.height = - totalHeight < newChart.options.height - 6 ? totalHeight + 6 : totalHeight - } - }) - } + summaryRowStyle(newChart, newData, tableCell, tableHeader, basicStyle.showSummary) // 自适应铺满 if (basicStyle.tableColumnMode === 'adapt') { newChart.on(S2Event.LAYOUT_RESIZE_COL_WIDTH, () => { @@ -334,15 +290,3 @@ export class TableNormal extends S2ChartView { super('table-normal', []) } } - -class SummaryCell extends CustomDataCell { - getTextStyle() { - const textStyle = cloneDeep(this.theme.colCell.bolderText) - textStyle.textAlign = this.theme.dataCell.text.textAlign - return textStyle - } - getBackgroundColor() { - const { backgroundColor, backgroundColorOpacity } = this.theme.colCell.cell - return { backgroundColor, backgroundColorOpacity } - } -} diff --git a/core/core-frontend/src/views/chart/components/js/panel/common/common_table.ts b/core/core-frontend/src/views/chart/components/js/panel/common/common_table.ts index d11b58fb69..7944bb6819 100644 --- a/core/core-frontend/src/views/chart/components/js/panel/common/common_table.ts +++ b/core/core-frontend/src/views/chart/components/js/panel/common/common_table.ts @@ -28,7 +28,7 @@ import { type PivotSheet, renderPolygon, renderText, - S2DataConfig, + S2DataConfig, S2Event, S2Options, S2Theme, SERIES_NUMBER_FIELD, @@ -40,13 +40,15 @@ import { TableDataCell, updateShapeAttr, ViewMeta -} from '@antv/s2' +} from "@antv/s2"; import { cloneDeep, filter, find, intersection, keys, merge, repeat } from 'lodash-es' import { createVNode, render } from 'vue' import TableTooltip from '@/views/chart/components/editor/common/TableTooltip.vue' import Exceljs from 'exceljs' import { saveAs } from 'file-saver' import { ElMessage } from 'element-plus-secondary' +import { useI18n } from '@/hooks/web/useI18n' +const { t } = useI18n() export function getCustomTheme(chart: Chart): S2Theme { const headerColor = hexColorToRGBA( @@ -1748,3 +1750,92 @@ const getWrapTextHeight = (wrapText, textStyle, spreadsheet, maxLines) => { const lines = wrapText.split('\n').length return Math.min(lines, maxLines) * maxHeight } + +/** + * 设置汇总行 + * @param chart + * @param s2Options + * @param newData + * @param tableHeader + * @param basicStyle + * @param showSummary + */ +export const configSummaryRow = (chart, s2Options, newData, tableHeader, basicStyle, showSummary) =>{ + if (!showSummary) return + // 设置汇总行高度和表头一致 + const heightByField = {} + heightByField[newData.length] = tableHeader.tableTitleHeight + s2Options.style.rowCfg = { heightByField } + // 计算汇总加入到数据里,冻结最后一行 + s2Options.frozenTrailingRowCount = 1 + const yAxis = chart.yAxis + const xAxis = chart.xAxis + const summaryObj = newData.reduce( + (p, n) => { + if (chart.type === 'table-info') { + xAxis + .filter(axis => [2, 3, 4].includes(axis.deType)) + .forEach(axis => { + p[axis.dataeaseName] = + (parseFloat(n[axis.dataeaseName]) || 0) + (parseFloat(p[axis.dataeaseName]) || 0) + }) + } else { + yAxis.forEach(axis => { + p[axis.dataeaseName] = + (parseFloat(n[axis.dataeaseName]) || 0) + (parseFloat(p[axis.dataeaseName]) || 0) + }) + } + return p + }, + { SUMMARY: true } + ) + newData.push(summaryObj) + s2Options.dataCell = viewMeta => { + if (viewMeta.rowIndex !== newData.length - 1) { + return new CustomDataCell(viewMeta, viewMeta.spreadsheet) + } + if (viewMeta.colIndex === 0) { + if (tableHeader.showIndex) { + viewMeta.fieldValue = basicStyle.summaryLabel ?? t('chart.total_show') + } else { + if (xAxis.length) { + viewMeta.fieldValue = basicStyle.summaryLabel ?? t('chart.total_show') + } + } + } + return new SummaryCell(viewMeta, viewMeta.spreadsheet) + } +} + +/** + * 汇总行样式,紧贴在单元格后面 + * @param newChart + * @param newData + * @param tableCell + * @param tableHeader + * @param showSummary + */ +export const summaryRowStyle = (newChart, newData, tableCell, tableHeader, showSummary) => { + if (!showSummary) return + newChart.on(S2Event.LAYOUT_BEFORE_RENDER, () => { + const totalHeight = + tableHeader.tableTitleHeight * 2 + tableCell.tableItemHeight * (newData.length - 1) + if (totalHeight < newChart.options.height) { + // 6 是阴影高度 + newChart.options.height = + totalHeight < newChart.options.height - 6 ? totalHeight + 6 : totalHeight + } + }) +} + +export class SummaryCell extends CustomDataCell { + getTextStyle() { + const textStyle = cloneDeep(this.theme.colCell.bolderText) + textStyle.textAlign = this.theme.dataCell.text.textAlign + return textStyle + } + getBackgroundColor() { + const { backgroundColor, backgroundColorOpacity } = this.theme.colCell.cell + return { backgroundColor, backgroundColorOpacity } + } +}