Ant-design: Aucun moyen d'afficher les données statistiques d'agrégation dans le tableau

Créé le 11 avr. 2017  ·  78Commentaires  ·  Source: ant-design/ant-design

Version

2.9.1

Environnement

navigateur

Lien de reproduction

http: // aucun

Étapes à suivre pour reproduire

Je veux afficher les statistiques d'agrégation au pied de la table, j'essaye les méthodes suivantes:

  1. en utilisant footer prop, ajoutez tr et td
      <Table
        dataSource={dataSource}
        footer={() => {
          return (
            <tr className='ant-table-row  ant-table-row-level-0'>
              <td>总计</td>
              <td>总计</td>
            <td>总计</td>
            </tr>
          )
        }}
      />
  1. ajouter des données supplémentaires dans dataSource prop
dataSource.push({id: '总计', price: '3000'})

Qu'attend-on?

Une image vaut mieux que mille mots:

Que se passe-t-il réellement?

  1. using footer prop, Mais le footer prop n'est pas adapté au corps de la table.

  2. ajoutez des données supplémentaires dans dataSource prop, mais si la longueur de la source de données est supérieure à pageSize , les données supplémentaires seront ignorées.

Inactive IssueHuntFest ❓FAQ 💡 Feature Request

Commentaire le plus utile

Peut-être pouvons-nous faire quelque chose pour que footer corresponde au corps de la table?

Tous les 78 commentaires

Bonjour @TangMonk , il semble que vous demandez une fonctionnalité plutôt que de signaler un bogue, j'ai bien peur que nous n'ayons pas l'intention de mettre en œuvre cette fonctionnalité. Vous pouvez désactiver la pagination par défaut de la table et implémenter la pagination par vous-même.

Peut-être pouvons-nous faire quelque chose pour que footer corresponde au corps de la table?

@yesmeck , merci pour votre réponse, mais il y a trop de problèmes à ce sujet, je pense que cette fonctionnalité est vraiment utile et nécessaire.

problèmes connexes: # 3591, # 1483, # 4581

@ afc163 , merci!

Quelle est votre suggestion ou solution?

Je ne suis pas sûr, je pense qu'il ne peut pas limiter strictement la taille des données de la table en utilisant pageSize , les données doivent être traitées côté serveur plutôt que côté client, nous pouvons donc ajouter toutes les données supplémentaires à la table

Salut,
Y a-t-il des mises à jour sur ces fonctionnalités? Ou une autre façon de le faire?

@yesmeck La solution la plus simple est de rendre le pied de page un <tfoot> réel à l' <div> supplémentaire à l'extérieur du tableau.

Les gens essaient de compresser une ligne supplémentaire dans dataSource simplement parce qu'ils veulent que la disposition du tableau aligne les colonnes pour eux.

Oui, nous avons déjà un accessoire footer , nous ne pouvons pas trouver un nom approprié pour <tfoot/> .

Je suggère de réimplémenter le prop footer actuel pour le rendre <tfoot /> intérieur d'une table, sans ajouter un nouveau tfoot prop. Ne pensez pas que ça cassera quoi que ce soit.

@yesmeck On dirait que cette fonctionnalité est fréquemment demandée. J'ai également du mal à ajouter une ligne de résumé. Vous avez un travail autour, mais implique une manipulation hacky dom, heureux de voir une solution plus jolie.

Quelqu'un dans l'équipe s'en occupe déjà? Si non, je pourrais peut-être examiner la question.

Vous pouvez essayer PR.

@yesmeck Ici vous allez: https://github.com/react-component/table/pull/191
Voir exemple / renderFooterInTable pour l'effet

Après avoir réfléchi un peu à l'API tfoot , j'aimerais l'ajouter à la propriété 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',
}];

rend

screen shot 2018-02-27 at 15 03 33

Il est plus clair de faire une différence entre les Table[footer] actuels.

Bonne idée. Je suis d'accord que ce serait un meilleur endroit pour insérer une nouvelle API.

