From 46a5c546de42c0a2007e14bad03a5fcc58d98ef7 Mon Sep 17 00:00:00 2001 From: wisonic-s <51065359+wisonic-s@users.noreply.github.com> Date: Fri, 21 Mar 2025 18:34:38 +0800 Subject: [PATCH] =?UTF-8?q?fix(=E5=9B=BE=E8=A1=A8):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E8=A1=A8=E5=92=8C=E6=B1=87=E6=80=BB=E8=A1=A8?= =?UTF-8?q?=E5=BC=80=E5=90=AF=E6=80=BB=E8=AE=A1=E4=B9=8B=E5=90=8E=E5=BA=8F?= =?UTF-8?q?=E5=8F=B7=E5=88=97=E8=AE=A1=E7=AE=97=E9=94=99=E8=AF=AF=E4=BB=A5?= =?UTF-8?q?=E5=8F=8A=E5=9B=BE=E7=89=87=E4=B8=8D=E6=98=BE=E7=A4=BA=20(#1545?= =?UTF-8?q?4)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core-frontend/src/models/chart/chart.d.ts | 6 + .../js/panel/charts/table/table-info.ts | 112 ++++++++++++------ .../js/panel/charts/table/table-normal.ts | 83 +++++++++---- .../js/panel/common/common_table.ts | 92 ++++---------- 4 files changed, 163 insertions(+), 130 deletions(-) diff --git a/core/core-frontend/src/models/chart/chart.d.ts b/core/core-frontend/src/models/chart/chart.d.ts index 90787da11e..aef3385b16 100644 --- a/core/core-frontend/src/models/chart/chart.d.ts +++ b/core/core-frontend/src/models/chart/chart.d.ts @@ -209,3 +209,9 @@ declare interface Filter { datasetTableField: ChartViewField fieldId: string } + +declare interface PageInfo { + currentPage: number + pageSize: number + total: number +} 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 5f52abd437..a36397397f 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 @@ -1,6 +1,5 @@ import { type LayoutResult, - MergedCell, S2DataConfig, S2Event, S2Options, @@ -15,7 +14,7 @@ import { hexColorToRGBA, isAlphaColor, parseJson } from '../../../util' import { S2ChartView, S2DrawOptions } from '../../types/impl/s2' import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common' import { useI18n } from '@/hooks/web/useI18n' -import { isEqual, isNumber, merge } from 'lodash-es' +import { filter, isEqual, isNumber, merge } from 'lodash-es' import { copyContent, CustomDataCell, @@ -23,12 +22,13 @@ import { getRowIndex, calculateHeaderHeight, SortTooltip, - configSummaryRow, summaryRowStyle, configEmptyDataStyle, getLeafNodes, getColumns, - drawImage + drawImage, + getSummaryRow, + SummaryCell } from '@/views/chart/components/js/panel/common/common_table' const { t } = useI18n() @@ -197,37 +197,6 @@ export class TableInfo extends S2ChartView { s2Options.frozenColCount = tableCell.tableColumnFreezeHead ?? 0 s2Options.frozenRowCount = tableCell.tableRowFreezeHead ?? 0 } - // 开启序号之后,第一列就是序号列,修改 label 即可 - if (s2Options.showSeriesNumber) { - let indexLabel = tableHeader.indexLabel - if (!indexLabel) { - indexLabel = '' - } - s2Options.layoutCoordinate = (_, __, col) => { - if (col.colIndex === 0 && col.rowIndex === 0) { - col.label = indexLabel - col.value = indexLabel - } - } - } - s2Options.dataCell = viewMeta => { - const field = fields.filter(f => f.dataeaseName === viewMeta.valueField)?.[0] - if (field?.deType === 7 && chart.showPosition !== 'dialog') { - return new ImageCell(viewMeta, viewMeta?.spreadsheet) - } - if (viewMeta.colIndex === 0 && s2Options.showSeriesNumber) { - if (tableCell.mergeCells) { - viewMeta.fieldValue = getRowIndex(s2Options.mergedCellsInfo, viewMeta) - } else { - viewMeta.fieldValue = - pageInfo.pageSize * (pageInfo.currentPage - 1) + viewMeta.rowIndex + 1 - } - } - // 配置文本自动换行参数 - viewMeta.autoWrap = tableCell.mergeCells ? false : basicStyle.autoWrap - viewMeta.maxLines = basicStyle.maxLines - return new CustomDataCell(viewMeta, viewMeta?.spreadsheet) - } // tooltip this.configTooltip(chart, s2Options) // 合并单元格 @@ -256,8 +225,8 @@ export class TableInfo extends S2ChartView { return new CustomTableColCell(node, sheet, config) } } - // 总计 - configSummaryRow(chart, s2Options, newData, tableHeader, basicStyle, basicStyle.showSummary) + // 序列号和总计行 + this.configSummaryRowAndIndex(chart, pageInfo, s2Options, s2DataConfig) // 开始渲染 const newChart = new TableSheet(containerDom, s2DataConfig, s2Options) // 总计紧贴在单元格后面 @@ -475,6 +444,75 @@ export class TableInfo extends S2ChartView { return theme } + protected configSummaryRowAndIndex( + chart: Chart, + pageInfo: PageInfo, + s2Options: S2Options, + s2DataConfig: S2DataConfig + ) { + const { tableHeader, basicStyle, tableCell } = parseJson(chart.customAttr) + const fields = chart.data?.fields ?? [] + // 开启序号之后,第一列就是序号列,修改 label 即可 + if (s2Options.showSeriesNumber) { + let indexLabel = tableHeader.indexLabel + if (!indexLabel) { + indexLabel = '' + } + s2Options.layoutCoordinate = (_, __, col) => { + if (col.colIndex === 0 && col.rowIndex === 0) { + col.label = indexLabel + col.value = indexLabel + } + } + } + const { showSummary, summaryLabel } = basicStyle + const data = s2DataConfig.data + const xAxis = chart.xAxis + if (showSummary && data?.length) { + // 设置汇总行高度和表头一致 + const heightByField = {} + heightByField[data.length] = tableHeader.tableTitleHeight + s2Options.style.rowCfg = { heightByField } + // 计算汇总加入到数据里,冻结最后一行 + s2Options.frozenTrailingRowCount = 1 + const axis = filter(xAxis, axis => [2, 3, 4].includes(axis.deType)) + const summaryObj = getSummaryRow(data, axis, basicStyle.seriesSummary) as any + data.push(summaryObj) + } + s2Options.dataCell = viewMeta => { + // 总计行处理 + if (showSummary && viewMeta.rowIndex === data.length - 1) { + if (viewMeta.colIndex === 0) { + if (tableHeader.showIndex) { + viewMeta.fieldValue = summaryLabel ?? t('chart.total_show') + } else { + // 第一列不是数值类型的,显示总计 + if (![2, 3, 4].includes(xAxis?.[0]?.deType)) { + viewMeta.fieldValue = summaryLabel ?? t('chart.total_show') + } + } + } + return new SummaryCell(viewMeta, viewMeta?.spreadsheet) + } + const field = fields.find(f => f.dataeaseName === viewMeta.valueField) + if (field?.deType === 7 && chart.showPosition !== 'dialog') { + return new ImageCell(viewMeta, viewMeta?.spreadsheet) + } + if (viewMeta.colIndex === 0 && s2Options.showSeriesNumber) { + if (tableCell.mergeCells) { + viewMeta.fieldValue = getRowIndex(s2Options.mergedCellsInfo, viewMeta) + } else { + viewMeta.fieldValue = + pageInfo.pageSize * (pageInfo.currentPage - 1) + viewMeta.rowIndex + 1 + } + } + // 配置文本自动换行参数 + viewMeta.autoWrap = tableCell.mergeCells ? false : basicStyle.autoWrap + viewMeta.maxLines = basicStyle.maxLines + return new CustomDataCell(viewMeta, viewMeta?.spreadsheet) + } + } + constructor() { super('table-info', []) } 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 5d692d8dbb..5697e84847 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 @@ -2,9 +2,11 @@ import { useI18n } from '@/hooks/web/useI18n' import { formatterItem, valueFormatter } from '@/views/chart/components/js/formatter' import { configEmptyDataStyle, - configSummaryRow, copyContent, + CustomDataCell, + getSummaryRow, SortTooltip, + SummaryCell, summaryRowStyle } from '@/views/chart/components/js/panel/common/common_table' import { S2ChartView, S2DrawOptions } from '@/views/chart/components/js/panel/types/impl/s2' @@ -16,11 +18,10 @@ import { S2Options, ScrollbarPositionType, TableColCell, - TableDataCell, TableSheet, ViewMeta } from '@antv/s2' -import { cloneDeep, isNumber } from 'lodash-es' +import { isNumber } from 'lodash-es' import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common' const { t } = useI18n() @@ -161,26 +162,6 @@ export class TableNormal extends S2ChartView { s2Options.frozenColCount = tableCell.tableColumnFreezeHead ?? 0 s2Options.frozenRowCount = tableCell.tableRowFreezeHead ?? 0 } - // 开启序号之后,第一列就是序号列,修改 label 即可 - if (s2Options.showSeriesNumber) { - let indexLabel = tableHeader.indexLabel - if (!indexLabel) { - indexLabel = '' - } - s2Options.layoutCoordinate = (_, __, col) => { - if (col.colIndex === 0 && col.rowIndex === 0) { - col.label = indexLabel - col.value = indexLabel - } - } - s2Options.dataCell = viewMeta => { - if (viewMeta.colIndex === 0 && s2Options.showSeriesNumber) { - viewMeta.fieldValue = - pageInfo.pageSize * (pageInfo.currentPage - 1) + viewMeta.rowIndex + 1 - } - return new TableDataCell(viewMeta, viewMeta.spreadsheet) - } - } // tooltip this.configTooltip(chart, s2Options) // 隐藏表头,保留顶部的分割线, 禁用表头横向 resize @@ -201,9 +182,8 @@ export class TableNormal extends S2ChartView { chart.container = container this.configHeaderInteraction(chart, s2Options) } - - // 总计 - configSummaryRow(chart, s2Options, newData, tableHeader, basicStyle, basicStyle.showSummary) + // 配置总计和序号列 + this.configSummaryRowAndIndex(chart, pageInfo, s2Options, s2DataConfig) // 开始渲染 const newChart = new TableSheet(containerDom, s2DataConfig, s2Options) // 总计紧贴在单元格后面 @@ -302,6 +282,57 @@ export class TableNormal extends S2ChartView { return newChart } + + protected configSummaryRowAndIndex( + chart: Chart, + pageInfo: PageInfo, + s2Options: S2Options, + s2DataConfig: S2DataConfig + ) { + const { tableHeader, basicStyle } = parseJson(chart.customAttr) + // 开启序号之后,第一列就是序号列,修改 label 即可 + if (s2Options.showSeriesNumber) { + let indexLabel = tableHeader.indexLabel + if (!indexLabel) { + indexLabel = '' + } + s2Options.layoutCoordinate = (_, __, col) => { + if (col.colIndex === 0 && col.rowIndex === 0) { + col.label = indexLabel + col.value = indexLabel + } + } + } + const { showSummary, summaryLabel } = basicStyle + const data = s2DataConfig.data + const { xAxis, yAxis } = chart + if (showSummary && data?.length) { + // 设置汇总行高度和表头一致 + const heightByField = {} + heightByField[data.length] = tableHeader.tableTitleHeight + s2Options.style.rowCfg = { heightByField } + // 计算汇总加入到数据里,冻结最后一行 + s2Options.frozenTrailingRowCount = 1 + const summaryObj = getSummaryRow(data, yAxis, basicStyle.seriesSummary) as any + data.push(summaryObj) + } + s2Options.dataCell = viewMeta => { + // 总计行处理 + if (showSummary && viewMeta.rowIndex === data.length - 1) { + if (viewMeta.colIndex === 0) { + if (tableHeader.showIndex || xAxis?.length) { + viewMeta.fieldValue = summaryLabel ?? t('chart.total_show') + } + } + return new SummaryCell(viewMeta, viewMeta?.spreadsheet) + } + if (viewMeta.colIndex === 0 && s2Options.showSeriesNumber) { + viewMeta.fieldValue = pageInfo.pageSize * (pageInfo.currentPage - 1) + viewMeta.rowIndex + 1 + } + return new CustomDataCell(viewMeta, viewMeta?.spreadsheet) + } + } + constructor() { super('table-normal', []) } 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 aad4d06d1e..e87bad4780 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 @@ -1872,40 +1872,11 @@ const getWrapTextHeight = (wrapText, textStyle, spreadsheet, maxLines) => { 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 || !newData.length) return - // 设置汇总行高度和表头一致 - const heightByField = {} - heightByField[newData.length] = tableHeader.tableTitleHeight - s2Options.style.rowCfg = {heightByField} - // 计算汇总加入到数据里,冻结最后一行 - s2Options.frozenTrailingRowCount = 1 - - const xAxis = chart.xAxis - - const axis = chart.type === 'table-info' - ? filter(chart.xAxis, axis => [2, 3, 4].includes(axis.deType)) - : chart.yAxis - const summaryObj = {SUMMARY: true} +export function getSummaryRow(data, axis, sumCon = []) { + const summaryObj = { SUMMARY: true } for (let i = 0; i < axis.length; i++) { const a = axis[i].dataeaseName - let savedAxis = find(basicStyle.seriesSummary, s => s.field === a) + let savedAxis = find(sumCon, s => s.field === a) if (savedAxis) { if (savedAxis.summary == undefined) { savedAxis.summary = 'sum' @@ -1925,58 +1896,45 @@ export const configSummaryRow = ( } switch (savedAxis.summary) { case 'sum': - summaryObj[a] = sumBy(newData, d => (parseFloat(d[a]) || 0)) + summaryObj[a] = sumBy(data, d => parseFloat(d[a]) || 0) break case 'avg': - summaryObj[a] = meanBy(newData, d => (parseFloat(d[a]) || 0)) + summaryObj[a] = meanBy(data, d => parseFloat(d[a]) || 0) break case 'max': - summaryObj[a] = maxBy(filter(newData, d => parseFloat(d[a]) !== undefined), d => parseFloat(d[a]))[a] + summaryObj[a] = maxBy( + filter(data, d => parseFloat(d[a]) !== undefined), + d => parseFloat(d[a]) + )[a] break case 'min': - summaryObj[a] = minBy(filter(newData, d => parseFloat(d[a]) !== undefined), d => parseFloat(d[a]))[a] + summaryObj[a] = minBy( + filter(data, d => parseFloat(d[a]) !== undefined), + d => parseFloat(d[a]) + )[a] break - case 'var_pop'://方差 - if (newData.length < 2) { + case 'var_pop': //方差 + if (data.length < 2) { continue } else { - const mean = meanBy(newData, d => (parseFloat(d[a]) || 0)) // 计算均值 - const squaredDeviations = map(newData, d => ((parseFloat(d[a]) || 0) - mean) ** 2); // 计算偏差平方 - summaryObj[a] = sum(squaredDeviations) / (size(newData) - 1); // 样本方差(分母n-1) + const mean = meanBy(data, d => parseFloat(d[a]) || 0) // 计算均值 + const squaredDeviations = map(data, d => ((parseFloat(d[a]) || 0) - mean) ** 2) // 计算偏差平方 + summaryObj[a] = sum(squaredDeviations) / (size(data) - 1) // 样本方差(分母n-1) } break - case 'stddev_pop'://标准差 - if (newData.length < 2) { + case 'stddev_pop': //标准差 + if (data.length < 2) { continue } else { - const mean = meanBy(newData, d => (parseFloat(d[a]) || 0)) // 计算均值 - const squaredDeviations = map(newData, d => ((parseFloat(d[a]) || 0) - mean) ** 2); // 计算偏差平方 - const sampleVariance = sum(squaredDeviations) / (size(newData) - 1); // 样本方差(分母n-1) - summaryObj[a] = Math.sqrt(sampleVariance); // 样本标准差 + const mean = meanBy(data, d => parseFloat(d[a]) || 0) // 计算均值 + const squaredDeviations = map(data, d => ((parseFloat(d[a]) || 0) - mean) ** 2) // 计算偏差平方 + const sampleVariance = sum(squaredDeviations) / (size(data) - 1) // 样本方差(分母n-1) + summaryObj[a] = Math.sqrt(sampleVariance) // 样本标准差 } break } } - - newData.push(summaryObj) - s2Options.dataCell = viewMeta => { - // 配置文本自动换行参数 - viewMeta.autoWrap = basicStyle.autoWrap - viewMeta.maxLines = basicStyle.maxLines - if (viewMeta.rowIndex !== newData.length - 1) { - return new CustomDataCell(viewMeta, viewMeta.spreadsheet) - } - if (viewMeta.colIndex === 0) { - if (tableHeader.showIndex) { - viewMeta.fieldValue = basicStyle.summaryLabel ?? i18nt('chart.total_show') - } else { - if (xAxis.length) { - viewMeta.fieldValue = basicStyle.summaryLabel ?? i18nt('chart.total_show') - } - } - } - return new SummaryCell(viewMeta, viewMeta.spreadsheet) - } + return summaryObj } /**