mirror of
https://github.com/dataease/dataease.git
synced 2026-05-15 13:32:18 +08:00
fix(图表): 修复明细表基础样式勾选“自动换行”后,会出现表头部分部分信息不显示的问题 #16804
This commit is contained in:
committed by
jianneng-fit2cloud
parent
4e482fc860
commit
84f4a7386f
@@ -16,21 +16,22 @@ import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { filter, isEqual, isNumber, merge } from 'lodash-es'
|
||||
import {
|
||||
calcTreeWidth,
|
||||
calculateGroupHeaderHeight,
|
||||
calculateHeaderHeight,
|
||||
configEmptyDataStyle,
|
||||
copyContent,
|
||||
CustomDataCell,
|
||||
CustomTableColCell,
|
||||
getRowIndex,
|
||||
calculateHeaderHeight,
|
||||
SortTooltip,
|
||||
configEmptyDataStyle,
|
||||
getLeafNodes,
|
||||
getColumns,
|
||||
drawImage,
|
||||
getColumns,
|
||||
getLeafNodes,
|
||||
getRowIndex,
|
||||
getStartPosition,
|
||||
getSummaryRow,
|
||||
SortTooltip,
|
||||
SummaryCell,
|
||||
summaryRowStyle,
|
||||
calcTreeWidth,
|
||||
getStartPosition
|
||||
summaryRowStyle
|
||||
} from '@/views/chart/components/js/panel/common/common_table'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -236,28 +237,48 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
||||
summaryRowStyle(newChart, newData, tableCell, tableHeader, basicStyle.showSummary)
|
||||
// 开启自动换行
|
||||
if (basicStyle.autoWrap && !tableCell.mergeCells) {
|
||||
// 调整表头宽度时,计算表头高度
|
||||
// 记录调整列宽的信息
|
||||
const setResizeColWidthInfo = (info?) => {
|
||||
newChart.store.set('resizeColWidthInfo', info ? info : undefined)
|
||||
}
|
||||
setResizeColWidthInfo()
|
||||
// 计算分组表头的高度
|
||||
newChart.on(S2Event.LAYOUT_BEFORE_RENDER, () => {
|
||||
calculateGroupHeaderHeight(newChart, tableHeader, basicStyle)
|
||||
setResizeColWidthInfo()
|
||||
})
|
||||
// 调整行高不能小于初始行高
|
||||
newChart.on(S2Event.LAYOUT_RESIZE_COL_HEIGHT, info => {
|
||||
if (info.info.resizedHeight < newChart.options.style.colCfg.height) {
|
||||
info.style.colCfg.heightByField[info.info.id] = newChart.options.style.colCfg.height
|
||||
}
|
||||
})
|
||||
// 调整表头单元格宽度时,计算表头高度
|
||||
newChart.on(S2Event.LAYOUT_RESIZE_COL_WIDTH, info => {
|
||||
setResizeColWidthInfo(info.info)
|
||||
calculateHeaderHeight(info, newChart, tableHeader, basicStyle, null)
|
||||
})
|
||||
newChart.on(S2Event.LAYOUT_AFTER_HEADER_LAYOUT, (ev: LayoutResult) => {
|
||||
const maxHeight = newChart.store.get('autoCalcHeight') as number
|
||||
if (maxHeight) {
|
||||
// 更新列的高度
|
||||
ev.colLeafNodes.forEach(n => (n.height = maxHeight))
|
||||
ev.colsHierarchy.height = maxHeight
|
||||
newChart.store.set('autoCalcHeight', undefined)
|
||||
} else {
|
||||
if (ev.colLeafNodes?.length) {
|
||||
const { value, width } = ev.colLeafNodes[0]
|
||||
calculateHeaderHeight(
|
||||
{ info: { meta: { value }, resizedWidth: width } },
|
||||
newChart,
|
||||
tableHeader,
|
||||
basicStyle,
|
||||
ev
|
||||
)
|
||||
}
|
||||
if (ev.colLeafNodes?.length) {
|
||||
const { value, width } = ev.colLeafNodes[0]
|
||||
calculateHeaderHeight(
|
||||
{ info: { meta: { value }, resizedWidth: width } },
|
||||
newChart,
|
||||
tableHeader,
|
||||
basicStyle,
|
||||
ev
|
||||
)
|
||||
}
|
||||
if (tableHeader.headerGroup) {
|
||||
const groupHeight = ev.colNodes.filter(node => node.colIndex === -1)?.[0]?.height || 0
|
||||
ev.colsHierarchy.height =
|
||||
ev.colsHierarchy.height + ev.colsHierarchy.maxLevel * groupHeight
|
||||
ev.colLeafNodes.forEach(node => {
|
||||
if (node.level < ev.colsHierarchy.maxLevel) {
|
||||
const addHeight = ev.colsHierarchy.maxLevel - node.level
|
||||
node.height = node.height + addHeight * groupHeight
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -59,7 +59,8 @@ import {
|
||||
repeat,
|
||||
sumBy,
|
||||
size,
|
||||
sum
|
||||
sum,
|
||||
isNumber
|
||||
} from 'lodash-es'
|
||||
import { createVNode, render } from 'vue'
|
||||
import TableTooltip from '@/views/chart/components/editor/common/TableTooltip.vue'
|
||||
@@ -69,7 +70,6 @@ import { ElMessage } from 'element-plus-secondary'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import Decimal from 'decimal.js'
|
||||
|
||||
|
||||
const { t: i18nt } = useI18n()
|
||||
|
||||
export function getCustomTheme(chart: Chart): S2Theme {
|
||||
@@ -1874,10 +1874,15 @@ export async function exportRowQuotaTreePivot(instance: PivotSheet, chart: Chart
|
||||
saveAs(dataBlob, `${chart.title ?? '透视表'}.xlsx`)
|
||||
}
|
||||
|
||||
function extractNumber(formattedValue: string, formatterCfg: BaseFormatter): {
|
||||
value: number
|
||||
numFmt: string
|
||||
} | string {
|
||||
function extractNumber(
|
||||
formattedValue: string,
|
||||
formatterCfg: BaseFormatter
|
||||
):
|
||||
| {
|
||||
value: number
|
||||
numFmt: string
|
||||
}
|
||||
| string {
|
||||
if (!formatterCfg) {
|
||||
return formattedValue
|
||||
}
|
||||
@@ -2255,9 +2260,9 @@ const drawTextShape = (cell, isHeader) => {
|
||||
cell.actualTextWidth = cell.spreadsheet.measureTextWidth(wrapText, textStyle)
|
||||
|
||||
// 获取文本位置并渲染文本
|
||||
const position = cell.getTextPosition()
|
||||
const { x, y } = cell.getTextAndIconPosition()?.text || cell.getTextPosition()
|
||||
// 绘制文本
|
||||
cell.textShape = renderText(cell, [cell.textShape], position.x, position.y, wrapText, textStyle, {
|
||||
cell.textShape = renderText(cell, [cell.textShape], x, y, wrapText, textStyle, {
|
||||
fontSize: extraStyleFontSize
|
||||
})
|
||||
|
||||
@@ -2312,8 +2317,6 @@ export const calculateHeaderHeight = (info, newChart, tableHeader, basicStyle, l
|
||||
ev.colLeafNodes.forEach(n => (n.height = maxHeight))
|
||||
ev.colsHierarchy.height = maxHeight
|
||||
}
|
||||
|
||||
newChart.store.set('autoCalcHeight', maxHeight)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2450,7 +2453,10 @@ export function getSummaryRow(data, axis, sumCon = []) {
|
||||
})
|
||||
// 计算方差(平方差的平均值)
|
||||
const variance = squaredDeviations.reduce((acc, val) => acc.plus(val), new Decimal(0))
|
||||
summaryObj[a] = variance.dividedBy(data.length - 1).sqrt().toNumber() // 计算总体标准差
|
||||
summaryObj[a] = variance
|
||||
.dividedBy(data.length - 1)
|
||||
.sqrt()
|
||||
.toNumber() // 计算总体标准差
|
||||
}
|
||||
break
|
||||
}
|
||||
@@ -2460,7 +2466,6 @@ export function getSummaryRow(data, axis, sumCon = []) {
|
||||
return summaryObj
|
||||
}
|
||||
|
||||
|
||||
export class SummaryCell extends CustomDataCell {
|
||||
getTextStyle() {
|
||||
const textStyle = cloneDeep(this.theme.colCell.bolderText)
|
||||
@@ -2568,7 +2573,6 @@ export function drawImage() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export function calcTreeWidth(node) {
|
||||
if (!node.children?.length) {
|
||||
return node.width
|
||||
@@ -2615,3 +2619,122 @@ export function summaryRowStyle(newChart, newData, tableCell, tableHeader, showS
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算分组表头高度
|
||||
* @param newChart
|
||||
* @param tableHeader
|
||||
* @param basicStyle
|
||||
*/
|
||||
export const calculateGroupHeaderHeight = (newChart, tableHeader, basicStyle) => {
|
||||
let maxGroupHeight = 0
|
||||
// 获取分组名字最长的列
|
||||
const maxNameMeta = newChart.dataCfg?.meta
|
||||
?.filter(item => !item.field.startsWith('f_'))
|
||||
?.reduce((max, cur) => (cur.name.length > (max?.name.length ?? 0) ? cur : max), null)
|
||||
if (maxNameMeta) {
|
||||
let colWidth = basicStyle.tableColumnWidth
|
||||
const maxNameColumn = findNodeByKey(newChart.dataCfg.fields.columns, maxNameMeta.field)
|
||||
const maxNameColumns = []
|
||||
if (maxNameColumn) {
|
||||
maxNameColumns.push(maxNameColumn)
|
||||
}
|
||||
const { resizedWidth, meta } = newChart.store.get('resizeColWidthInfo') || {
|
||||
resizedWidth: 0,
|
||||
width: 0
|
||||
}
|
||||
const leafKeys = getLeafKeys(maxNameColumns)
|
||||
if (basicStyle.tableFieldWidth.length > 0) {
|
||||
colWidth = 0
|
||||
const fieldWidth = basicStyle.tableFieldWidth
|
||||
// fieldWidth中对象的key在leafKeys时,对fieldWidth中对象的width求和
|
||||
fieldWidth.forEach(fw => {
|
||||
// 调整单元格宽度时,排除掉当前调整的列,使用调整后的宽度
|
||||
if (
|
||||
leafKeys.filter(key => meta?.key !== key).includes(fw.fieldId) &&
|
||||
isNumber(fw.width) &&
|
||||
fw.width > 0
|
||||
) {
|
||||
colWidth += fw.width
|
||||
}
|
||||
})
|
||||
}
|
||||
if (basicStyle.tableColumnMode === 'custom') {
|
||||
colWidth = basicStyle.tableColumnWidth * (leafKeys.length === 0 ? 1 : leafKeys.length) || 100
|
||||
} else {
|
||||
colWidth =
|
||||
(newChart.facet?.cfg?.width ? newChart.facet.cfg.width : newChart.options.width) *
|
||||
(colWidth / 100)
|
||||
}
|
||||
// 计算分组表头的高度
|
||||
if (colWidth > 0) {
|
||||
colWidth = colWidth + resizedWidth
|
||||
const nodeHeight = calculateGroupHeaderMaxTextHeight(
|
||||
{ info: { name: maxNameMeta.name, resizedWidth: colWidth } },
|
||||
newChart,
|
||||
tableHeader,
|
||||
basicStyle,
|
||||
null
|
||||
)
|
||||
maxGroupHeight = Math.max(maxGroupHeight, nodeHeight)
|
||||
}
|
||||
if (maxGroupHeight > 0) {
|
||||
newChart.options.style.colCfg.height = maxGroupHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 获取最里层的叶子节点
|
||||
const getLeafKeys = (columns: any[]): string[] => {
|
||||
const keys: string[] = []
|
||||
columns.forEach(col => {
|
||||
if (col && typeof col === 'object' && Array.isArray(col.children) && col.children.length > 0) {
|
||||
keys.push(...getLeafKeys(col.children))
|
||||
} else if (col && typeof col === 'object' && col.key) {
|
||||
keys.push(col.key)
|
||||
}
|
||||
})
|
||||
return keys
|
||||
}
|
||||
// 根据 key 查找节点
|
||||
const findNodeByKey = (columns: any[], key: string): any | null => {
|
||||
for (const col of columns) {
|
||||
if (col.key === key) return col
|
||||
if (col.children) {
|
||||
const found = findNodeByKey(col.children, key)
|
||||
if (found) return found
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算分组表头最大文本高度
|
||||
* @param info
|
||||
* @param newChart
|
||||
* @param tableHeader
|
||||
* @param basicStyle
|
||||
* @param _layoutResult
|
||||
*/
|
||||
const calculateGroupHeaderMaxTextHeight = (
|
||||
info,
|
||||
newChart,
|
||||
tableHeader,
|
||||
basicStyle,
|
||||
_layoutResult
|
||||
) => {
|
||||
if (tableHeader.showTableHeader === false) return
|
||||
const maxLines = basicStyle.maxLines ?? 1
|
||||
const textStyle = { ...newChart.theme.cornerCell.text, fontSize: tableHeader.tableTitleFontSize }
|
||||
const sourceText = info.info.name
|
||||
return (
|
||||
getWrapTextHeight(
|
||||
getWrapText(sourceText, textStyle, info.info.resizedWidth, newChart),
|
||||
textStyle,
|
||||
newChart,
|
||||
maxLines
|
||||
) +
|
||||
textStyle.fontSize +
|
||||
10.5
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user