mirror of
https://github.com/dataease/dataease.git
synced 2026-06-16 11:21:44 +08:00
feat(图表): 汇总表支持表头分组
This commit is contained in:
@@ -60,6 +60,13 @@ const onCancelConfig = () => {
|
||||
emits('onCancelConfig')
|
||||
}
|
||||
|
||||
const allAxis = computed(() => {
|
||||
const axis = [...props.chart.xAxis]
|
||||
if (props.chart.type === 'table-normal') {
|
||||
axis.push(...props.chart.yAxis)
|
||||
}
|
||||
return axis
|
||||
})
|
||||
const onConfigChange = () => {
|
||||
const { fields } = s2.dataCfg
|
||||
emits('onConfigChange', { columns: fields.columns, meta: [] })
|
||||
@@ -67,10 +74,9 @@ const onConfigChange = () => {
|
||||
|
||||
const init = () => {
|
||||
const chart = cloneDeep(props.chart)
|
||||
const xAxis = chart.xAxis
|
||||
const { headerGroupConfig } = chart.customAttr.tableHeader
|
||||
const showColumns = []
|
||||
xAxis?.forEach(axis => {
|
||||
allAxis.value?.forEach(axis => {
|
||||
axis.hide !== true &&
|
||||
showColumns.push({ field: axis.dataeaseName, title: axis.chartShowName ?? axis.name })
|
||||
})
|
||||
@@ -93,11 +99,11 @@ const init = () => {
|
||||
}
|
||||
setupColumnTitle(headerGroupConfig.columns, nameFieldMap)
|
||||
}
|
||||
const allAxis = showColumns.map(item => item.field)
|
||||
const allKeys = showColumns.map(item => item.field)
|
||||
const leafNodes = getLeafNodes(headerGroupConfig.columns)
|
||||
const leafKeys = leafNodes.map(item => item.field)
|
||||
const { columns } = headerGroupConfig
|
||||
if (!isEqual(allAxis, leafKeys)) {
|
||||
if (!isEqual(allKeys, leafKeys)) {
|
||||
columns.splice(0, columns.length, ...showColumns)
|
||||
} else {
|
||||
const nameMap = showColumns.reduce((pre, cur) => {
|
||||
|
||||
@@ -96,18 +96,21 @@ const groupConfigValid = computed(() => {
|
||||
if (noGroup) {
|
||||
return false
|
||||
}
|
||||
const xAxis = props.chart.xAxis
|
||||
const allAxis = [...props.chart?.xAxis]
|
||||
if (props.chart.type === 'table-normal') {
|
||||
allAxis.push(...props.chart?.yAxis)
|
||||
}
|
||||
const showColumns = []
|
||||
xAxis?.forEach(axis => {
|
||||
axis.hide !== true && showColumns.push({ key: axis.dataeaseName })
|
||||
allAxis?.forEach(axis => {
|
||||
axis.hide !== true && showColumns.push({ field: axis.dataeaseName })
|
||||
})
|
||||
if (!showColumns.length) {
|
||||
return false
|
||||
}
|
||||
const allAxis = showColumns.map(item => item.key)
|
||||
const allKeys = showColumns.map(item => item.field)
|
||||
const leafNodes = getLeafNodes(columns as Array<ColumnNode>)
|
||||
const leafKeys = leafNodes.map(item => item.key)
|
||||
return isEqual(allAxis, leafKeys)
|
||||
const leafKeys = leafNodes.map(item => item.field)
|
||||
return isEqual(allKeys, leafKeys)
|
||||
})
|
||||
const init = () => {
|
||||
const tableHeader = props.chart?.customAttr?.tableHeader
|
||||
|
||||
@@ -28,7 +28,9 @@ import {
|
||||
getSummaryRow,
|
||||
SummaryCell,
|
||||
mapKeyToField,
|
||||
setupColumnTitle
|
||||
setupColumnTitle,
|
||||
calcTreeWidth,
|
||||
getStartPosition
|
||||
} from '@/views/chart/components/js/panel/common/common_table'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -153,15 +155,21 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
||||
})
|
||||
}
|
||||
setupColumnTitle(headerGroupConfig.columns as unknown as ColumnNode[], nameMap)
|
||||
const allKeys = columns.map(c => drillFieldMap[c] || c.field)
|
||||
const allKeys = columns.map(c => drillFieldMap[c.field] || c.field)
|
||||
const leafNodes = getLeafNodes(headerGroupConfig.columns as ColumnNode[])
|
||||
const leafKeys = leafNodes.map(c => c.field)
|
||||
if (isEqual(leafKeys, allKeys)) {
|
||||
if (Object.keys(drillFieldMap).length) {
|
||||
const drillNameMap =
|
||||
chart.drillFields?.reduce((pre, cur) => {
|
||||
pre[cur.dataeaseName] = cur.chartShowName || cur.name
|
||||
return pre
|
||||
}, {}) || {}
|
||||
const originField = Object.values(drillFieldMap)[0]
|
||||
const drillField = Object.keys(drillFieldMap)[0]
|
||||
const [drillCol] = getColumns([originField], headerGroupConfig.columns as ColumnNode[])
|
||||
drillCol.field = drillField
|
||||
drillCol.title = drillNameMap[drillField] ?? drillCol.title
|
||||
}
|
||||
columns.splice(0, columns.length, ...headerGroupConfig.columns)
|
||||
}
|
||||
@@ -516,19 +524,3 @@ export class TableInfo extends S2ChartView<TableSheet> {
|
||||
super('table-info', [])
|
||||
}
|
||||
}
|
||||
|
||||
function calcTreeWidth(node) {
|
||||
if (!node.children?.length) {
|
||||
return node.width
|
||||
}
|
||||
return node.children.reduce((pre, cur) => {
|
||||
return pre + calcTreeWidth(cur)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
function getStartPosition(node) {
|
||||
if (!node.children?.length) {
|
||||
return node.x
|
||||
}
|
||||
return getStartPosition(node.children[0])
|
||||
}
|
||||
|
||||
@@ -6,7 +6,13 @@ import {
|
||||
getSummaryRow,
|
||||
SortTooltip,
|
||||
SummaryCell,
|
||||
summaryRowStyle
|
||||
summaryRowStyle,
|
||||
getLeafNodes,
|
||||
getColumns,
|
||||
calcTreeWidth,
|
||||
getStartPosition,
|
||||
mapKeyToField,
|
||||
setupColumnTitle
|
||||
} 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'
|
||||
@@ -20,7 +26,7 @@ import {
|
||||
TableSheet,
|
||||
ViewMeta
|
||||
} from '@antv/s2'
|
||||
import { isNumber } from 'lodash-es'
|
||||
import { isEqual, isNumber } from 'lodash-es'
|
||||
import { TABLE_EDITOR_PROPERTY, TABLE_EDITOR_PROPERTY_INNER } from './common'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -34,7 +40,8 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
'table-header-selector': [
|
||||
...TABLE_EDITOR_PROPERTY_INNER['table-header-selector'],
|
||||
'tableHeaderSort',
|
||||
'showTableHeader'
|
||||
'showTableHeader',
|
||||
'headerGroup'
|
||||
],
|
||||
'basic-style-selector': [
|
||||
...TABLE_EDITOR_PROPERTY_INNER['basic-style-selector'],
|
||||
@@ -76,6 +83,7 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
|
||||
const columns = []
|
||||
const meta = []
|
||||
const drillFieldMap = {}
|
||||
if (chart.drill) {
|
||||
// 下钻过滤字段
|
||||
const filterFields = chart.drillFilters.map(i => i.fieldId)
|
||||
@@ -84,13 +92,14 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
const drillFieldIndex = chart.xAxis.findIndex(ele => ele.id === drillFieldId)
|
||||
// 当前下钻字段
|
||||
const curDrillFieldId = chart.drillFields[filterFields.length].id
|
||||
const curDrillField = fields.filter(ele => ele.id === curDrillFieldId)
|
||||
const curDrillField = fields.find(ele => ele.id === curDrillFieldId)
|
||||
filterFields.push(curDrillFieldId)
|
||||
// 移除下钻字段,把当前下钻字段插入到下钻入口位置
|
||||
fields = fields.filter(ele => {
|
||||
return !filterFields.includes(ele.id)
|
||||
})
|
||||
fields.splice(drillFieldIndex, 0, ...curDrillField)
|
||||
drillFieldMap[curDrillField.dataeaseName] = chart.drillFields[0].dataeaseName
|
||||
fields.splice(drillFieldIndex, 0, curDrillField)
|
||||
}
|
||||
const axisMap = [...chart.xAxis, ...chart.yAxis].reduce((pre, cur) => {
|
||||
pre[cur.dataeaseName] = cur
|
||||
@@ -102,10 +111,9 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
if (f?.hide === true) {
|
||||
return
|
||||
}
|
||||
columns.push(ele.dataeaseName)
|
||||
columns.push({ field: ele.dataeaseName, title: ele.chartShowName ?? ele.name })
|
||||
meta.push({
|
||||
field: ele.dataeaseName,
|
||||
name: ele.chartShowName ?? ele.name,
|
||||
formatter: function (value) {
|
||||
if (!f) {
|
||||
return value
|
||||
@@ -124,7 +132,47 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
const { basicStyle, tableCell, tableHeader, tooltip } = parseJson(chart.customAttr)
|
||||
// 表头分组
|
||||
const { headerGroup, showTableHeader } = tableHeader
|
||||
if (headerGroup && showTableHeader !== false) {
|
||||
const { headerGroupConfig } = tableHeader
|
||||
if (headerGroupConfig?.columns?.length) {
|
||||
// 存量配置转换
|
||||
if (headerGroupConfig.columns[0].key) {
|
||||
mapKeyToField(headerGroupConfig.columns as unknown as ColumnNode[])
|
||||
}
|
||||
const nameMap =
|
||||
[...chart.xAxis, ...chart.yAxis].reduce((pre, cur) => {
|
||||
pre[cur.dataeaseName] = cur.name
|
||||
return pre
|
||||
}, {}) || {}
|
||||
if (headerGroupConfig.meta?.length) {
|
||||
headerGroupConfig.meta.forEach(m => {
|
||||
nameMap[m.field] = m.name
|
||||
})
|
||||
}
|
||||
setupColumnTitle(headerGroupConfig.columns as unknown as ColumnNode[], nameMap)
|
||||
const allKeys = columns.map(c => drillFieldMap[c.field] || c.field)
|
||||
const leafNodes = getLeafNodes(headerGroupConfig.columns as ColumnNode[])
|
||||
const leafKeys = leafNodes.map(c => c.field)
|
||||
if (isEqual(leafKeys, allKeys)) {
|
||||
if (Object.keys(drillFieldMap).length) {
|
||||
const drillNameMap =
|
||||
chart.drillFields?.reduce((pre, cur) => {
|
||||
pre[cur.dataeaseName] = cur.chartShowName || cur.name
|
||||
return pre
|
||||
}, {}) || {}
|
||||
const originField = Object.values(drillFieldMap)[0]
|
||||
const drillField = Object.keys(drillFieldMap)[0]
|
||||
const [drillCol] = getColumns([originField], headerGroupConfig.columns as ColumnNode[])
|
||||
drillCol.field = drillField
|
||||
drillCol.title = drillNameMap[drillField] ?? drillCol.title
|
||||
}
|
||||
columns.splice(0, columns.length, ...headerGroupConfig.columns)
|
||||
}
|
||||
}
|
||||
}
|
||||
// 空值处理
|
||||
const newData = this.configEmptyDataStrategy(chart)
|
||||
// data config
|
||||
@@ -136,7 +184,6 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
data: newData
|
||||
}
|
||||
|
||||
const { basicStyle, tableCell, tableHeader, tooltip } = parseJson(chart.customAttr)
|
||||
// options
|
||||
const s2Options: S2Options = {
|
||||
width: containerDom.offsetWidth,
|
||||
@@ -221,6 +268,13 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
n.x = p
|
||||
return p + n.width
|
||||
}, 0)
|
||||
// 处理分组的单元格,宽度为所有叶子节点之和
|
||||
ev.colNodes.forEach(n => {
|
||||
if (n.colIndex === -1) {
|
||||
n.width = calcTreeWidth(n)
|
||||
n.x = getStartPosition(n)
|
||||
}
|
||||
})
|
||||
ev.colsHierarchy.width = totalWidth
|
||||
newChart.store.set('lastLayoutResult', undefined)
|
||||
return
|
||||
@@ -241,6 +295,13 @@ export class TableNormal extends S2ChartView<TableSheet> {
|
||||
n.x = p
|
||||
return p + n.width
|
||||
}, 0)
|
||||
// 处理分组的单元格,宽度为所有叶子节点之和
|
||||
ev.colNodes.forEach(n => {
|
||||
if (n.colIndex === -1) {
|
||||
n.width = calcTreeWidth(n)
|
||||
n.x = getStartPosition(n)
|
||||
}
|
||||
})
|
||||
// 从最后一列减掉
|
||||
const lastNode = ev.colLeafNodes[ev.colLeafNodes.length - 1]
|
||||
if (totalWidth > containerWidth) {
|
||||
|
||||
@@ -2066,6 +2066,23 @@ export const summaryRowStyle = (newChart, newData, tableCell, tableHeader, showS
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
export function calcTreeWidth(node) {
|
||||
if (!node.children?.length) {
|
||||
return node.width
|
||||
}
|
||||
return node.children.reduce((pre, cur) => {
|
||||
return pre + calcTreeWidth(cur)
|
||||
}, 0)
|
||||
}
|
||||
|
||||
export function getStartPosition(node) {
|
||||
if (!node.children?.length) {
|
||||
return node.x
|
||||
}
|
||||
return getStartPosition(node.children[0])
|
||||
}
|
||||
|
||||
export class SummaryCell extends CustomDataCell {
|
||||
getTextStyle() {
|
||||
const textStyle = cloneDeep(this.theme.colCell.bolderText)
|
||||
|
||||
Reference in New Issue
Block a user