@hackape Pourriez-vous proposer un nouveau PR?

chose sûre

https://codesandbox.io/s/m45r6o4nj8
Atteint, mais il y a un problème avec la liaison de la barre de défilement, il est plus pratique de voir

@yesmeck quel est l'état de

Je l'ai vu fusionné 👍

Cependant, j'ai reçu une demande de fonctionnalité supplémentaire. Je voudrais proposer que le soi-disant "pied de page" apparaisse en haut du tableau, juste sous l'en-tête du tableau.

Exemple:
image

La fonctionnalité réellement demandée discutée tout le temps est un moyen de se faufiler dans une ligne supplémentaire pour afficher des informations statistiques - en d'autres termes une "ligne de résumé", sans altérer le contenu de dataSource , pas un "pied de page" dans le sens de la position.

@hackape Vous pouvez utiliser le regroupement de colonnes, voir https://codesandbox.io/s/pmorq2x2lq

Oui, si c'était uniquement à des fins de positionnement, ce serait un moyen viable. Mais dans le sens de la logique métier, il est préférable de laisser l'utilisateur le faire via mon API proposée.

Pensez que nous pouvons renommer l'API column.footer en 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'
  }
}]

Je propose d'introduire deux nouveaux professionnels nommés pinnedTopData et 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}
/>

Rendus:

| Prix ​​| Nom |
| ---------- | ------ |
| Total: 8 | |
| 3 | Foo |
| 5 | Bar |
| Total: 8 | |

Il est préférable de résoudre # 6896 et ce problème avec la même API.

Y a-t-il de nouveaux progrès?

@Nokecy voit sa solution de deux manières. Il ne l'a pas ajouté temporairement à l'attribut. Je pense que sa re-table a cet attribut. Le principe est que le numéro de version est mis à jour vers la dernière version, mais antd package.json doit être modifié. Aussi Deux méthodes,
1. S'il n'y a pas beaucoup de colonnes et qu'aucune barre de défilement n'apparaît, c'est facile à résoudre, j'ai un exemple ci-dessus.
2. Vous pouvez utiliser plusieurs barres de titre pour afficher, ce n'est pas si beau.

J'attends avec impatience qu'ils améliorent cette fonction et continuent à faire attention, mais notre antd est de 2. Même si elle est mise à jour, je ne sais pas si la version

Une mise à jour pour ce problème ??

avant de pouvoir expédier une API officielle, pour l'instant, je suggère de fournir un composant personnalisé table.props.components.body.wrapper et de falsifier le props.children qu'il a reçu.

https://codesandbox.io/s/xpvwpx0npw
J'ai directement manipulé l'élément dom et encapsulé un total. Vous pouvez ajouter beaucoup de pieds de page selon cette méthode, mais le responsable ne recommande pas la manipulation directe de l'élément dom. Si vous en avez besoin de toute urgence, vous pouvez vous référer à ceci

@ LDD123 le scroll x n'est que sur le pied de page dans votre exemple. le corps doit également défiler avec le pied de page

image

@jagratiTomar le corps

@ LDD123 pouvez-vous partager un exemple où il y a un scroll-y également dans le corps, car dans ce cas, seul le corps doit défiler et non le pied de page

@jagratiTomar maintenant, j'ai caché scroll-x pas de défilement, ça ira

@ LDD123 donc vous dites que quand il y a scroll-y cet exemple fonctionnerait bien?

ouais

Bonjour @yesmeck @ afc163 ,

Nos concepteurs mettent le pied de page (il contient les valeurs agrégées) au-dessus du corps et juste en dessous de l'en-tête à des fins UX. Les flèches pour le tri sur l'en-tête et le pied de page n'ont que des valeurs agrégées. Avec ColumnGroup, les flèches pour le tri sont ajoutées en bas. Du point de vue du style, il est beaucoup plus facile de styliser le pied de page et de le placer en haut car le conteneur de pied de page a une couleur différente et que seules certaines cellules ont un séparateur.

Je ferais juste:

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

