Compare commits

...
4 Commits
Author SHA1 Message Date
Tanner Linsley ba1325336f 4.2.2 2017-01-16 15:01:44 -07:00
Tanner Linsley 7bd30b623c Improved Sorting Performance 2017-01-16 15:01:37 -07:00
Tanner Linsley f72fec3cc2 4.2.1 2017-01-16 14:18:20 -07:00
Tanner Linsley a8a0d1bab8 Fix pageSize bug and 1 Million rows example 2017-01-16 14:18:11 -07:00
6 changed files with 211 additions and 57 deletions
+2
View File
@@ -15,6 +15,7 @@ import ServerSide from '../stories/ServerSide.js'
import SubComponents from '../stories/SubComponents.js'
import Pivoting from '../stories/Pivoting.js'
import PivotingSubComponents from '../stories/PivotingSubComponents.js'
import MillionRows from '../stories/MillionRows.js'
//
configure(() => {
storiesOf('1. Docs')
@@ -35,4 +36,5 @@ configure(() => {
.add('Sub Components', SubComponents)
.add('Pivoting & Aggregation', Pivoting)
.add('Pivoting & Aggregation w/ Sub Components', PivotingSubComponents)
.add('1 Million Rows w/ Pivoting & Sub Components', MillionRows)
}, module)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "react-table",
"version": "4.2.0",
"version": "4.2.2",
"description": "A fast, lightweight, opinionated table and datagrid built on React",
"license": "MIT",
"homepage": "https://github.com/tannerlinsley/react-table#readme",
+68 -54
View File
@@ -170,7 +170,7 @@ export default React.createClass({
oldState.pivotBy !== newState.pivotBy ||
oldState.sorting !== newState.sorting
) {
this.setState(this.getDataModel(nextProps, nextState))
this.setStateWithData(this.getDataModel(nextProps, nextState))
}
},
@@ -178,9 +178,14 @@ export default React.createClass({
const oldState = this.getResolvedState()
const newResolvedState = this.getResolvedState({}, newState)
if (
oldState.resolvedData !== newResolvedState.resolvedData ||
oldState.sorting !== newResolvedState.sorting
) {
Object.assign(newState, this.getDataModel({}, newState))
Object.assign(newState, this.getSortedData({}, newState))
}
// Calculate pageSize all the time
if (newResolvedState.resolvedData) {
newState.pages = newResolvedState.manual ? newResolvedState.pages : Math.ceil(newResolvedState.resolvedData.length / newResolvedState.pageSize)
}
return this.setState(newState, cb)
},
@@ -190,8 +195,7 @@ export default React.createClass({
const newState = this.getResolvedState(nextProps, nextState)
// State changes that trigger a render
if (
oldState.sorting !== newState.sorting ||
oldState.resolvedData !== newState.resolvedData ||
oldState.sortedData !== newState.sortedData ||
oldState.page !== newState.page ||
oldState.pageSize !== newState.pageSize ||
oldState.expandedRows !== newState.expandedRows
@@ -231,6 +235,7 @@ export default React.createClass({
pageSize,
page,
sorting,
pages,
// Pivoting State
pivotBy,
pivotValKey,
@@ -259,13 +264,14 @@ export default React.createClass({
standardColumns,
allDecoratedColumns,
hasHeaderGroups,
pages
// Sorted Data
sortedData
} = resolvedProps
// Pagination
const startRow = pageSize * page
const endRow = startRow + pageSize
const pageRows = manual ? resolvedData : resolvedData.slice(startRow, endRow)
const pageRows = manual ? resolvedData : sortedData.slice(startRow, endRow)
const minRows = this.getMinRows()
const padRows = pages > 1 ? _.range(pageSize - pageRows.length)
: minRows ? _.range(Math.max(minRows - pageRows.length, 0))
@@ -332,7 +338,7 @@ export default React.createClass({
>
{typeof column.header === 'function' ? (
<column.header
data={resolvedData}
data={sortedData}
column={column}
/>
) : column.header}
@@ -377,7 +383,7 @@ export default React.createClass({
<span key={column.id}>
{typeof column.header === 'function' ? (
<column.header
data={resolvedData}
data={sortedData}
column={column}
/>
) : column.header}
@@ -427,7 +433,7 @@ export default React.createClass({
>
{typeof column.header === 'function' ? (
<column.header
data={resolvedData}
data={sortedData}
column={column}
/>
) : column.header}
@@ -535,36 +541,38 @@ export default React.createClass({
const makePadRow = (row, i) => {
return (
<TrComponent
key={i}
className={classnames(trClassName, '-padRow')}
style={trStyle}
>
{SubComponent && (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={_.prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
/>
)}
{standardColumns.map((column, i2) => {
const show = typeof column.show === 'function' ? column.show() : column.show
return (
<TdComponent
key={i2}
className={classnames(column.className, {hidden: !show})}
style={Object.assign({}, tdStyle, column.style, {
flex: `${columnPercentage} 0 auto`,
width: `${column.minWidth}px`
<TrGroupComponent>
<TrComponent
key={i}
className={classnames(trClassName, '-padRow')}
style={trStyle}
>
{SubComponent && (
<ThComponent
className={classnames(thClassname, 'rt-expander-header')}
style={_.prefixAll({
flex: `0 0 auto`,
width: `${expanderColumnWidth}px`
})}
>
&nbsp;
</TdComponent>
)
})}
</TrComponent>
/>
)}
{standardColumns.map((column, i2) => {
const show = typeof column.show === 'function' ? column.show() : column.show
return (
<TdComponent
key={i2}
className={classnames(column.className, {hidden: !show})}
style={Object.assign({}, tdStyle, column.style, {
flex: `${columnPercentage} 0 auto`,
width: `${column.minWidth}px`
})}
>
&nbsp;
</TdComponent>
)
})}
</TrComponent>
</TrGroupComponent>
)
}
@@ -616,11 +624,7 @@ export default React.createClass({
data,
pivotIDKey,
pivotValKey,
subRowsKey,
manual,
sorting,
pageSize,
pages
subRowsKey
} = this.getResolvedState(nextProps, nextState)
// Determine Header Groups
@@ -715,7 +719,7 @@ export default React.createClass({
const columnPercentage = 100 / allVisibleColumns.length
// Access the data
let accessedData = data.map((d, i) => {
let resolvedData = data.map((d, i) => {
const row = {
__original: d,
__index: i
@@ -768,24 +772,34 @@ export default React.createClass({
})
return groupedRows
}
accessedData = groupRecursively(accessedData, pivotBy)
resolvedData = groupRecursively(resolvedData, pivotBy)
}
const resolvedSorting = sorting.length ? sorting : this.getInitSorting(allDecoratedColumns)
// Resolve the data from either manual data or sorted data
const resolvedData = manual ? accessedData : this.sortData(accessedData, resolvedSorting)
return {
resolvedData,
columnPercentage,
pivotColumn,
resolvedData,
allVisibleColumns,
headerGroups,
standardColumns,
allDecoratedColumns,
hasHeaderGroups,
pages: manual ? pages : Math.ceil(resolvedData.length / pageSize)
hasHeaderGroups
}
},
getSortedData (nextProps, nextState) {
const {
manual,
sorting,
allDecoratedColumns,
resolvedData
} = this.getResolvedState(nextProps, nextState)
const resolvedSorting = sorting.length ? sorting : this.getInitSorting(allDecoratedColumns)
// Resolve the data from either manual data or sorted data
return {
sortedData: manual ? resolvedData : this.sortData(resolvedData, resolvedSorting)
}
},
@@ -880,7 +894,7 @@ export default React.createClass({
// Normalize the page to display
const currentRow = pageSize * page
const newPage = Math.floor(currentRow / pageSize)
const newPage = Math.floor(currentRow / newPageSize)
if (onPageSizeChange) {
return onPageSizeChange(newPageSize, newPage)
+1 -1
View File
@@ -108,7 +108,7 @@ $expandSize = 7px
background: alpha(black, .03)
&.-highlight
.rt-tbody
.rt-tr:hover
.rt-tr:not(.-padRow):hover
background: alpha(black, .05)
.-pagination
+138
View File
@@ -0,0 +1,138 @@
import React from 'react'
import _ from 'lodash'
import namor from 'namor'
import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/index'
export default () => {
const data = _.map(_.range(1000000), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),
age: Math.floor(Math.random() * 30),
visits: Math.floor(Math.random() * 100)
}
})
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName'
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age',
aggregate: vals => _.round(_.mean(vals)),
render: row => {
return <span>{row.aggregated ? `${row.value} (avg)` : row.value}</span>
}
}, {
header: 'Visits',
accessor: 'visits',
aggregate: vals => _.sum(vals)
}]
}]
return (
<div>
<div className='table-wrap'>
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
pivotBy={['firstName', 'lastName']}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>You can put any component you want here, even another React Table!</em>
<br />
<br />
<ReactTable
data={data}
columns={columns}
defaultPageSize={3}
showPagination={false}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>It even has access to the row data: </em>
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
</div>
)
}}
/>
</div>
)
}}
/>
</div>
<div style={{textAlign: 'center'}}>
<br />
<em>Tip: Hold shift when sorting to multi-sort!</em>
</div>
<CodeHighlight>{() => getCode()}</CodeHighlight>
</div>
)
}
function getCode () {
return `
const columns = [{
header: 'Name',
columns: [{
header: 'First Name',
accessor: 'firstName'
}, {
header: 'Last Name',
id: 'lastName',
accessor: d => d.lastName
}]
}, {
header: 'Info',
columns: [{
header: 'Age',
accessor: 'age'
}]
}]
export default (
<ReactTable
data={data}
columns={columns}
defaultPageSize={10}
pivotBy={['firstName', 'lastName']}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>You can put any component you want here, even another React Table!</em>
<br />
<br />
<ReactTable
data={data}
columns={columns}
defaultPageSize={3}
showPagination={false}
SubComponent={(row) => {
return (
<div style={{padding: '20px'}}>
<em>It even has access to the row data: </em>
<CodeHighlight>{() => JSON.stringify(row, null, 2)}</CodeHighlight>
</div>
)
}}
/>
</div>
)
}}
/>
)
`
}
+1 -1
View File
@@ -6,7 +6,7 @@ import CodeHighlight from './components/codeHighlight'
import ReactTable from '../lib/index'
export default () => {
const data = _.map(_.range(10000), d => {
const data = _.map(_.range(1000), d => {
return {
firstName: namor.generate({ words: 1, numLen: 0 }),
lastName: namor.generate({ words: 1, numLen: 0 }),