Ant-design: Невозможно отобразить данные статистики агрегирования в таблице

Созданный на 11 апр. 2017  ·  78Комментарии  ·  Источник: ant-design/ant-design

Версия

2.9.1

Окружающая обстановка

браузер

Ссылка для воспроизведения

http: // нет

Действия по воспроизведению

Я хочу показать статистику агрегирования в нижнем колонтитуле таблицы, я пробую следующие способы:

  1. используя footer prop, добавьте к нему tr и td
      <Table
        dataSource={dataSource}
        footer={() => {
          return (
            <tr className='ant-table-row  ant-table-row-level-0'>
              <td>总计</td>
              <td>总计</td>
            <td>总计</td>
            </tr>
          )
        }}
      />
  1. добавить дополнительные данные в dataSource prop
dataSource.push({id: '总计', price: '3000'})

Что ожидается?

Одна картинка стоит тысячи слов:

Что на самом деле происходит?

  1. используя footer prop, но footer prop не подходит для таблицы tbody.

  2. добавить дополнительные данные в dataSource prop, но если длина dataSource превышает pageSize , дополнительные данные будут проигнорированы.

Inactive IssueHuntFest ❓FAQ 💡 Feature Request

Самый полезный комментарий

Может быть, мы сможем сделать что-нибудь, чтобы footer подходило к телу стола?

Все 78 Комментарий

Привет @TangMonk , похоже, вы запрашиваете функцию, а не сообщаете об ошибке. Боюсь, что у нас нет плана по реализации этой функции. Вы можете отключить разбиение на страницы по умолчанию и реализовать разбиение на страницы самостоятельно.

Может быть, мы сможем сделать что-нибудь, чтобы footer подходило к телу стола?

@yesmeck , спасибо за ответ, но здесь слишком много проблем, я думаю, что эта функция действительно полезна и необходима.

связанные вопросы: # 3591, # 1483, # 4581

@ afc163 , спасибо!

Какое ваше предложение или решение?

Я не уверен, я думаю, что нельзя строго ограничить размер данных таблицы с помощью pageSize , данные должны обрабатываться на стороне сервера, а не на стороне клиента, поэтому мы можем добавить любые дополнительные данные в таблицу

Привет,
Есть ли какие-нибудь обновления по этим функциям? Или другим способом?

@yesmeck Простейшее решение - сделать так, чтобы нижний колонтитул отображал реальный <tfoot> внутри таблицы вместо добавления лишнего <div> вне таблицы.

Люди пытаются втиснуть дополнительную строку в dataSource просто потому, что они хотят, чтобы макет таблицы выровнял для них столбцы.

Да, у нас уже есть опора footer , не могу определить подходящее имя для <tfoot/> .

Я предлагаю повторно реализовать текущую опору footer чтобы она отображала внутреннюю таблицу <tfoot /> , а не добавляла новую опору tfoot . Не думайте, что это что-нибудь сломает.

@yesmeck Похоже, эту функцию часто запрашивают. Я также изо всех сил пытаюсь добавить итоговую строку. Есть работа, но включает в себя хакерские манипуляции с домом, рад видеть более красивое решение.

Кто-нибудь из команды уже позаботился об этом? Если нет, возможно, я мог бы изучить это.

Можно попробовать PR.

@yesmeck Вот и все: https://github.com/react-component/table/pull/191
См. Пример / renderFooterInTable для эффекта

Подумав немного над tfoot API, я хотел бы добавить его в свойство 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',
}];

оказывает

screen shot 2018-02-27 at 15 03 33

Более наглядно провести различие между текущими Table[footer] .

Хорошая идея. Я согласен, что это было бы лучшим местом для использования нового API.

@hackape Не могли бы вы предложить новый пиар?

верная вещь

https://codesandbox.io/s/m45r6o4nj8
Реализовано, но есть проблема с привязкой полосы прокрутки, удобнее видеть

@yesmeck в каком состоянии сейчас

Видел это слияние 👍 @yesmeck

Однако я получил дополнительный запрос функции. Я хотел бы предложить, чтобы так называемый «нижний колонтитул» отображался вверху таблицы, прямо под заголовком таблицы.

Пример:
image

Фактически запрошенная функция, которая обсуждается все время, - это способ втиснуть дополнительную строку для отображения статистической информации - другими словами, «сводную строку», не изменяя содержимое dataSource , а не «нижний колонтитул» в позиционный смысл.

@hackape Вы можете использовать группировку столбцов, см. https://codesandbox.io/s/pmorq2x2lq

Да, если бы это было исключительно для позиционирования, это было бы жизнеспособным средством. Но с точки зрения бизнес-логики лучше позволить пользователю делать это через предложенный мной API.

Думаю, мы можем переименовать column.footer API в 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'
  }
}]

Я предлагаю представить двух новых профессионалов с именами pinnedTopData и 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}
/>

Оказывает:

