Ant-design: No hay forma de mostrar datos de estadísticas de agregación en la tabla

Creado en 11 abr. 2017  ·  78Comentarios  ·  Fuente: ant-design/ant-design

Versión

2.9.1

Medio ambiente

navegador

Enlace de reproducción

http: // ninguno

pasos para reproducir

Quiero mostrar estadísticas de agregación en el pie de la tabla, lo intento de las siguientes maneras:

  1. usando footer prop, agregue tr y td
      <Table
        dataSource={dataSource}
        footer={() => {
          return (
            <tr className='ant-table-row  ant-table-row-level-0'>
              <td>总计</td>
              <td>总计</td>
            <td>总计</td>
            </tr>
          )
        }}
      />
  1. agregar datos adicionales en dataSource prop
dataSource.push({id: '总计', price: '3000'})

¿Lo que es esperado?

Una imagen vale mas que mil palabras:

¿Qué está pasando realmente?

  1. usando footer prop, pero el footer prop no se ajusta al cuerpo de la mesa.

  2. agregue datos adicionales en dataSource prop, pero si la longitud de la fuente de datos es superior a pageSize , los datos adicionales se ignorarán.

Inactive IssueHuntFest ❓FAQ 💡 Feature Request

Comentario más útil

¿Quizás podamos hacer algo para que footer ajuste a la mesa tbody?

Todos 78 comentarios

Hola @TangMonk , parece que está solicitando una función que no sea informar un error, me temo que no tenemos un plan para implementar esta función. Puede deshabilitar la paginación predeterminada de la tabla e implementar la paginación usted mismo.

¿Quizás podamos hacer algo para que footer ajuste a la mesa tbody?

@yesmeck , gracias por tu respuesta, pero hay demasiados problemas al respecto, creo que esta función es realmente útil y necesaria.

problemas relacionados: # 3591, # 1483, # 4581

@ afc163 , ¡gracias!

¿Cuál es tu sugerencia o solución?

No estoy seguro, creo que no puede limitar estrictamente el tamaño de los datos de la tabla usando pageSize , los datos deben procesarse por el lado del servidor en lugar del lado del cliente, por lo que podemos agregar cualquier dato adicional a la tabla

Hola,
¿Hay alguna actualización sobre estas características? ¿O otra forma de hacerlo?

@yesmeck La solución más simple es hacer que el pie de página represente un <tfoot> real dentro de la tabla, en lugar de agregar un <div> adicional fuera de la tabla.

La gente está tratando de incluir una fila adicional en dataSource simplemente porque quieren que el diseño de la tabla alinee las columnas para ellos.

Sí, ya tenemos un footer prop, no podemos encontrar un nombre apropiado para <tfoot/> .

Estoy sugiriendo reimplementar el footer prop actual para que renderice una tabla interior <tfoot /> , no agregando un nuevo tfoot prop. No creas que romperá nada.

@yesmeck Parece que esta función se solicita con frecuencia. También estoy luchando por agregar una fila de resumen. Conseguí una solución, pero implica manipulación de hacky dom, feliz de ver una solución más bonita.

¿Alguien del equipo ya se está ocupando de eso? Si no, tal vez podría investigarlo.

Puedes probar PR.

@yesmeck Aquí tienes: https://github.com/react-component/table/pull/191
Consulte el ejemplo / renderFooterInTable para ver el efecto.

Después de pensar un rato en la API tfoot , me gustaría agregarla a la propiedad column :

const columns = [{
  title: 'Age',
  dataIndex: 'age',
  key: 'age',
  footer: (data) => {
    return <div>Summary: {data.reduce((sum, record) => sum + record.age, 0)}</div>
  },
}, {
  title: 'Name',
  dataIndex: 'name',
  key: 'name',
}, {
  title: 'Address',
  dataIndex: 'address',
  key: 'address',
}];

renders

screen shot 2018-02-27 at 15 03 33

Es más claro hacer una diferencia entre los Table[footer] actuales.

Buena idea. Estoy de acuerdo en que este sería un mejor lugar para introducir una nueva API.

@hackape ¿Podrías proponer un nuevo RP?

cosa segura

https://codesandbox.io/s/m45r6o4nj8
Realizado, pero hay un problema con el enlace de la barra de desplazamiento, es más conveniente ver

@yesmeck ¿cuál es el estado de react-component / table # 195 ahora, algún comentario?

Lo vi fusionado 👍 @yesmeck