Le composant de table pourrait avoir quelque chose comme ceci:

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

Conception:
screen shot 2018-05-30 at 17 07 38

Ne vous inquiétez pas du texte non aligné dans les cellules, il s'agit d'une page déjà terminée, ils doivent s'aligner sur la nouvelle que nous codons.

Je pourrais offrir mon aide si je savais qu'il pourrait être publié d'ici 2 ou 3 semaines (pied de colonne et alignement). Sinon, je serai obligé de trouver d'autres solutions.

Oh et je ne pouvais pas comprendre si # 6896 concernait le pied de page de la colonne, alors j'ai écrit ici.

Merci.

@kaanozcan J'ai soumis un PR mettant en œuvre la même idée (voir ici ) en mars, l'équipe de base l'a fusionné, puis il a été rétabli. On dirait qu'ils ont une autre idée sur la façon dont le problème devrait être abordé. Compte tenu de la situation, je vous suggère d'emprunter la voie «trouver d'autres solutions».

@kaanozcan Voici un exemple qui permet d'atteindre votre objectif par des composants personnalisés https://codesandbox.io/s/xjpkx9rzzw

@yesmeck Cela fonctionne parfaitement. Merci.

La fermeture en raison de la demande initiale peut être réalisée par des composants personnalisés.

@yesmeck Pouvons-nous fournir une démo sur ce cas d'utilisation?

https://codesandbox.io/s/xjpkx9rzzw
Cet exemple n'a aucune signification pratique. Parce que si les données changent .. La dernière somme n'utilise pas les dernières données. C'est le résultat de la dernière actualisation. Elle devrait être là où se trouvent des données sales.

@yesmeck L'exemple que vous avez donné ne peut pas être utilisé ... car les données ne peuvent pas être modifiées.
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", }, ]; comme cette modification ... en fait la somme finale est incorrecte.

@yesmeck https://codesandbox.io/s/xjpkx9rzzw Cette démo a un problème, lorsque vous définissez à gauche de fixe, vous pouvez voir que le style est en désordre。

J'ai réussi à le faire en utilisant le wrapper de composant, mais c'est un peu gênant. Le code ressemble à ceci

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>
  );
}

Ce qui est ennuyeux, c'est que je dois appeler getLocalData si je veux que les données agrégées soient calculées sur les lignes filtrées.
Ce serait beaucoup plus agréable si le body wrapper recevait la table ref comme accessoire ou avait un moyen plus simple d'accéder aux données qui seront rendues (props.children est une liste de nœuds de réaction, pas très utile pour calculer les agrégats)

Pourrions-nous utiliser footer prop mais restituer dans une table au lieu de div supplémentaires?

Temporairement traité comme ceci:

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>
                                        );
                                    }}

Ce n'est pas parfait.

Dans l'attente du pied des colonnes qui sortira bientôt O (∩_∩) O

@ybning Avez-vous des problèmes avec les colonnes fixes? Beaucoup de ces colonnes fixes auront des problèmes. .

@yesmeck Votre exemple casse le comptage des tables internes: https://codesandbox.io/s/rrpo02qwkq
Accédez à la page 2 puis revenez à la page 1, il duplique les données à chaque navigation.

Une mise à jour pour ce problème?

@linrf non, j'espère que quelqu'un pourra résoudre ce problème

Pouvons-nous ajouter un accessoire total pour traiter les statistiques d'agrégation?
total est différent avec footer ,
n'accepte qu'une fonction pour traiter les données de la colonne, la valeur par défaut est reduce

v7a kvx 5cig rjeo 696g
J'ai enfin mis le total dans la colonne

Le rendu du contenu du pied de page de la table d'antd n'est vraiment pas facile à utiliser, en particulier lorsque la table elle-même a des colonnes fixes.

Vous pouvez modifier la façon de l'implémenter avec deux tableaux, l'un pour le rendu du tableau d'origine et l'autre pour le rendu de l'élément de pied de page inférieur. Avec la couverture de style, masquez l'en-tête du pied de tableau et la barre de défilement de la zone de défilement du tableau d'origine. Enfin, ajoutez le code JS pour aligner les positions de défilement horizontal des deux tableaux. C'est presque la même chose.