| Цена | Имя |
| ---------- | ------ |
| Всего: 8 | |
| 3 | Фу |
| 5 | Бар |
| Всего: 8 | |

Лучше решить # 6896 и эту проблему с помощью того же API.

Есть новый прогресс?

@Nokecy видит свое решение двояко. Он не добавил его к атрибуту временно. Я думаю, что его повторная таблица имеет этот атрибут. Предпосылка заключается в том, что номер версии обновлен до последней, но antd package.json должен быть изменен. Два метода,
1. Если столбцов мало и полоса прокрутки не появляется, это легко решить, у меня есть пример выше.
2. Вы можете использовать несколько строк заголовка для отображения, это выглядит не так красиво.

Я с нетерпением жду их улучшения этой функции и обращаю внимание, но наш antd - 2. Даже если он обновлен, я не знаю, будет ли у версии

Любое обновление для этой проблемы ??

прежде чем они смогут отправить официальный API, пока я предлагаю предоставить пользовательский компонент table.props.components.body.wrapper и изменить полученный props.children .

https://codesandbox.io/s/xpvwpx0npw
Я напрямую манипулировал элементом dom и инкапсулировал итог. Вы можете добавить много нижних колонтитулов с помощью этого метода, но чиновник не рекомендует напрямую управлять элементом dom. Если вам это нужно срочно, вы можете обратиться к этому

@ LDD123 прокрутка x находится только в нижнем колонтитуле в вашем примере. тело также должно прокручиваться с нижним колонтитулом

image

@jagratiTomar тело будет прокручиваться при прокрутке нижнего колонтитула

@ LDD123 можете ли вы поделиться и примером, где есть прокрутка также в теле, потому что в этом случае только тело должно прокручиваться, а не нижний колонтитул

@jagratiTomar сейчас, я скрыл scroll-x, а не прокручиваю, все будет в порядке

@ LDD123, значит, вы говорите, что при прокрутке этот пример будет работать правильно?

да

Привет @yesmeck @ afc163 ,

Наши дизайнеры помещают нижний колонтитул (он содержит агрегированные значения) поверх тела и прямо под заголовком для целей UX. Стрелки для сортировки в верхнем и нижнем колонтитулах имеют только агрегированные значения. С помощью ColumnGroup стрелки для сортировки добавляются внизу. С точки зрения стилизации намного проще стилизовать нижний колонтитул и установить его вверху, поскольку контейнер нижнего колонтитула имеет другой цвет и только некоторые ячейки имеют разделитель.

Я бы просто сделал:

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

Компонент таблицы может иметь что-то вроде этого:

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

Дизайн:
screen shot 2018-05-30 at 17 07 38

Не обращайте внимания на невыровненный текст в ячейках, это с ранее созданной страницы, которую они должны выровнять по новой, которую мы кодируем.

Я мог бы предложить свою помощь, если бы знал, что он может быть выпущен в течение 2 или 3 недель (нижний колонтитул столбца и его выравнивание). В противном случае мне придется искать другие решения.

О, и я не мог понять, касается ли # 6896 нижнего колонтитула столбца, поэтому я написал здесь.

Благодарю.

@kaanozcan Я представил PR, реализующий ту же идею (см. здесь ) еще в марте, основная команда объединила его, а затем вернули. Похоже, у них есть другие представления о том, как решать проблему. Учитывая ситуацию, я бы посоветовал вам пойти по пути «найти другие решения».

@kaanozcan Вот пример достижения вашей цели с помощью пользовательских компонентов https://codesandbox.io/s/xjpkx9rzzw

@yesmeck Это отлично работает. Благодарю.

Закрытие по первоначальному запросу может быть выполнено с помощью пользовательских компонентов.

@yesmeck Не могли бы мы предоставить демонстрацию этого

https://codesandbox.io/s/xjpkx9rzzw
Этот пример не имеет практического значения, потому что если данные изменяются ... Последняя сумма не использует самые последние данные. Это результат последнего обновления. Он должен быть там, где есть грязные данные.

@yesmeck Приведенный вами пример нельзя использовать ... потому что данные не могут быть изменены.
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", }, ]; типа этой модификации ... на самом деле окончательная сумма неверна.

@yesmeck https://codesandbox.io/s/xjpkx9rzzw У этой демонстрации есть проблема, когда вы устанавливаете левую часть фиксированной, вы можете видеть, что стиль в беспорядке。

Мне удалось это сделать с помощью обертки компонентов, но это немного неудобно. Код выглядит так

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

Раздражает то, что мне нужно вызвать getLocalData если я хочу, чтобы агрегированные данные вычислялись по отфильтрованным строкам.
Было бы намного лучше, если бы оболочка тела получала ссылку на таблицу в качестве опоры или имела более простой способ доступа к данным, которые будут отображаться (props.children - это список реагирующих узлов, не очень полезный для вычисления агрегатов)

Можно ли использовать footer prop, но отображать в таблице вместо дополнительного div?

Временно обрабатывается так:

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

