大数据渲染

This commit is contained in:
wanghaoo 2018-12-18 13:59:48 +08:00
parent e6e06fdbcc
commit 8ba93bd05e
14 changed files with 16623 additions and 20555 deletions

100
demo/demolist/Demo30.js Normal file
View File

@ -0,0 +1,100 @@
/**
*
* @title 大数据加载
* Tooltip
* @description
*/
import React, { Component } from "react";
import Tooltip from "bee-tooltip";
import Table from "../../src";
import BigData from "../../src/lib/bigData";
const BigDataTable = BigData(Table);
const columns = [
{
title:'序号',
dataIndex:'index',
width:'50',
render:(text,record,index)=>{
return index
},
fixed:'left'
},
{
title: "用户名", dataIndex: "a", key: "a", width: 580, className: "rowClassName",
render: (text, record, index) => {
return (
<Tooltip inverse overlay={text}>
<span tootip={text} style={{
display: "inline-block",
width: "80px",
textOverflow: "ellipsis",
overflow: "hidden",
whiteSpace: "nowrap",
verticalAlign: "middle",
}}>{text}</span>
</Tooltip>
);
}
},
{ id: "123", title: "性别", dataIndex: "b", key: "b", width: 200},
{ title: "年龄", dataIndex: "c", key: "c", width: 200 },
{
title: "操作",
dataIndex: "d",
key: "d",
fixed:'right',
render(text, record, index) {
return (
<div style={{ position: 'relative' }} title={text} >
<a
href="javascript:;"
tooltip={text}
onClick={() => {
alert('这是第' + index + '列,内容为:' + text);
}}
>
一些操作
</a>
</div>
);
}
}
];
const data = [ ...new Array(10000) ].map((e, i) => {
return { a: i + 'a', b: i + 'b', c: i + 'c', d: i + 'd', key: i };
})
class Demo1 extends Component {
constructor(props) {
super(props);
this.state = {
data: data,
selectedRowIndex: 0
}
}
render() {
return (
<BigDataTable
columns={columns}
data={data}
parentNodeId='parent'
headerHeight={42}
scroll={{y:400}}
onRowClick={(record, index, indent) => {
this.setState({
selectedRowIndex: index
});
}}
/>
);
}
}
export default Demo1;

131
demo/demolist/Demo31.js Normal file
View File

@ -0,0 +1,131 @@
/**
*
* @title 含有嵌套子表格的大数据场景
* @description 通过expandedRowRender参数来实现子表格
*
*/
import React, { Component } from "react";
import Table from "../../src";
import BigData from "../../src/lib/bigData";
const BigDataTable = BigData(Table);
const outColumns = [
{
title: "操作",
dataIndex: "d",
key: "d",
width:200,
render(text, record, index) {
return (
<a
href="#"
onClick={() => {
alert("这是第" + index + "列,内容为:" + text);
}}
>
一些操作
</a>
);
}
},
{ title: "用户名", dataIndex: "a", key: "a", width: 250 },
{ id: "123", title: "性别", dataIndex: "b", key: "b", width: 100 },
{ title: "年龄", dataIndex: "c", key: "c", width: 200 },
];
const innerColumns = [
{
title: "操作",
dataIndex: "d",
key: "d",
width:200,
render(text, record, index) {
return (
<a
href="#"
onClick={() => {
alert("这是第" + index + "列,内容为:" + text);
}}
>
一些操作
</a>
);
}
},
{ title: "用户名", dataIndex: "a", key: "a", width: 100 },
{ id: "123", title: "性别", dataIndex: "b", key: "b", width: 100 },
{ title: "年龄", dataIndex: "c", key: "c", width: 200 },
];
const data16 = [
{ a: "令狐冲", b: "男", c: 41, d: "操作", key: "1" },
{ a: "杨过", b: "男", c: 67, d: "操作", key: "2" },
{ a: "郭靖", b: "男", c: 25, d: "操作", key: "3" }
];
class Demo31 extends Component {
constructor(props){
super(props);
this.state={
data_obj:{}
}
}
expandedRowRender = (record, index, indent) => {
let height = 42 * (this.state.data_obj[record.key].length+ 2);
return (
<Table
columns={innerColumns}
style={{height:height}}
data={this.state.data_obj[record.key]}
/>
);
};
getData=(expanded, record)=>{
//当点击展开的时候才去请求数据
let new_obj = Object.assign({},this.state.data_obj);
if(expanded){
if(record.key==='1'){
new_obj[record.key] = [
{ a: "令狐冲", b: "男", c: 41, d: "操作", key: "1" },
{ a: "杨过", b: "男", c: 67, d: "操作", key: "2" }
]
this.setState({
data_obj:new_obj
})
}else{
new_obj[record.key] = [
{ a: "令狐冲", b: "男", c: 41, d: "操作", key: "1" }
]
this.setState({
data_obj:new_obj
})
}
}
}
haveExpandIcon=(record, index)=>{
//控制是否显示行展开icon该参数只有在和expandedRowRender同时使用才生效
if(index == 0){
return true;
}
return false;
}
render() {
return (
<BigDataTable
columns={outColumns}
data={data16}
onExpand={this.getData}
expandedRowRender={this.expandedRowRender}
scroll={{y:350}}
title={currentData => <div>标题: 这是一个标题</div>}
footer={currentData => <div>表尾: 我是小尾巴</div>}
/>
);
}
}
export default Demo31;

View File

@ -21,14 +21,9 @@ const columns5 = [
fixed: "left" fixed: "left"
}, },
{ title: "Age", width: 100, dataIndex: "age", key: "age", fixed: "left" }, { title: "Age", width: 100, dataIndex: "age", key: "age", fixed: "left" },
{ title: "Column 1", dataIndex: "c1", key: "1" }, { title: "Column 1", dataIndex: "key", key: "1" },
{ title: "Column 2", dataIndex: "c2", key: "2" }, { title: "Column 2", dataIndex: "address", key: "2" },
{ title: "Column 3", dataIndex: "c3", key: "3" },
{ title: "Column 4", dataIndex: "c4", key: "4" },
{ title: "Column 5", dataIndex: "c5", key: "5" },
{ title: "Column 6", dataIndex: "c6", key: "6" },
{ title: "Column 7", dataIndex: "c7", key: "7" },
{ title: "Column 8", dataIndex: "c8", key: "8" }
]; ];
const data5 = [ const data5 = [

File diff suppressed because one or more lines are too long

91
dist/demo.css vendored
View File

@ -2422,6 +2422,9 @@ i.uf {
/* /*
* 选择时删除文本阴影及设置默认选中颜色 * 选择时删除文本阴影及设置默认选中颜色
*/ */
::-moz-selection {
background: rgb(187,222,251);
text-shadow: none; }
::selection { ::selection {
background: rgb(187,222,251); background: rgb(187,222,251);
text-shadow: none; } text-shadow: none; }
@ -5285,7 +5288,7 @@ a, .mdl-accordion, .mdl-button, .mdl-card, .mdl-checkbox, .mdl-dropdown-menu,
.u-panel .u-panel-body { .u-panel .u-panel-body {
padding: 15px 15px; padding: 15px 15px;
position: relative; } position: relative; }
.u-panel .u-panel-body .u-panel-copy { .u-panel .u-panel-body .uf {
position: absolute; position: absolute;
right: 25px; right: 25px;
top: 30px; top: 30px;
@ -5295,7 +5298,7 @@ a, .mdl-accordion, .mdl-button, .mdl-card, .mdl-checkbox, .mdl-dropdown-menu,
margin: 8px; margin: 8px;
border-radius: 4px; border-radius: 4px;
cursor: pointer; } cursor: pointer; }
.u-panel .u-panel-body .u-panel-copy:hover { .u-panel .u-panel-body .uf:hover {
color: #a8a7a7; } color: #a8a7a7; }
.u-panel-default { .u-panel-default {
@ -6671,8 +6674,7 @@ input.u-button[type="submit"] {
border-radius: 0 500px 500px 0; } border-radius: 0 500px 500px 0; }
.u-pagination { .u-pagination {
font-size: 14px; font-size: 14px; }
position: relative; }
.u-pagination-list { .u-pagination-list {
float: left; float: left;
margin: 5px; } margin: 5px; }
@ -6680,10 +6682,6 @@ input.u-button[type="submit"] {
clear: both; clear: both;
display: table; display: table;
content: ''; } content: ''; }
.u-pagination-list > li.iconBtn > a {
padding: 0 11px;
font-size: 22px;
line-height: 1.57142857; }
.u-pagination-list > li > a, .u-pagination-list > li > span { .u-pagination-list > li > a, .u-pagination-list > li > span {
display: inline-block; display: inline-block;
text-decoration: none; text-decoration: none;
@ -6771,15 +6769,9 @@ input.u-button[type="submit"] {
margin: 5px; margin: 5px;
float: left; float: left;
min-width: 120px; } min-width: 120px; }
.u-pagination .data_per_select > span {
display: inline-block;
line-height: 36px;
float: left; }
.u-pagination .data_per_select .u-select { .u-pagination .data_per_select .u-select {
width: 50px; width: 50px;
margin: 0 6px; margin: 0 6px; }
height: 36px;
float: left; }
.u-pagination .data_per_select .u-select .u-select-selection { .u-pagination .data_per_select .u-select .u-select-selection {
height: 36px; } height: 36px; }
.u-pagination .data_per_select .u-select .u-select-selection .u-select-selection-rendered { .u-pagination .data_per_select .u-select .u-select-selection .u-select-selection-rendered {
@ -6799,26 +6791,20 @@ input.u-button[type="submit"] {
.u-pagination .page_jump { .u-pagination .page_jump {
float: left; float: left;
margin: 5px; } margin: 5px; }
.u-pagination .page_jump > span {
display: inline-block;
line-height: 36px;
float: left; }
.u-pagination .page_jump_value { .u-pagination .page_jump_value {
outline: none; outline: none;
-webkit-appearance: none; -webkit-appearance: none;
background: #fff; background: #fff;
border-radius: 4px; border-radius: 4px;
line-height: 32px;
width: 50px; width: 50px;
margin: 0 6px;
text-align: center; text-align: center;
border: 1px solid #d7d7d7; } border: 1px solid #d7d7d7; }
.u-pagination .page_jump_btn, .u-pagination .page_jump_btn {
.u-pagination .page_jump_value { margin-top: -3px;
margin: 0 6px; margin-left: 10px;
padding: 0; border-color: #d7d7d7; }
height: 36px;
line-height: 34px;
box-sizing: border-box;
float: left; }
.u-pagination-total { .u-pagination-total {
float: left; float: left;
height: 36px; height: 36px;
@ -6826,15 +6812,6 @@ input.u-button[type="submit"] {
margin: 5px; } margin: 5px; }
.u-pagination-total span { .u-pagination-total span {
padding: 0 5px; } padding: 0 5px; }
.u-pagination.u-pagination-disabled .u-pagination-disabled-mask {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 46px;
background: rgba(255, 255, 255, 0.6);
z-index: 2;
cursor: not-allowed; }
.pagination-state { .pagination-state {
float: left; float: left;
@ -6941,29 +6918,15 @@ input.u-button[type="submit"] {
margin: 0 5px; margin: 0 5px;
height: 18px; height: 18px;
line-height: 18px; line-height: 18px;
font-size: 14px; font-size: 14px; }
white-space: nowrap;
cursor: pointer;
outline: none;
position: relative;
line-height: 1;
vertical-align: middle; }
.u-checkbox.disabled .u-checkbox-label { .u-checkbox.disabled .u-checkbox-label {
cursor: not-allowed; cursor: not-allowed;
opacity: 0.5; } opacity: 0.5; }
.u-checkbox input[type='checkbox'] { .u-checkbox input[type='checkbox'] {
position: absolute; display: none;
z-index: 3; cursor: pointer; }
cursor: pointer;
opacity: 0;
box-sizing: border-box;
padding: 0;
width: 100%;
height: 100%; }
.u-checkbox input[disabled] { .u-checkbox input[disabled] {
cursor: not-allowed; } cursor: not-allowed; }
.u-checkbox input[type='checkbox']:focus + .u-checkbox-label:before {
border-color: #1e88e5; }
.u-checkbox.is-checked .u-checkbox-label:before { .u-checkbox.is-checked .u-checkbox-label:before {
box-shadow: inset 0 0 0 10px rgb(30,136,229); box-shadow: inset 0 0 0 10px rgb(30,136,229);
border-color: rgb(30,136,229); } border-color: rgb(30,136,229); }
@ -7015,37 +6978,22 @@ input.u-button[type="submit"] {
box-shadow: inset 0 0 0 10px rgb(76,175,80); box-shadow: inset 0 0 0 10px rgb(76,175,80);
border-color: rgb(76,175,80); } border-color: rgb(76,175,80); }
.u-checkbox.u-checkbox-success input[type='checkbox']:focus + .u-checkbox-label:before {
border-color: rgb(76,175,80); }
.u-checkbox.u-checkbox-warning.is-checked .u-checkbox-label:before { .u-checkbox.u-checkbox-warning.is-checked .u-checkbox-label:before {
box-shadow: inset 0 0 0 10px rgb(255,152,0); box-shadow: inset 0 0 0 10px rgb(255,152,0);
border-color: rgb(255,152,0); } border-color: rgb(255,152,0); }
.u-checkbox.u-checkbox-warning input[type='checkbox']:focus + .u-checkbox-label:before {
border-color: rgb(255,152,0); }
.u-checkbox.u-checkbox-danger.is-checked .u-checkbox-label:before { .u-checkbox.u-checkbox-danger.is-checked .u-checkbox-label:before {
box-shadow: inset 0 0 0 10px rgb(244,67,54); box-shadow: inset 0 0 0 10px rgb(244,67,54);
border-color: rgb(244,67,54); } border-color: rgb(244,67,54); }
.u-checkbox.u-checkbox-danger input[type='checkbox']:focus + .u-checkbox-label:before {
border-color: rgb(244,67,54); }
.u-checkbox.u-checkbox-dark.is-checked .u-checkbox-label:before { .u-checkbox.u-checkbox-dark.is-checked .u-checkbox-label:before {
box-shadow: inset 0 0 0 10px rgb(97,97,97); box-shadow: inset 0 0 0 10px rgb(97,97,97);
border-color: rgb(97,97,97); } border-color: rgb(97,97,97); }
.u-checkbox.u-checkbox-dark input[type='checkbox']:focus + .u-checkbox-label:before {
border-color: rgb(97,97,97); }
.u-checkbox.u-checkbox-info.is-checked .u-checkbox-label:before { .u-checkbox.u-checkbox-info.is-checked .u-checkbox-label:before {
box-shadow: inset 0 0 0 10px rgb(0,188,212); box-shadow: inset 0 0 0 10px rgb(0,188,212);
border-color: rgb(0,188,212); } border-color: rgb(0,188,212); }
.u-checkbox.u-checkbox-info input[type='checkbox']:focus + .u-checkbox-label:before {
border-color: rgb(0,188,212); }
/* FormGroup */ /* FormGroup */
/* Navlayout */ /* Navlayout */
/* keyframes 定义 */ /* keyframes 定义 */
@ -7583,8 +7531,7 @@ ul {
zoom: 1; zoom: 1;
position: absolute; position: absolute;
right: 4px; right: 4px;
padding: 0 0 0 8px; padding: 0 0 0 8px; }
top: -3px; }
.u-select-selection--multiple .u-select-selection-choice-remove:before { .u-select-selection--multiple .u-select-selection-choice-remove:before {
display: block; display: block;
font-family: "uf"; } font-family: "uf"; }
@ -8496,8 +8443,6 @@ ul {
overflow: hidden; } overflow: hidden; }
.u-table td { .u-table td {
border-bottom: 1px solid #e9e9e9; } border-bottom: 1px solid #e9e9e9; }
.u-table tr {
transition: all 0.3s ease; }
.u-table tr:hover { .u-table tr:hover {
background: rgb(227,242,253); } background: rgb(227,242,253); }
.u-table tr:hover td .uf-eye { .u-table tr:hover td .uf-eye {
@ -8528,6 +8473,8 @@ ul {
.u-table-header { .u-table-header {
overflow: hidden; overflow: hidden;
background: #f7f7f7; } background: #f7f7f7; }
.u-table.fixed-height td {
padding: 0px 8px; }
.u-table-fixed-header .u-table-body { .u-table-fixed-header .u-table-body {
background: #fff; background: #fff;
position: relative; } position: relative; }

6
dist/demo.css.map vendored

File diff suppressed because one or more lines are too long

36504
dist/demo.js vendored

File diff suppressed because one or more lines are too long

6
dist/demo.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -93,6 +93,7 @@
"jest": "^22.0.4", "jest": "^22.0.4",
"react": "^16.6.3", "react": "^16.6.3",
"react-addons-test-utils": "^15.5.0", "react-addons-test-utils": "^15.5.0",
"react-dom": "^16.6.3" "react-dom": "^16.6.3",
"shineout": "^1.1.7"
} }
} }

View File

@ -173,10 +173,14 @@ class Table extends Component {
if(nextProps.columns.length !== this.props.columns.length && this.refs && this.refs.bodyTable){ if(nextProps.columns.length !== this.props.columns.length && this.refs && this.refs.bodyTable){
this.scrollTop = this.refs.bodyTable.scrollTop; this.scrollTop = this.refs.bodyTable.scrollTop;
} }
} else if (nextProps.children !== this.props.children) { } else if (nextProps.children !== this.props.children) {
this.columnManager.reset(null, nextProps.children); this.columnManager.reset(null, nextProps.children);
} }
//适配lazyload
if(nextProps.scrollTop){
this.refs.bodyTable.scrollTop = nextProps.scrollTop;
this.scrollTop = nextProps.scrollTop;
}
if (!nextProps.originWidth) { if (!nextProps.originWidth) {
this.computeTableWidth(); this.computeTableWidth();
} }
@ -489,7 +493,12 @@ class Table extends Component {
const expandIconAsCell = fixed !== 'right' ? props.expandIconAsCell : false; const expandIconAsCell = fixed !== 'right' ? props.expandIconAsCell : false;
const expandIconColumnIndex = fixed !== 'right' ? props.expandIconColumnIndex : -1; const expandIconColumnIndex = fixed !== 'right' ? props.expandIconColumnIndex : -1;
if(props.lazyLoad && props.lazyLoad.preHeight){
rst.push(
<TableRow height={props.lazyLoad.preHeight} columns={[]} className='' store={this.store} visible = {true}/>
)
}
const lazyCurrentIndex = props.lazyLoad && props.lazyLoad.currentIndex ?props.lazyLoad.currentIndex :0;
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
const record = data[i]; const record = data[i];
const key = this.getRowKey(record, i); const key = this.getRowKey(record, i);
@ -515,14 +524,12 @@ class Table extends Component {
fixedIndex = this.treeRowIndex; fixedIndex = this.treeRowIndex;
} }
if (props.fixedHeight) { if (props.height) {
height = props.fixedHeight height = props.height
} else { } else if(fixed) {
height = (fixed && fixedColumnsBodyRowsHeight[fixedIndex]) ? fixedColumnsBodyRowsHeight[fixedIndex] : null; height = fixedColumnsBodyRowsHeight[fixedIndex];
} }
let leafColumns; let leafColumns;
if (fixed === 'left') { if (fixed === 'left') {
leafColumns = this.columnManager.leftLeafColumns(); leafColumns = this.columnManager.leftLeafColumns();
@ -538,6 +545,7 @@ class Table extends Component {
className = className + ' sumrow'; className = className + ' sumrow';
} }
rst.push( rst.push(
<TableRow <TableRow
indent={indent} indent={indent}
@ -567,6 +575,7 @@ class Table extends Component {
ref={rowRef} ref={rowRef}
store={this.store} store={this.store}
fixed={fixed} fixed={fixed}
lazyCurrentIndex={lazyCurrentIndex}
/> />
); );
this.treeRowIndex++; this.treeRowIndex++;
@ -578,12 +587,18 @@ class Table extends Component {
)); ));
} }
if (childrenColumn) { if (childrenColumn) {
this.treeType = true;//证明是tree表形式 this.treeType = true;//证明是tree表形式visible = {true}
rst = rst.concat(this.getRowsByData( rst = rst.concat(this.getRowsByData(
childrenColumn, subVisible, indent + 1, columns, fixed childrenColumn, subVisible, indent + 1, columns, fixed
)); ));
} }
} }
if(props.lazyLoad && props.lazyLoad.sufHeight){
rst.push(
<TableRow height={props.lazyLoad.sufHeight} columns={[]} className='' store={this.store} visible = {true}/>
)
}
return rst; return rst;
} }
@ -924,7 +939,7 @@ class Table extends Component {
handleBodyScroll(e) { handleBodyScroll(e) {
const { scroll = {},clsPrefix } = this.props; const { scroll = {},clsPrefix,handleScroll } = this.props;
const { headTable, bodyTable, fixedColumnsBodyLeft, fixedColumnsBodyRight } = this.refs; const { headTable, bodyTable, fixedColumnsBodyLeft, fixedColumnsBodyRight } = this.refs;
// Prevent scrollTop setter trigger onScroll event // Prevent scrollTop setter trigger onScroll event
// http://stackoverflow.com/q/1386696 // http://stackoverflow.com/q/1386696
@ -952,9 +967,9 @@ class Table extends Component {
.remove(new RegExp(`^${clsPrefix}-scroll-position-.+$`)) .remove(new RegExp(`^${clsPrefix}-scroll-position-.+$`))
.add(`${clsPrefix}-scroll-position-${position}`); .add(`${clsPrefix}-scroll-position-${position}`);
} }
} }
if (scroll.y) { console.log('lastScrollTop--'+this.lastScrollTop+'--eventScrollTop--'+ e.target.scrollTop);
if (scroll.y && this.lastScrollTop != e.target.scrollTop) {
if (fixedColumnsBodyLeft && e.target !== fixedColumnsBodyLeft) { if (fixedColumnsBodyLeft && e.target !== fixedColumnsBodyLeft) {
fixedColumnsBodyLeft.scrollTop = e.target.scrollTop; fixedColumnsBodyLeft.scrollTop = e.target.scrollTop;
} }
@ -964,9 +979,20 @@ class Table extends Component {
if (bodyTable && e.target !== bodyTable) { if (bodyTable && e.target !== bodyTable) {
bodyTable.scrollTop = e.target.scrollTop; bodyTable.scrollTop = e.target.scrollTop;
} }
this.lastScrollTop = e.target.scrollTop;
console.log('handleBodyScroll---scrollTop--'+e.target.scrollTop);
if(handleScroll){
const scrollTop = e.target.scrollTop
debounce(
handleScroll(scrollTop)
,200);
} }
}
// Remember last scrollLeft for scroll direction detecting. // Remember last scrollLeft for scroll direction detecting.
this.lastScrollLeft = e.target.scrollLeft; this.lastScrollLeft = e.target.scrollLeft;
} }
handleRowHover(isHover, key) { handleRowHover(isHover, key) {
@ -995,7 +1021,10 @@ class Table extends Component {
className += ` ${clsPrefix}-bordered`; className += ` ${clsPrefix}-bordered`;
} }
className += ` ${clsPrefix}-scroll-position-${this.state.scrollPosition}`; className += ` ${clsPrefix}-scroll-position-${this.state.scrollPosition}`;
//如果传入height说明是固定高度
if(props.height){
className += ' fixed-height';
}
const isTableScroll = this.columnManager.isAnyColumnsFixed() || const isTableScroll = this.columnManager.isAnyColumnsFixed() ||
props.scroll.x || props.scroll.x ||
props.scroll.y; props.scroll.y;
@ -1005,8 +1034,7 @@ class Table extends Component {
show: loading, show: loading,
}; };
} }
const leftFixedWidth = this.columnManager.getLeftColumnsWidth();
const rightFixedWidth = this.columnManager.getRightColumnsWidth();
return ( return (
<div className={className} style={props.style} ref={el => this.contentTable = el}> <div className={className} style={props.style} ref={el => this.contentTable = el}>
{this.getTitle()} {this.getTitle()}

View File

@ -57,7 +57,7 @@ $checkbox-height:16px;
} }
tr { tr {
transition: all 0.3s ease; // transition: all 0.3s ease;
&:hover { &:hover {
background: $table-hover-color; background: $table-hover-color;
td { td {
@ -110,6 +110,10 @@ $checkbox-height:16px;
background: $table-head-background-color; background: $table-head-background-color;
} }
&.fixed-height td {
padding: 0px 8px;
}
&-fixed-header &-body { &-fixed-header &-body {
background: #fff; background: #fff;
position: relative; position: relative;
@ -273,6 +277,7 @@ $checkbox-height:16px;
color: transparent; color: transparent;
pointer-events: none; pointer-events: none;
} }
} }
// &-scroll-position-left &-fixed-left { // &-scroll-position-left &-fixed-left {
@ -706,3 +711,4 @@ $checkbox-height:16px;
.u-checkbox .u-checkbox-label:after,.u-checkbox .u-checkbox-label::before { .u-checkbox .u-checkbox-label:after,.u-checkbox .u-checkbox-label::before {
} }

View File

@ -51,7 +51,7 @@ class TableRow extends Component{
this.onRowDoubleClick = this.onRowDoubleClick.bind(this); this.onRowDoubleClick = this.onRowDoubleClick.bind(this);
this.onMouseEnter = this.onMouseEnter.bind(this); this.onMouseEnter = this.onMouseEnter.bind(this);
this.onMouseLeave = this.onMouseLeave.bind(this); this.onMouseLeave = this.onMouseLeave.bind(this);
this.expandHeight = 0;
} }
@ -64,6 +64,8 @@ class TableRow extends Component{
this.setState({ hovered: false }); this.setState({ hovered: false });
} }
}); });
this.setRowHeight()
} }
componentWillUnmount() { componentWillUnmount() {
@ -74,6 +76,13 @@ class TableRow extends Component{
} }
} }
setRowHeight() {
const { setRowHeight } = this.props
if (!setRowHeight || !this.element) return
setRowHeight(this.element.clientHeight + this.expandHeight, this.props.index)
}
onRowClick(event) { onRowClick(event) {
const { const {
record, record,
@ -119,11 +128,15 @@ class TableRow extends Component{
} }
} }
bindElement = (el)=> {
this.element = el
}
render() { render() {
const { const {
clsPrefix, columns, record, height, visible, index, clsPrefix, columns, record, height, visible, index,
expandIconColumnIndex, expandIconAsCell, expanded, expandRowByClick, expandIconColumnIndex, expandIconAsCell, expanded, expandRowByClick,
expandable, onExpand, needIndentSpaced, indent, indentSize,isHiddenExpandIcon,fixed expandable, onExpand, needIndentSpaced, indent, indentSize,isHiddenExpandIcon,fixed,lazyCurrentIndex=0
} = this.props; } = this.props;
let showSum = false; let showSum = false;
let { className } = this.props; let { className } = this.props;
@ -169,7 +182,7 @@ class TableRow extends Component{
record={record} record={record}
indentSize={indentSize} indentSize={indentSize}
indent={indent} indent={indent}
index={index} index={index+lazyCurrentIndex}
column={columns[i]} column={columns[i]}
key={columns[i].key} key={columns[i].key}
fixed= {fixed} fixed= {fixed}
@ -191,6 +204,7 @@ class TableRow extends Component{
onMouseLeave={this.onMouseLeave} onMouseLeave={this.onMouseLeave}
className={`${clsPrefix} ${className} ${clsPrefix}-level-${indent}`} className={`${clsPrefix} ${className} ${clsPrefix}-level-${indent}`}
style={style} style={style}
ref={this.bindElement}
> >
{cells} {cells}
</tr> </tr>

132
src/lib/bigData.js Normal file
View File

@ -0,0 +1,132 @@
import React, { Component } from "react";
import PropTypes from "prop-types";
const defaultHeight = 40;
export default function bigData(Table) {
return class BigData extends Component {
static defaultProps = {
data: undefined,
// height: 40, //默认行高
};
constructor(props) {
super(props);
this.state = {
currentIndex: 0,
scrollLeft: 0,
scrollTop: 0
};
const rowHeight = this.props.height?this.props.height:defaultHeight
this.rowsInView = this.props.scroll.y?Math.ceil(this.props.scroll.y/rowHeight):25 ;
this.cachedRowHeight = [];
this.lastScrollTop = 0;
}
/**
*获取数据区高度
*
*
**/
getContentHeight() {
if (!this.props.data) return 0;
return this.getSumHeight(0, this.props.data.length);
}
getSumHeight(start, end) {
const { height } = this.props;
const rowHeight = height?height:defaultHeight;
let sumHeight = 0;
for (let i = start; i < end; i++) {
sumHeight += this.cachedRowHeight[i] || rowHeight;
}
return sumHeight;
}
getIndex(scrollTop = this.state.scrollTop) {
const { data } = this.props
const {rowsInView} = this;
const max = data.length
const mcf = scrollTop > 0.5 ? Math.ceil : Math.floor
let index = mcf((scrollTop * max) - (rowsInView * scrollTop))
if (index > max - rowsInView) index = max - rowsInView
if (index < 0) index = 0
return index
}
// getLastRowHeight = (index) =>{
// const { height, data } = this.props
// const {rowsInView} = this;
// if (index + rowsInView >= data.length) return 0
// let lastRowHeight = 0
// if (index >= 1 && index < data.length / 2) {
// lastRowHeight = this.cachedRowHeight[index - 1] || height
// }
// return lastRowHeight
// }
handleScroll = (scrollTop)=> {
console.log('scrollTop----'+scrollTop)
const {data,height} = this.props;
const rowHeight = height?height:defaultHeight;
const {rowsInView} = this;
const {currentIndex} = this.state;
let index = 0;
let temp = scrollTop;
while (temp > 0) {
temp -= this.cachedRowHeight[index] || rowHeight
if(temp > 0){
index += 1
}
}
// offset last row
// index -= 1
console.log(index);
if (data.length - rowsInView < index) index = data.length - rowsInView
if (index < 0) index = 0
if(currentIndex !== index){
this.setState({ currentIndex: index ,scrollTop:scrollTop})
}
// this.lastScrollTop = scrollTop;
//scrollTop/rowHeight如果小于0.5按当前值如果大于0.5为下一个currentIndex 值
}
setRowHeight(height, index) {
const oldHeight = this.cachedRowHeight[index]
this.cachedRowHeight[index] = height
const rowHeight = this.props.height?this.props.height:defaultHeight;
let { currentIndex ,scrollTop} = this.state
if (currentIndex === index && !oldHeight) {
scrollTop += height - rowHeight;
}
this.setState({scrollTop});
}
render() {
const { data } = this.props;
const { currentIndex,scrollTop } = this.state;
const {rowsInView} = this;
const lazyLoad = {
preHeight: this.getSumHeight(0, currentIndex),
sufHeight: this.getSumHeight(currentIndex + rowsInView , data.length),
currentIndex:currentIndex
};
return (
<Table
{...this.props}
data={data.slice(currentIndex, currentIndex + rowsInView)}
lazyLoad={lazyLoad}
handleScroll={this.handleScroll}
scrollTop={scrollTop}
setRowHeight={this.setRowHeight}
// className={'lazy-table'}
/>
);
}
};
}