Sin embargo, recibí una solicitud de función adicional. Me gustaría proponer permitir que el llamado "pie de página" aparezca en la parte superior de la tabla, justo debajo del encabezado de la tabla.

Ejemplo:
image

La función solicitada real que se está discutiendo todo el tiempo es un medio para incluir una fila adicional para mostrar información estadística; en otras palabras, una "fila de resumen", sin alterar el contenido de dataSource , no un "pie de página" en el sentido posicional.

@hackape Puede utilizar la agrupación de columnas, consulte https://codesandbox.io/s/pmorq2x2lq

Sí, si fuera únicamente con fines de posicionamiento, este sería un medio viable. Pero en el sentido de la lógica empresarial, es mucho mejor dejar que el usuario lo haga a través de mi API propuesta.

Creo que podemos cambiar el nombre de la API column.footer a column.summary .

const columns = [{
  title: 'Age',
  dataIndex: 'age',
  key: 'age',
  summary: {
    render: (data) => {
      return <div>Summary: {data.reduce((sum, record) => sum + record.age, 0)}</div>
    },
    position: 'bottom',  // default to 'bottom', could be 'top'
  }
}]

Propondría presentar dos nuevos profesionales llamados pinnedTopData y pinnedBottomData .

const columns = [
  { title: 'Price', dataIndex: 'price' },
  { name: 'Name', dataIndex: 'name' },
];

const data = [
  { price: 3, Name: 'Foo' },
  { price: 5, Name: 'Bar' },
];

const pinnedData = [
  { price: <span style={{ fontWeight: 'bold' }}>Total: 8</span> }
];

<Table
  columns={columns}
  dataSource={data}
  pinnedTopData={pinnedData}
  pinnedBottomData={pinnedData}
/>

Renders:

| Precio | Nombre |
| ---------- | ------ |
| Total: 8 | |
| 3 | Foo |
| 5 | Bar |
| Total: 8 | |

Es mejor resolver # 6896 y este problema con la misma API.

¿Hay nuevos avances?

@Nokecy ve su solución de dos maneras. No lo ha agregado al atributo temporalmente. Creo que su re-tabla tiene este atributo. La premisa es que el número de versión se actualiza a la última, pero se debe modificar antd package.json. También Dos métodos,
1. Si no hay muchas columnas y no aparece ninguna barra de desplazamiento, es fácil de resolver, tengo un ejemplo arriba.
2. Puede usar múltiples barras de título para mostrar, no se siente tan hermoso.

Espero que mejoren esta función y sigan prestando atención, pero nuestro antd es 2. Incluso si está actualizado, no sé si la versión

¿Alguna actualización para este problema?

antes de que puedan enviar una API oficial, por ahora sugiero proporcionar un componente personalizado table.props.components.body.wrapper y manipular el props.children que recibió.

https://codesandbox.io/s/xpvwpx0npw
Manipulé directamente el elemento dom y encapsulé un total del total. Puede agregar muchos pies de página de acuerdo con este método, pero el funcionario no recomienda operar directamente el elemento dom. Si lo necesita con urgencia, puede consultar este

@ LDD123 el desplazamiento x está solo en el pie de página en su ejemplo. el cuerpo también debe desplazarse con pie de página

image

@jagratiTomar el cuerpo se desplazará cuando el pie de página se esté desplazando,

@ LDD123 puede compartir un ejemplo donde hay un scroll-y también en el cuerpo, porque en ese caso solo el cuerpo debe desplazarse y no el pie de página

@jagratiTomar ahora, oculto scroll-x no scroll, estará bien

@ LDD123, ¿estás diciendo que cuando haya scroll-y este ejemplo funcionaría bien?

yeap

Hola @yesmeck @ afc163 ,

Nuestros diseñadores ponen el pie de página (tiene los valores agregados) en la parte superior del cuerpo y justo debajo del encabezado para fines de UX. Las flechas para ordenar el encabezado y el pie de página solo tienen valores agregados. Con ColumnGroup, las flechas para ordenar se añaden al final. Desde la perspectiva del estilo, es mucho más fácil diseñar el pie de página y colocarlo en la parte superior, ya que el contenedor de pie de página tiene un color diferente y solo algunas celdas tienen separador.

Yo solo haría:

.my-table tfoot > tr {
 background-color: gray;
}

El componente de tabla podría tener algo como esto:

<Table appendColumnFooterTop={true}>
   <Column
      footer={(data) => <div>Summary: {data.reduce((sum, record) => sum + record.age, 0)}</div>}
   />
</Table>

Diseño:
screen shot 2018-05-30 at 17 07 38