Это не идеально.

С нетерпением жду подножия колонн, которые скоро выйдут O (∩_∩) O

@ybning У вас проблемы с фиксированными столбцами? Многие из этих фиксированных столбцов будут иметь проблемы. .

@yesmeck Ваш пример нарушает подсчет внутренней таблицы: https://codesandbox.io/s/rrpo02qwkq
Перейдите на страницу 2, затем вернитесь на страницу 1, данные дублируются для каждой навигации.

Есть обновления по этой проблеме?

@linrf нет, надеюсь, кто-нибудь сможет решить эту проблему

Не могли бы мы добавить опору total для статистики агрегирования сделок?
total отличается от footer ,
принимать только функцию для обработки данных столбца, по умолчанию reduce

v7a kvx 5cig rjeo 696g
Я наконец поместил сумму в столбец

Рендеринг содержимого нижнего колонтитула таблицы antd действительно непрост в использовании, особенно когда сама таблица имеет фиксированные столбцы.

Вы можете изменить способ реализации с помощью двух таблиц, одна для визуализации исходной таблицы, а другая для визуализации нижнего элемента нижнего колонтитула. Используя покрытие стилей, скройте верхнюю часть нижнего колонтитула таблицы и полосу прокрутки исходной области прокрутки таблицы. Наконец, добавьте код JS, чтобы выровнять позиции горизонтальной прокрутки двух таблиц. Это почти то же самое.

Составные части:

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

Файл покрытия стиля:

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

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

+1 Хотелось бы иметь способ отображать агрегаты столбцов в нижнем колонтитуле.

Это может быть реализовано с помощью компонентов 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 выделил 5 долларов США на решение этой проблемы.


@piuccio По вашему мнению, я пишу это машинописным шрифтом.

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

Я использую эту версию пакета, запустить этот код не удалось.
«antd»: «2.13.14», «react»: «15.4.0», «react-dom»: «15.4.0»

сообщение об ошибке
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 Вероятно, это ваша настройка разрешения модуля при импорте react . Попробуйте изменить

import from 'react';

в это:

import * as react from 'react'

Я сделал компонент,
Используйте модель столбцов для визуализации нижнего колонтитула
Однако полосы прокрутки в настоящее время не поддерживаются.

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;

Вызов страницы

...
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 current;
var pageSize;
var state = this.state; // Если нет разбиения по страницам, все отображаются по умолчанию

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

Это то, может ли исходный код данных обработки таблицы добавить сюда функцию для вычисления суммы значений списка, добавить общее количество данных при выводе и вычесть данные, только что добавленные со страницы, и pageize @sorrycc

через 2 года эта проблема все еще существует.

спустя 2 года эта проблема все еще существует.

Первоначально я использовал метод изменения рендеринга перезаписи col и добавления данных в невыгружаемую таблицу:

image

Но в случае разбивки на страницы, если загружено несколько данных, они будут уничтожены. Https://github.com/ant-design/ant-design/blob/fee5e291632cce131611dd1a9e2ab89e02ee43a3/components/table/Table.tsx#L407

Хочу пиариться, но боюсь, что мой дизайн API не соответствует требованиям моего начальника @ afc163 ...

спустя 2 года эта проблема все еще существует.

новый стол в пути. с нетерпением ждем нового стола

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

@ alexchen1875 Это не упомянул ничего, связанного с этим.

@ alexchen1875 Это не упомянул ничего, связанного с этим.

Внимательно прочтите инструкции в разделе таблицы.

@ alexchen1875 круто !

Я хочу отправить PR и временно добавить реквизит «Разрешить данные не обрезать данные» для поддержки пропуска https://github.com/ant-design/ant-design/blob/61e319b66826530a1882c20a41862a15d57b120a/components/table/Table.tsx Логика фильтра https://github.com/ant-design/ant-design/issues/5710#issuecomment -524164125 также доступным в случае разбивки на страницы, я не знаю, примет ли команда ...

Я модифицировал эту демонстрацию ,
добавлена ​​поддержка фиксированных столбцов , группировки заголовков , объединения ячеек и прокрутки ,
Я использовал \

и пейджинг не будет затронут.Временно используется в моем проекте

👉 новый демонстрационный адрес

Применение :

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

image

antd v4 поддерживал Table summary : https://github.com/ant-design/ant-design/issues/21656

image

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

antd v4 поддерживал Table summary : # 21656

image

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

antd4 поддерживает резюме, но я считаю, что это резюме все еще необходимо повторить. Хотя текущий способ его использования бесплатный, но в то же время влияние заключается в том, что код слишком громоздкий и не соответствует первоначальному замыслу antd4, чтобы стать проще.

Распространенный простой сценарий - суммирование данных текущей страницы. Дружественный интерфейс должен заключаться в непосредственной настройке summary: true в облаке, чтобы код был аккуратным и унифицированным. Во многих сложных сценариях можно использовать текущую панель сводки.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги