123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955 |
- /*
- * <<
- * Davinci
- * ==
- * Copyright (C) 2016 - 2017 EDP
- * ==
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * >>
- */
- import React from 'react'
- import { findDOMNode } from 'react-dom'
- import classnames from 'classnames'
- import { IChartProps } from '../'
- import { IChartStyles, IPaginationParams } from '../../Widget'
- import { ITableHeaderConfig } from 'containers/Widget/components/Config/Table'
- import { ResizeCallbackData } from 'libs/react-resizable'
- import { Table as AntTable, Tooltip, Icon } from 'antd'
- import { TableProps, ColumnProps, SorterResult } from 'antd/lib/table'
- import { PaginationConfig } from 'antd/lib/pagination/Pagination'
- import PaginationWithoutTotal from 'components/PaginationWithoutTotal'
- import { ViewModelTypes } from 'containers/View/constants'
- import { TABLE_PAGE_SIZES } from 'app/globalConstants'
- import { getFieldAlias } from 'containers/Widget/components/Config/Field'
- import { decodeMetricName } from 'containers/Widget/components/util'
- import Styles from './Table.less'
- import { hasProperty } from 'utils/util'
- import {
- findChildConfig,
- traverseConfig,
- computeCellWidth,
- getDataColumnWidth,
- getTableCellValueRange,
- getCellSpanMap
- } from './util'
- import { MapAntSortOrder } from './constants'
- import { FieldSortTypes } from '../../Config/Sort'
- import { tableComponents } from './components'
- import { resizeTableColumns } from './components/HeadCell'
- interface IMapTableHeaderConfig {
- [key: string]: ITableHeaderConfig
- }
- interface ISelectItemCellProps {
- index: number
- value: string
- key: string
- }
- interface ISelectItemsCell {
- [propName: string]: ISelectItemCellProps[]
- }
- interface ISelectItems {
- group: string[]
- cell: ISelectItemsCell
- }
- interface ITableStates {
- chartStyles: IChartStyles
- data: object[]
- width: number
- pagination: IPaginationParams
- currentSorter: { column: string; direction: FieldSortTypes }
- tableColumns: Array<ColumnProps<any>>
- mapTableHeaderConfig: IMapTableHeaderConfig
- containerWidthRatio: number
- tablePagination: {
- current: number
- pageSize: number
- simple: boolean
- total: number
- }
- selectedRow: object[]
- tableBodyHeight: number
- selectItems: ISelectItems
- }
- export class Table extends React.PureComponent<IChartProps, ITableStates> {
- private static HeaderSorterWidth = 0
- public state: Readonly<ITableStates> = {
- chartStyles: null,
- data: null,
- width: 0,
- pagination: null,
- currentSorter: null,
- tableColumns: [],
- mapTableHeaderConfig: {},
- containerWidthRatio: 1,
- tablePagination: {
- current: void 0,
- pageSize: void 0,
- simple: false,
- total: void 0
- },
- tableBodyHeight: 0,
- selectedRow: [],
- selectItems: {
- group: [],
- cell: {}
- }
- }
- private table = React.createRef<AntTable<any>>()
- private handleResize = (idx: number, containerWidthRatio: number) => (
- _,
- { size }: ResizeCallbackData
- ) => {
- const nextColumns = resizeTableColumns(
- this.state.tableColumns,
- idx,
- size.width,
- containerWidthRatio
- )
- this.setState({ tableColumns: nextColumns })
- }
- private tableChange = (
- pagination: PaginationConfig,
- _,
- sorter: SorterResult<object>
- ) => {
- const nextCurrentSorter: ITableStates['currentSorter'] = sorter.field
- ? { column: sorter.field, direction: MapAntSortOrder[sorter.order] }
- : null
- this.setState({ currentSorter: nextCurrentSorter })
- const { current, pageSize } = pagination
- this.refreshTable(current, pageSize, nextCurrentSorter)
- }
- private refreshTable = (
- current: number,
- pageSize: number,
- sorter?: ITableStates['currentSorter']
- ) => {
- const { tablePagination } = this.state
- if (pageSize !== tablePagination.pageSize) {
- current = 1
- }
- const { onPaginationChange } = this.props
- onPaginationChange(current, pageSize, sorter)
- }
- private basePagination: PaginationConfig = {
- pageSizeOptions: TABLE_PAGE_SIZES.map((s) => s.toString()),
- showQuickJumper: true,
- showSizeChanger: true,
- showTotal: (total: number) => `共${total}条`
- }
- public componentDidMount() {
- const { headerFixed, withPaging } = this.props.chartStyles.table
- this.adjustTableCell(headerFixed, withPaging)
- }
- public componentDidUpdate() {
- const { headerFixed, withPaging } = this.props.chartStyles.table
- this.adjustTableCell(
- headerFixed,
- withPaging,
- this.state.tablePagination.total
- )
- }
- private adjustTableCell(
- headerFixed: boolean,
- withPaging: boolean,
- dataTotal?: number
- ) {
- const tableDom = findDOMNode(this.table.current) as Element
- const excludeElems = []
- let paginationMargin = 0
- let paginationWithoutTotalHeight = 0
- if (headerFixed) {
- excludeElems.push('.ant-table-thead')
- }
- if (withPaging) {
- excludeElems.push('.ant-pagination.ant-table-pagination')
- paginationMargin = 32
- if (dataTotal === -1) {
- paginationWithoutTotalHeight = 45
- }
- }
- const excludeElemsHeight = excludeElems.reduce((acc, exp) => {
- const elem = tableDom.querySelector(exp)
- return acc + (elem ? elem.getBoundingClientRect().height : 0)
- }, paginationMargin)
- const tableBodyHeight =
- this.props.height - excludeElemsHeight - paginationWithoutTotalHeight
- this.setState({
- tableBodyHeight
- })
- }
- public static getDerivedStateFromProps(
- nextProps: IChartProps,
- prevState: ITableStates
- ) {
- const { chartStyles, data, width } = nextProps
- if (
- chartStyles !== prevState.chartStyles ||
- data !== prevState.data ||
- width !== prevState.width
- ) {
- const {
- tableColumns,
- mapTableHeaderConfig,
- containerWidthRatio
- } = getTableColumns(nextProps)
- const tablePagination = getPaginationOptions(nextProps)
- return {
- tableColumns,
- mapTableHeaderConfig,
- containerWidthRatio,
- tablePagination,
- chartStyles,
- data,
- width
- }
- }
- return { chartStyles, data, width }
- }
- private adjustTableColumns(
- tableColumns: Array<ColumnProps<any>>,
- mapTableHeaderConfig: IMapTableHeaderConfig,
- containerWidthRatio: number
- ) {
- traverseConfig<ColumnProps<any>>(
- tableColumns,
- 'children',
- (column, idx, siblings) => {
- const canResize = siblings === tableColumns
- column.onHeaderCell = (col) => ({
- width: col.width,
- onResize: canResize && this.handleResize(idx, containerWidthRatio),
- config: mapTableHeaderConfig[column.key]
- })
- }
- )
- return tableColumns
- }
- private getRowKey = (_, idx: number) => idx.toString()
- private getTableScroll(
- columns: Array<ColumnProps<any>>,
- containerWidth: number,
- headerFixed: boolean,
- tableBodyHeght: number
- ) {
- const scroll: TableProps<any>['scroll'] = {}
- const columnsTotalWidth = columns.reduce(
- (acc, c) => acc + (c.width as number),
- 0
- )
- if (columnsTotalWidth > containerWidth) {
- scroll.x = Math.max(columnsTotalWidth, containerWidth)
- }
- if (headerFixed) {
- scroll.y = tableBodyHeght
- }
- return scroll
- }
- private isSameObj(
- prevObj: object,
- nextObj: object,
- isSourceData?: boolean
- ): boolean {
- let isb = void 0
- const clonePrevObj = { ...prevObj }
- const cloneNextObj = { ...nextObj }
- if (isSourceData === true) {
- delete clonePrevObj['key']
- delete clonePrevObj['value']
- delete cloneNextObj['key']
- delete cloneNextObj['value']
- }
- for (const attr in clonePrevObj) {
- if (
- clonePrevObj[attr] !== undefined &&
- clonePrevObj[attr] === cloneNextObj[attr]
- ) {
- isb = true
- } else {
- isb = false
- break
- }
- }
- return isb
- }
- private matchAttrInBrackets(attr: string) {
- const re = /\(\S+\)/
- const key = re.test(attr) ? attr.match(/\((\S+)\)/)[1] : attr
- return key
- }
- private rowClick = (record, row, event) => {
- const {
- getDataDrillDetail,
- onCheckTableInteract,
- onDoInteract
- } = this.props
- let selectedRow = [...this.state.selectedRow]
- let filterObj = void 0
- if (event.target && event.target.innerHTML) {
- for (const attr in record) {
- if (record[attr].toString() === event.target.innerText) {
- const key = this.matchAttrInBrackets(attr)
- filterObj = {
- key,
- value: event.target.innerText
- }
- }
- }
- }
- const recordConcatFilter = {
- ...record,
- ...filterObj
- }
- const isInteractiveChart = onCheckTableInteract && onCheckTableInteract()
- if (isInteractiveChart && onDoInteract) {
- selectedRow = [recordConcatFilter]
- } else {
- if (selectedRow.length === 0) {
- selectedRow.push(recordConcatFilter)
- } else {
- const isb = selectedRow.some((sr) =>
- this.isSameObj(sr, recordConcatFilter, true)
- )
- if (isb) {
- for (let index = 0, l = selectedRow.length; index < l; index++) {
- if (this.isSameObj(selectedRow[index], recordConcatFilter, true)) {
- selectedRow.splice(index, 1)
- break
- }
- }
- } else {
- selectedRow.push(recordConcatFilter)
- }
- }
- }
- this.setState(
- {
- selectedRow
- },
- () => {
- const sourceData = Object.values(this.state.selectedRow)
- const isInteractiveChart =
- onCheckTableInteract && onCheckTableInteract()
- if (isInteractiveChart && onDoInteract) {
- const triggerData = sourceData
- onDoInteract(triggerData)
- }
- }
- )
- }
- private asyncEmitDrillDetail() {
- const { getDataDrillDetail } = this.props
- setTimeout(() => {
- if (this.props.getDataDrillDetail) {
- const sourceData = this.combineFilter()
- const sourceGroup = this.combineGroups()
- const brushed = [{ 0: Object.values(sourceData) }]
- getDataDrillDetail(
- JSON.stringify({
- filterObj: sourceData,
- brushed,
- sourceData,
- sourceGroup
- })
- )
- }
- }, 500)
- }
- private combineGroups() {
- const { group } = this.state.selectItems
- return group
- }
- private combineFilter() {
- const { cell } = this.state.selectItems
- return Object.keys(cell).reduce((iteratee, target) => {
- iteratee = iteratee.concat(cell[target])
- return iteratee
- }, [])
- }
- private getTableStyle(headerFixed: boolean, tableBodyHeght: number) {
- const tableStyle: React.CSSProperties = {}
- if (!headerFixed) {
- tableStyle.height = tableBodyHeght
- tableStyle.overflowY = 'auto'
- }
- return tableStyle
- }
- private filterSameNeighbourSibings = (arr, targetIndex) => {
- let s = targetIndex
- let e = targetIndex
- let flag = -1
- const orgIndex = targetIndex
- do {
- const target = arr[targetIndex]
- if (flag === -1 && targetIndex > 0 && arr[targetIndex - 1] === target) {
- s = targetIndex -= 1
- } else if (flag === 1 && arr[targetIndex + 1] === target) {
- e = targetIndex += 1
- } else if (flag === -1) {
- flag = 1
- targetIndex = orgIndex
- } else {
- break
- }
- } while (targetIndex > -1 && targetIndex < arr.length)
- return { s, e }
- }
- private coustomFilter(array, column, index) {
- const nativeIndex = array.reduce(
- (a, b, c) => (b.index === index ? c : a),
- 0
- )
- const columns = array.map((a) => a[column])
- const { s: start, e: end } = this.filterSameNeighbourSibings(
- columns,
- nativeIndex
- )
- return array.filter(
- (arr) =>
- arr['index'] < array[start]['index'] || arr.index > array[end]['index']
- )
- }
- private collectCell = (target, index, dataIndex: string) => (event) => {
- const { group, cell } = this.state.selectItems
- const { data } = this.props
- const groupName = this.matchAttrInBrackets(dataIndex)
- if (this.isValueModelType(groupName)) {
- return
- }
- if (group.includes(dataIndex)) {
- group.forEach((g, i) => (g === dataIndex ? group.splice(i, 1) : void 0))
- const setKeyArray = data.map((obj: { key: number }, index) => ({
- ...obj,
- index: obj.key || index,
- key: groupName,
- value: obj[dataIndex]
- }))
- cell[dataIndex] = this.coustomFilter(setKeyArray, groupName, index)
- } else {
- const sourceCol = cell[dataIndex]
- const currentValue = {
- ...target,
- index,
- key: groupName,
- value: target[dataIndex]
- }
- if (sourceCol && sourceCol.length) {
- const isb = sourceCol.some((col) => col.index === index)
- if (isb) {
- cell[dataIndex] = this.coustomFilter(
- cell[dataIndex],
- groupName,
- index
- )
- } else {
- sourceCol.push(currentValue)
- }
- } else {
- cell[dataIndex] = [currentValue]
- }
- }
- this.setState(
- {
- selectItems: { ...this.state.selectItems }
- },
- () => {
- this.asyncEmitDrillDetail()
- }
- )
- }
- private collectGroups = (target, dataIndex) => (event) => {
- const groupName = this.matchAttrInBrackets(dataIndex)
- if (this.isValueModelType(groupName)) {
- return
- }
- const { group, cell } = this.state.selectItems
- if (group.includes(dataIndex)) {
- group.forEach((a, index) => {
- if (a === dataIndex) {
- group.splice(index, 1)
- }
- })
- } else {
- group.push(dataIndex)
- }
- delete cell[dataIndex]
- this.setState(
- {
- selectItems: { ...this.state.selectItems }
- },
- () => {
- this.asyncEmitDrillDetail()
- }
- )
- }
- private onCellClassName = (target, index, dataIndex) => {
- const { group, cell } = this.state.selectItems
- let result = ''
- Object.keys(cell).forEach((key) => {
- if (dataIndex === key) {
- cell[key].forEach((ck) => {
- if (index === ck.index) {
- result = Styles.select
- }
- })
- }
- })
- if (group && group.includes(dataIndex)) {
- result = Styles.select
- }
- return result
- }
- private isValueModelType = (modelName) => {
- const target = this.getModelTypecollectByModel()
- const result = hasProperty(target, modelName as never)
- return typeof result !== 'boolean' ? result === ViewModelTypes.Value : false
- }
- private getModelTypecollectByModel = () => {
- const { model } = this.props
- return Object.keys(model).reduce((iteratee, target) => {
- iteratee[target] = hasProperty(model[target], 'modelType')
- return iteratee
- }, {})
- }
- private onHeadCellClassName = (target, dataIndex) => {
- const { group } = this.state.selectItems
- if (group && group.includes(dataIndex)) {
- return Styles.select
- }
- return ''
- }
- private loop = (col) => {
- if (col && col.dataIndex) {
- return {
- ...col,
- onHeaderCell: (target) => {
- return {
- ...col.onHeaderCell(target),
- className: this.onHeadCellClassName(target, col.dataIndex),
- onClick: this.collectGroups(target, col.dataIndex)
- }
- },
- onCell: (target, index) => {
- // fix index in pagination
- return {
- ...col.onCell(target, index),
- className: this.onCellClassName(target, index, col.dataIndex),
- onClick: this.collectCell(target, index, col.dataIndex)
- }
- }
- }
- } else {
- return { ...col }
- }
- }
- private enhancerColumns = (column) => {
- const columns = column.map((col) => {
- if (col.children && col.children.length) {
- return {
- ...this.loop(col),
- children: this.enhancerColumns(col.children)
- }
- }
- return this.loop(col)
- })
- return columns
- }
- private getEnhancerColumn = (column) => {
- return this.enhancerColumns(column)
- }
- public render() {
- const { data, chartStyles, width } = this.props
- const { headerFixed, bordered, withPaging, size } = chartStyles.table
- const {
- tablePagination,
- tableColumns,
- tableBodyHeight,
- mapTableHeaderConfig,
- containerWidthRatio
- } = this.state
- const adjustedTableColumns = this.adjustTableColumns(
- tableColumns,
- mapTableHeaderConfig,
- containerWidthRatio
- )
- const getEnhancerColumn = this.getEnhancerColumn(adjustedTableColumns)
- const paginationConfig: PaginationConfig = {
- ...this.basePagination,
- ...tablePagination
- }
- const scroll = this.getTableScroll(
- adjustedTableColumns,
- width,
- headerFixed,
- tableBodyHeight
- )
- const style = this.getTableStyle(headerFixed, tableBodyHeight)
- const paginationWithoutTotal =
- withPaging && tablePagination.total === -1 ? (
- <PaginationWithoutTotal
- dataLength={data.length}
- size={'small' as any}
- {...paginationConfig}
- />
- ) : null
- const tableCls = classnames({
- [Styles.table]: true,
- [Styles.noBorder]: bordered !== undefined && !bordered
- })
- return (
- <>
- <AntTable
- style={style}
- className={tableCls}
- ref={this.table}
- size={size}
- dataSource={data}
- rowKey={this.getRowKey}
- components={tableComponents}
- columns={getEnhancerColumn}
- // columns={adjustedTableColumns}
- pagination={
- withPaging && tablePagination.total !== -1
- ? paginationConfig
- : false
- }
- scroll={scroll}
- bordered={bordered}
- onRowClick={this.rowClick}
- onChange={this.tableChange}
- />
- {paginationWithoutTotal}
- </>
- )
- }
- }
- export default Table
- function getTableColumns(props: IChartProps) {
- const { chartStyles, width } = props
- if (!chartStyles.table) {
- return {
- tableColumns: [],
- mapTableHeaderConfig: {}
- }
- }
- const { cols, rows, metrics, data, queryVariables } = props
- const {
- headerConfig,
- columnsConfig,
- autoMergeCell,
- leftFixedColumns,
- rightFixedColumns,
- withNoAggregators
- } = chartStyles.table
- const tableColumns: Array<ColumnProps<any>> = []
- const mapTableHeaderConfig: IMapTableHeaderConfig = {}
- const fixedColumnInfo: { [key: string]: number } = {}
- const dimensions = cols.concat(rows)
- const cellSpanMap = getCellSpanMap(data, dimensions)
- let calculatedTotalWidth = 0
- let fixedTotalWidth = 0
- dimensions.forEach((dimension) => {
- const { name, field, format } = dimension
- const headerText = getFieldAlias(field, queryVariables || {}) || name
- const column: ColumnProps<any> = {
- key: name,
- title:
- field && field.desc ? (
- <>
- {headerText}
- <Tooltip title={field.desc} placement="top">
- <Icon className={Styles.headerIcon} type="info-circle" />
- </Tooltip>
- </>
- ) : (
- headerText
- ),
- dataIndex: name
- }
- if (autoMergeCell) {
- column.render = (text, _, idx) => {
- // dimension cells needs merge
- const rowSpan = cellSpanMap[name][idx]
- return rowSpan === 1 ? text : { children: text, props: { rowSpan } }
- }
- }
- let headerConfigItem: ITableHeaderConfig = null
- findChildConfig(headerConfig, 'headerName', 'children', name, (config) => {
- headerConfigItem = config
- })
- const columnConfigItem = columnsConfig.find(
- (cfg) => cfg.columnName === name
- )
- const isFixed =
- columnConfigItem &&
- columnConfigItem.style &&
- columnConfigItem.style.inflexible
- if (isFixed) {
- column.width = fixedColumnInfo[column.key] = columnConfigItem.style.width
- fixedTotalWidth += column.width
- } else {
- column.width = getDataColumnWidth(name, columnConfigItem, format, data)
- let headerWidth = computeCellWidth(
- headerConfigItem && headerConfigItem.style,
- headerText
- )
- if (dimension.field?.desc) {
- headerWidth += 14 + 16
- }
- if (columnConfigItem?.sort) {
- headerWidth += 30
- }
- column.width = Math.max(+column.width, headerWidth)
- column.width = Math.max(+column.width, headerWidth)
- }
- calculatedTotalWidth += column.width
- if (columnConfigItem) {
- column.sorter = columnConfigItem.sort
- }
- mapTableHeaderConfig[name] = headerConfigItem
- column.onCell = (record) => ({
- config: columnConfigItem,
- format,
- cellVal: record[name],
- cellValRange: null
- })
- tableColumns.push(column)
- })
- metrics.forEach((metric) => {
- const { name, field, format, agg } = metric
- let expression = decodeMetricName(name)
- if (!withNoAggregators) {
- expression = `${agg}(${expression})`
- }
- const headerText = getFieldAlias(field, queryVariables || {}) || expression
- const column: ColumnProps<any> = {
- key: name,
- title:
- field && field.desc ? (
- <>
- {headerText}
- <Tooltip title={field.desc} placement="top">
- <Icon className={Styles.headerIcon} type="info-circle" />
- </Tooltip>
- </>
- ) : (
- headerText
- ),
- dataIndex: expression
- }
- let headerConfigItem: ITableHeaderConfig = null
- findChildConfig(headerConfig, 'headerName', 'children', name, (config) => {
- headerConfigItem = config
- })
- const columnConfigItem = columnsConfig.find(
- (cfg) => cfg.columnName === name
- )
- const isFixed =
- columnConfigItem &&
- columnConfigItem.style &&
- columnConfigItem.style.inflexible
- if (isFixed) {
- column.width = fixedColumnInfo[column.key] = columnConfigItem.style.width
- fixedTotalWidth += column.width
- } else {
- column.width = getDataColumnWidth(
- expression,
- columnConfigItem,
- format,
- data
- )
- let headerWidth = computeCellWidth(
- headerConfigItem && headerConfigItem.style,
- headerText
- )
- if (metric.field?.desc) {
- headerWidth += 14 + 16
- }
- column.width = Math.max(+column.width, headerWidth)
- }
- calculatedTotalWidth += column.width
- if (columnConfigItem) {
- column.sorter = columnConfigItem.sort
- }
- mapTableHeaderConfig[name] = headerConfigItem
- column.onCell = (record) => ({
- config: columnConfigItem,
- format,
- cellVal: record[expression],
- cellValRange: getTableCellValueRange(data, expression, columnConfigItem)
- })
- tableColumns.push(column)
- })
- // adjust column width
- const flexibleTotalWidth = calculatedTotalWidth - fixedTotalWidth
- const flexibleContainerWidth = width - fixedTotalWidth
- const containerWidthRatio =
- flexibleTotalWidth < flexibleContainerWidth
- ? flexibleContainerWidth / flexibleTotalWidth
- : 1
- tableColumns.forEach((column) => {
- if (fixedColumnInfo[column.key] === void 0) {
- // Math.floor to avoid creating float column width value and scrollbar showing
- // not use Math.ceil because it will exceed the container width in total
- column.width = Math.floor(containerWidthRatio * Number(column.width))
- }
- })
- const groupedColumns: Array<ColumnProps<any>> = []
- traverseConfig<ITableHeaderConfig>(
- headerConfig,
- 'children',
- (currentConfig) => {
- const { key, isGroup, headerName, style } = currentConfig
- if (!isGroup) {
- return
- }
- const childrenConfig = currentConfig.children.filter(
- ({ isGroup, key, headerName }) =>
- (!isGroup &&
- tableColumns.findIndex((col) => col.key === headerName) >= 0) ||
- (isGroup && groupedColumns.findIndex((col) => col.key === key) >= 0)
- )
- if (!childrenConfig.length) {
- return
- }
- const groupedColumn: ColumnProps<any> = {
- key,
- title: headerName,
- width: 0,
- children: []
- }
- mapTableHeaderConfig[key] = currentConfig
- childrenConfig.sort((cfg1, cfg2) => {
- if (cfg1.isGroup || cfg2.isGroup) {
- return 0
- }
- const cfg1Idx = tableColumns.findIndex(
- (column) => column.key === cfg1.headerName
- )
- const cfg2Idx = tableColumns.findIndex(
- (column) => column.key === cfg2.headerName
- )
- return cfg1Idx - cfg2Idx
- })
- let insertIdx = Infinity
- childrenConfig.forEach(({ isGroup, key, headerName }) => {
- const columnIdx = tableColumns.findIndex((column) =>
- column.children ? column.key === key : column.key === headerName
- )
- insertIdx = Math.min(insertIdx, columnIdx)
- groupedColumn.children.push(tableColumns[columnIdx])
- groupedColumn.width =
- +groupedColumn.width + +tableColumns[columnIdx].width
- tableColumns.splice(columnIdx, 1)
- })
- tableColumns.splice(insertIdx, 0, groupedColumn)
- groupedColumns.push(groupedColumn)
- }
- )
- tableColumns.forEach((column) => {
- const name = (column.children && column.children.length
- ? column.title
- : column.dataIndex) as string
- if (leftFixedColumns.includes(name)) {
- column.fixed = 'left'
- }
- if (rightFixedColumns.includes(name)) {
- column.fixed = 'right'
- }
- })
- return { tableColumns, mapTableHeaderConfig, containerWidthRatio }
- }
- function getPaginationOptions(props: IChartProps) {
- const { chartStyles, width, pagination } = props
- // fixme
- let pageNo = void 0
- let pageSize = void 0
- let totalCount = void 0
- if (pagination) {
- pageNo = pagination.pageNo
- pageSize = pagination.pageSize
- totalCount = pagination.totalCount
- }
- // const { pageNo, pageSize, totalCount } = pagination
- const { pageSize: initialPageSize } = chartStyles.table
- const paginationOptions: ITableStates['tablePagination'] = {
- current: pageNo,
- pageSize: pageSize || +initialPageSize,
- total: totalCount,
- simple: width <= 768
- }
- return paginationOptions
- }
|