Composants:

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>
    );
  }
}

Fichier de couverture de style:

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

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

+1 J'adorerais avoir un moyen d'afficher les agrégations de colonnes dans le pied de page.

Cela peut être implémenté à l'aide de composants 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 a financé 5,00 $ pour ce numéro.


@piuccio Selon votre façon de penser, je l'écris à la

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();

J'utilise ce package de version, exécuter ce code a échoué.
"antd": "2.13.14", "react": "15.4.0", "react-dom": "15.4.0"

Message d'erreur
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 C'est probablement votre paramètre de résolution de module lors de l'importation react . Essayez de changer

import from 'react';

dans ceci:

import * as react from 'react'

J'ai fait un composant,
Utilisez le modèle de colonnes pour rendre le pied de page
Cependant, les barres de défilement ne sont actuellement pas prises en charge.

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;

Appel de page

...
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 ();
courant var;
var pageSize;
var state = this.state; // S'il n'y a pas de pagination, tous sont affichés par défaut

  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;
}

Il s'agit du code source des données de traitement de la table. Pouvez-vous ajouter une fonction ici pour calculer la somme des valeurs de la liste, ajouter le nombre total de données lors de la sortie et soustraire les données que vous venez d'ajouter de la page et de la taille de la page @sorrycc

après 2 ans, ce problème persiste.

après 2 ans, ce problème existe toujours.

J'ai initialement utilisé la méthode de modification du rendu de la réécriture de col et d'ajout de données dans la table non paginée:

image

Mais dans le cas de la pagination, si plusieurs données sont téléchargées, elles seront supprimées https://github.com/ant-design/ant-design/blob/fee5e291632cce131611dd1a9e2ab89e02ee43a3/components/table/Table.tsx#L407

Je veux faire des relations publiques, mais j'ai peur que la conception de mon API ne réponde pas aux exigences de mon patron @ afc163 ...

après 2 ans, ce problème existe toujours.

la nouvelle table en route. En attendant la nouvelle table

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

@ alexchen1875 Cela n'a rien mentionné à ce sujet.

@ alexchen1875 Cela n'a rien mentionné à ce sujet.

Lisez attentivement les instructions de la section tableau.

@ alexchen1875 génial!

Je souhaite soumettre un PR et ajouter temporairement un accessoire "Autoriser les données à ne pas recadrer les données" pour prendre en charge le saut https://github.com/ant-design/ant-design/blob/61e319b66826530a1882c20a41862a15d57b120a/components/table/Table.tsx La logique de filtrage de https://github.com/ant-design/ant-design/issues/5710#issuecomment -524164125 également disponible dans le cas de la pagination, je ne sais pas si l'équipe acceptera ...

J'ai modifié cette démo ,
ajout de la prise en charge des colonnes fixes , du regroupement des en-têtes , de la fusion et du défilement des cellules ,
J'ai utilisé \

et la pagination ne sera pas affectée.Utilisé temporairement dans mon projet

👉 nouvelle adresse de démonstration

utilisation:

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

image

antd v4 avait pris en charge le tableau summary : https://github.com/ant-design/ant-design/issues/21656

image

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

antd v4 avait pris en charge la table summary : # 21656

image

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

antd4 prend en charge le résumé, mais je pense que ce résumé doit encore être réitéré. Bien que la façon actuelle de l'utiliser soit gratuite, mais en même temps, l'impact est que le code est trop lourd et ne correspond pas à l'intention originale d'antd4 de devenir plus simple

Un scénario simple courant consiste à résumer les données de la page en cours. L'expérience conviviale devrait être de configurer directement summary: true sur le cloumn, afin que le code soit ordonné et unifié. De nombreux scénarios complexes peuvent utiliser la barre de résumé actuelle.

Cette page vous a été utile?
0 / 5 - 0 notes