No importa el texto no alineado en las celdas, es de una página hecha previamente que tienen que alinear con la nueva que estamos codificando.

Podría ofrecer mi ayuda si supiera que podría publicarse en 2 o 3 semanas (pie de página de la columna y su alineación). De lo contrario, me veré obligado a encontrar otras soluciones.

Ah, y no pude entender si el número 6896 trata sobre el pie de la columna, así que escribí aquí.

Gracias.

@kaanozcan Envié un PR implementando la misma idea (ver aquí ) en marzo, el equipo central lo fusionó y luego se revirtió. Parece que tienen otra idea sobre cómo abordar el problema. Dada la situación, le sugiero que tome el camino de "encontrar otras soluciones".

@kaanozcan Aquí hay un ejemplo de https://codesandbox.io/s/xjpkx9rzzw

@yesmeck Eso funciona perfectamente. Gracias.

El cierre debido a la solicitud original se puede lograr mediante componentes personalizados.

@yesmeck ¿Podríamos proporcionar alguna demostración sobre este caso de uso?

https://codesandbox.io/s/xjpkx9rzzw
Este ejemplo no tiene ningún significado práctico. Porque si los datos cambian .. La última suma no usa los últimos datos. Es el resultado de la última actualización. Debería estar donde hay datos sucios.

@yesmeck El ejemplo que dio no se puede usar ... porque los datos no se pueden cambiar.
const data = [ { key: "1", name: "John Brown", age: 30, address: "New York No. 1 Lake Park", }, { key: "2", name: "Jim Green", age: 20, address: "London No. 1 Lake Park", }, { key: "3", name: "Joe Black", age: Math.random() * 20, address: "Sidney No. 1 Lake Park", }, ]; como esta modificación ... en realidad, la suma final no es correcta.

@yesmeck https://codesandbox.io/s/xjpkx9rzzw Esta demostración tiene un problema, cuando configuras a la izquierda de fijo, puedes ver que el estilo es un desastre。

Me las arreglé para hacerlo usando el contenedor de componentes, pero es algo incómodo. El código se ve así

export default class extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      localData: props.data,
    };

    this.tableRef = React.createRef();
  }

  handleTableUpdate = () => {
    this.setState({ localData: this.tableRef.current.getLocalData() });
  }

  render() {
    return (
      <Table
        ref={this.tableRef}
        columns={this.props.columns}
        dataSource={this.props.data}
        onChange={this.handleTableUpdate}
        components={{
          body: {
            wrapper: (props) => (
              <BodyWithSummary
                columns={this.props.columns}
                data={this.state.localData}
                {...props}
              />
            ),
          },
        }}
      />
    );
  }
}

function BodyWithSummary(props) {
  const { data, columns, ...otherProps } = props;
  return (
    <tbody {...otherProps}>
      <React.Fragment>
        {data && data.length > 0 && (
          <tr>
            {props.columns.map((col) => renderColumn(col, data))}
          </tr>
        )}
        {props.children}
      </React.Fragment>
    </tbody>
  );
}

Lo molesto es que necesito llamar a getLocalData si quiero que los datos agregados se calculen en las filas filtradas.
Sería mucho mejor si el envoltorio del cuerpo recibiera la referencia de la tabla como un accesorio o tuviera una forma más fácil de acceder a los datos que se mostrarán (props.children es una lista de nodos de reacción, no muy útil para calcular los agregados)

¿Podríamos usar footer prop pero renderizar en la tabla en lugar de div adicional?

Manejado temporalmente así:

20180927 0905

      .ant-table-footer {
        padding: 0;
      }
                                    footer={(currentPageData)=>{
                                        return (
                                            <Row style={{marginRight:17}}>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>合计</Card>
                                                </Col>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                                <Col span={4} className="brd">
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                                <Col span={4}>
                                                    <Card bordered={false} className="bgfb" bodyStyle={{padding:'10px 15px'}}>123456789</Card>
                                                </Col>
                                            </Row>
                                        );
                                    }}

No es perfecto

Espero que el pie de las columnas salga pronto O (∩_∩) O

@ybning ¿Tiene problemas con las columnas fijas? Muchas de estas columnas fijas tendrán problemas. .

@yesmeck Su ejemplo rompe el conteo interno de la tabla: https://codesandbox.io/s/rrpo02qwkq
Navegue a la página 2 y luego regrese a la página 1, duplica los datos en cada navegación.

¿Alguna actualización para este problema?

@linrf no, espero que alguien pueda resolver este problema

¿Podríamos agregar un total prop para las estadísticas de agregación de transacciones?
total es diferente con footer ,
solo acepta una función para tratar los datos de la columna, el valor predeterminado es reduce

v7a kvx 5cig rjeo 696g
Finalmente puse el total en la columna

La representación del contenido del pie de página de la tabla de antd no es realmente fácil de usar, especialmente cuando la tabla en sí tiene columnas fijas.

Puede cambiar la forma de implementarlo con dos tablas, una para representar la tabla original y la otra para representar el elemento de pie de página inferior. Con cobertura de estilo, oculte el encabezado del pie de la tabla y la barra de desplazamiento del área de desplazamiento de la tabla original. Finalmente, agregue el código JS para alinear las posiciones de desplazamiento horizontal de las dos tablas, es casi lo mismo.

Componentes:

import React, { PureComponent } from 'react';
import { Table } from 'antd';
import styles from './index.less';

export default class ChartTable extends PureComponent {
  constructor(props) {
    super(props);

    this.refBox = React.createRef();
  }
  componentDidMount() {
    const tableList = Array.from(this.refBox.current.querySelectorAll('.ant-table-body'));
    this.tableList = tableList;
    tableList.forEach((table) => {
      table.addEventListener('scroll', this.handleTableScroll);
    });
  }
  componentWillUnmount() {
    this.tableList.forEach((table) => {
      table.removeEventListener('scroll', this.handleTableScroll);
    });
  }
  handleTableScroll = (e) => {
    const current = e.currentTarget;
    this.tableList.forEach((table) => {
      if (table !== current && table.scrollLeft !== current.scrollLeft) {
        table.scrollLeft = current.scrollLeft;
      }
    });
  }
  renderFooterTable = () => {
    const { columns, dataSource } = this.props;
    const dataList = [{
      department: '合计',
    }];
    return (
      <Table
        className={styles.footerTable}
        pagination={false}
        scroll={{ x: 'max-content' }}
        size="small"
        columns={columns}
        dataSource={dataList}
      />
    );
  }
  render() {
    return (
      <div ref={this.refBox}>
        <Table
          className={styles.mainTable}
          pagination={false}
          scroll={{ x: 'max-content', y: 350 }}
          size="small"
          columns={this.props.columns}
          dataSource={this.props.dataSource}
        />
        {this.renderFooterTable()}
      </div>
    );
  }
}

Archivo de cobertura de estilo:

mainTable {
  :global {
    .ant-table-body::-webkit-scrollbar {
      display: none;
    }
  }  
}
.footerTable {
  border-top: 1px solid #e8e8e8;

  :global {
    thead {
      display: none;
    }
  }
}

+1 Me encantaría tener una forma de mostrar agregaciones de columnas en el pie de página.

Esto se puede implementar usando componentes prop.

const __Table = (totalsRow = initTotals(), key='tableKey') => ({
    className,
    style,
    children
}) => (
    <table className={className} style={style} key={key}>
        {children}
        <tfoot>
            <tr>
                // add tfoot td here
            </tr>
        </tfoot>
    </table>
);

const TableWithTFoot = ({allData, columns}) =>
    <Table
        dataSource={allData.data}
        columns={columns}
        pagination={false}
        components={{ table: __Table(allData.totals) }}
    />

@rororofff ha financiado $ 5.00 para este número.


@piuccio Según tu pensamiento, lo escribo a máquina.

https://github.com/Arweil/antd-ext/blob/master/src/TableExt/TableExt.tsx

https://github.com/ant-design/ant-design/issues/5710#issuecomment -450855438

this.refBox = React.createRef();

Utilizo este paquete de versión, no se pudo ejecutar este código.
"antd": "2.13.14", "react": "15.4.0", "react-dom": "15.4.0"

mensaje de error
Uncaught TypeError: _react2.default.createRef is not a function at new EstimationReport (psReport.js?18c1:47) at eval (ReactCompositeComponent.js?063f:295) at measureLifeCyclePerf (ReactCompositeComponent.js?063f:75) at

@carvendy Probablemente sea su configuración de resolución de módulo al importar react . Intenta cambiar

import from 'react';

dentro de esto:

import * as react from 'react'

Hice un componente,
Usa el modelo de columnas para renderizar el pie de página
Sin embargo, las barras de desplazamiento no son compatibles actualmente.

import React from 'react';

class TableFooter extends React.Component {
  render() {
    const { dataSource, columns } = this.props;
    return (
      <table className="ant-table">
        <colgroup>
          {columns.map((colModel, index) => {
            return <col style={{
              width: colModel.width,
              minWidth: colModel.width
            }} key={index} />
          })}
        </colgroup>
        <tfoot >
          <tr >
            {columns.map((colum, idxCol) => {
              return <td style={{ padding: "0px 8px" }} className={colum.className} key={idxCol}>
                <strong>
                  {colum.footerContent ? colum.footerContent : (colum.footerSum ? dataSource.reduce((sum, record) => sum + parseFloat(record[colum.key]), 0) : "")}
                </strong>
              </td>
            })}
          </tr>
        </tfoot>
      </table>
    )
  }
}
export default TableFooter;

Llamada de página

...
render() {
  const columns = [
      {
        key: 'productName'
        footerContent: 'SUM:',
      },
      {
        key: 'quantity',
        footerSum: true,
      }
    }
];
return (
  <Table
    columns={columns}
    dataSource={dataSource}
    footer={()=> {
        return (
           <TableFooter dataSource={dataSource} columns={columns} />
        )
       }
    }
  />
)
....

var data = this.getLocalData ();
var corriente;
var pageSize;
var state = this.state; // Si no hay paginación, todos se muestran por defecto

  if (!this.hasPagination()) {
    pageSize = Number.MAX_VALUE;
    current = 1;
  } else {
    pageSize = state.pagination.pageSize;
    current = this.getMaxCurrent(state.pagination.total || data.length);
  } // 分页
  // ---
  // 当数据量少于等于每页数量时,直接设置数据
  // 否则进行读取分页数据


  if (data.length > pageSize || pageSize === Number.MAX_VALUE) {
    data = data.filter(function (_, i) {
      return i >= (current - 1) * pageSize && i < current * pageSize;
    });
  }

  return data;
}

Esto es si el código fuente de los datos de procesamiento de la tabla puede agregar una función aquí para calcular la suma de los valores de la lista, sumar el número total de datos al generar y restar los datos recién agregados de la página y el tamaño de la página @sorrycc

después de 2 años, este problema todavía existe.

después de 2 años, este problema aún existe.

Originalmente usé el método de modificar el render de reescribir col y agregar datos en la tabla no paginada:

image

Pero en el caso de la paginación, si se cargan varios datos, se eliminarán. Https://github.com/ant-design/ant-design/blob/fee5e291632cce131611dd1a9e2ab89e02ee43a3/components/table/Table.tsx#L407

Quiero PR, pero me temo que el diseño de mi API no cumple con los requisitos de mi jefe @ afc163 ...

después de 2 años, este problema aún existe.

la nueva mesa en camino. Esperando la nueva mesa

https://github.com/ant-design/ant-design/issues/16911#issuecomment -523423460

@ alexchen1875 Eso no mencionó nada relacionado con esto.

@ alexchen1875 Eso no mencionó nada relacionado con esto.

Lea atentamente las instrucciones de la sección de la tabla.

@ alexchen1875 ¡increíble!

Quiero enviar un PR y agregar temporalmente un accesorio de "Permitir que los datos no recorten datos" para admitir omitir https://github.com/ant-design/ant-design/blob/61e319b66826530a1882c20a41862a15d57b120a/components/table/Table.tsx La lógica de filtro de https://github.com/ant-design/ant-design/issues/5710#issuecomment -524164125 también esté disponible en el caso de la paginación, no sé si el equipo aceptará ...

Modifiqué esta demostración ,
soporte agregado para columnas fijas , agrupación de encabezados , combinación de celdas y desplazamiento ,
Yo usé \

y la paginación no se verá afectada.Utilizado temporalmente en mi proyecto

👉 nueva dirección de demostración

uso:

const calcRow = [
    {
        colspan: 2,
        render: () => 'total'
    },
    {
        render: sum => sum('age')
    },
    {
        render: sum => sum('score')
    }
]

image

antd v4 había admitido la tabla summary : # 21656

image

https://ant.design/components/table/#components -table-demo-summary

antd4 admite resumen, pero creo que este resumen aún debe repetirse. Aunque la forma actual de usarlo es gratuita, pero al mismo tiempo el impacto es que el código es demasiado engorroso y no se ajusta a la intención original de antd4 de ser más simple

Un escenario simple común es resumir los datos de la página actual. La experiencia amigable debe ser configurar directamente el resumen: verdadero en la nube, de modo que el código esté ordenado y unificado. Muchos escenarios complejos pueden usar la barra de resumen actual.

¿Fue útil esta página
0 / 5 - 0 calificaciones