fineui是帆软报表和BI产品线所使用的前端框架。
 
 
 

488 lines
17 KiB

/**
* GridTable
*
* Created by GUY on 2016/1/12.
* @class BI.GridTable
* @extends BI.Widget
*/
BI.GridTable = BI.inherit(BI.Widget, {
_defaultConfig: function () {
return BI.extend(BI.GridTable.superclass._defaultConfig.apply(this, arguments), {
baseCls: "bi-grid-table",
headerRowSize: 25,
rowSize: 25,
columnSize: [],
isNeedFreeze: false,
freezeCols: [],
header: [],
items: [],
regionColumnSize: []
});
},
render: function () {
var self = this, o = this.options;
this._width = 0;
this._height = 0;
this._scrollBarSize = BI.DOM.getScrollWidth();
var rowHeightGetter = function () {
return o.rowSize;
};
var columnLeftWidthGetter = function (index) {
return o.columnSize[index];
};
var columnRightWidthGetter = function (index) {
return o.columnSize[index + self._getFreezeColLength()];
};
this.topLeftGrid = BI.createWidget({
type: "bi.grid_view",
rowHeightGetter: rowHeightGetter,
columnWidthGetter: columnLeftWidthGetter
});
this.topLeftGrid.on(BI.GridView.EVENT_SCROLL, function (scroll) {
self.bottomLeftGrid.setScrollLeft(scroll.scrollLeft);
self._populateScrollbar();
self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments);
});
this.topRightGrid = BI.createWidget({
type: "bi.grid_view",
rowHeightGetter: rowHeightGetter,
columnWidthGetter: columnRightWidthGetter
});
this.topRightGrid.on(BI.GridView.EVENT_SCROLL, function (scroll) {
self.bottomRightGrid.setScrollLeft(scroll.scrollLeft);
self._populateScrollbar();
self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments);
});
this.bottomLeftGrid = BI.createWidget({
type: "bi.grid_view",
rowHeightGetter: rowHeightGetter,
columnWidthGetter: columnLeftWidthGetter
});
this.bottomLeftGrid.on(BI.GridView.EVENT_SCROLL, function (scroll) {
self.bottomRightGrid.setScrollTop(scroll.scrollTop);
self.topLeftGrid.setScrollLeft(scroll.scrollLeft);
self._populateScrollbar();
self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments);
});
this.bottomRightGrid = BI.createWidget({
type: "bi.grid_view",
rowHeightGetter: rowHeightGetter,
columnWidthGetter: columnRightWidthGetter
});
this.bottomRightGrid.on(BI.GridView.EVENT_SCROLL, function (scroll) {
self.bottomLeftGrid.setScrollTop(scroll.scrollTop);
self.topRightGrid.setScrollLeft(scroll.scrollLeft);
self._populateScrollbar();
self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments);
});
this.topLeft = BI.createWidget({
type: "bi.vertical",
scrollable: false,
scrolly: false,
items: [this.topLeftGrid]
});
this.topRight = BI.createWidget({
type: "bi.vertical",
scrollable: false,
scrolly: false,
items: [this.topRightGrid]
});
this.bottomLeft = BI.createWidget({
type: "bi.vertical",
scrollable: false,
scrolly: false,
items: [this.bottomLeftGrid]
});
this.bottomRight = BI.createWidget({
type: "bi.vertical",
scrollable: false,
scrolly: false,
items: [this.bottomRightGrid]
});
this.contextLayout = BI.createWidget({
type: "bi.absolute",
element: this,
items: [{
el: this.topLeft,
top: 0,
left: 0
}, {
el: this.topRight,
top: 0
}, {
el: this.bottomLeft,
left: 0
}, {
el: this.bottomRight
}]
});
this.topScrollbar = BI.createWidget({
type: "bi.grid_table_scrollbar",
width: BI.GridTableScrollbar.SIZE
});
this.topScrollbar.on(BI.GridTableScrollbar.EVENT_SCROLL, function (scrollTop) {
self.bottomLeftGrid.setScrollTop(scrollTop);
self.bottomRightGrid.setScrollTop(scrollTop);
self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments);
});
this.leftScrollbar = BI.createWidget({
type: "bi.grid_table_horizontal_scrollbar",
height: BI.GridTableScrollbar.SIZE
});
this.leftScrollbar.on(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, function (scrollLeft) {
self.topLeftGrid.setScrollLeft(scrollLeft);
self.bottomLeftGrid.setScrollLeft(scrollLeft);
self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments);
});
this.rightScrollbar = BI.createWidget({
type: "bi.grid_table_horizontal_scrollbar",
height: BI.GridTableScrollbar.SIZE
});
this.rightScrollbar.on(BI.GridTableHorizontalScrollbar.EVENT_SCROLL, function (scrollLeft) {
self.topRightGrid.setScrollLeft(scrollLeft);
self.bottomRightGrid.setScrollLeft(scrollLeft);
self.fireEvent(BI.Table.EVENT_TABLE_SCROLL, arguments);
});
this.scrollBarLayout = BI.createWidget({
type: "bi.absolute",
element: this,
items: [{
el: this.topScrollbar,
right: 0,
top: 0
}, {
el: this.leftScrollbar,
left: 0
}, {
el: this.rightScrollbar
}]
});
this._width = o.width - BI.GridTableScrollbar.SIZE;
this._height = o.height - BI.GridTableScrollbar.SIZE;
this.header = this._getHeader();
this.items = this._getItems();
},
mounted: function () {
var o = this.options;
if (o.items.length > 0 || o.header.length > 0) {
this._populate();
}
},
_getFreezeColLength: function () {
var o = this.options;
return o.isNeedFreeze === true ? BI.clamp(o.freezeCols.length, 0, o.columnSize.length) : 0;
},
_getFreezeHeaderHeight: function () {
var o = this.options;
if (o.header.length * o.headerRowSize >= this._height) {
return 0;
}
return o.header.length * o.headerRowSize;
},
_getActualItems: function () {
var o = this.options;
if (o.header.length * o.headerRowSize >= this._height) {
return o.header.concat(o.items);
}
return o.items;
},
_populateScrollbar: function () {
var o = this.options;
var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0,
summaryColumnSizeArray = [];
BI.each(o.columnSize, function (i, size) {
if (o.isNeedFreeze === true && o.freezeCols.contains(i)) {
totalLeftColumnSize += size;
} else {
totalRightColumnSize += size;
}
totalColumnSize += size;
if (i === 0) {
summaryColumnSizeArray[i] = size;
} else {
summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size;
}
});
this.topScrollbar.setContentSize(this._getActualItems().length * o.rowSize);
this.topScrollbar.setSize(this._height - this._getFreezeHeaderHeight());
this.topScrollbar.setPosition(Math.min(this.bottomLeftGrid.getScrollTop(), this.bottomRightGrid.getScrollTop()));
this.topScrollbar.populate();
this.leftScrollbar.setContentSize(totalLeftColumnSize);
this.leftScrollbar.setSize(regionSize);
this.leftScrollbar.setPosition(this.bottomLeftGrid.getScrollLeft());
this.leftScrollbar.populate();
this.rightScrollbar.setContentSize(totalRightColumnSize);
this.rightScrollbar.setSize(this._width - regionSize);
this.rightScrollbar.setPosition(this.bottomRightGrid.getScrollLeft());
this.rightScrollbar.populate();
var items = this.scrollBarLayout.attr("items");
items[0].top = this._getFreezeHeaderHeight();
items[1].top = this._height;
items[2].top = this._height;
items[2].left = regionSize;
this.scrollBarLayout.attr("items", items);
this.scrollBarLayout.resize();
},
_getHeader: function () {
var o = this.options;
var freezeColLength = this._getFreezeColLength();
var leftHeader = [], rightHeader = [];
BI.each(o.header, function (i, cols) {
leftHeader[i] = [];
rightHeader[i] = [];
BI.each(cols, function (j, col) {
var cell = {
type: "bi.grid_table_cell",
cell: col
};
if (j < freezeColLength) {
leftHeader[i].push(cell);
} else {
rightHeader[i].push(cell);
}
});
});
return [leftHeader, rightHeader];
},
_getItems: function () {
var o = this.options;
var freezeColLength = this._getFreezeColLength();
var leftItems = [], rightItems = [];
BI.each(this._getActualItems(), function (i, cols) {
leftItems[i] = [];
rightItems[i] = [];
BI.each(cols, function (j, col) {
var cell = {
type: "bi.grid_table_cell",
cell: col
};
if (j < freezeColLength) {
leftItems[i].push(cell);
} else {
rightItems[i].push(cell);
}
});
});
return [leftItems, rightItems];
},
_populateTable: function () {
var self = this, o = this.options;
var regionSize = this.getRegionSize(), totalLeftColumnSize = 0, totalRightColumnSize = 0, totalColumnSize = 0,
summaryColumnSizeArray = [];
var freezeColLength = this._getFreezeColLength();
BI.each(o.columnSize, function (i, size) {
if (o.isNeedFreeze === true && o.freezeCols.contains(i)) {
totalLeftColumnSize += size;
} else {
totalRightColumnSize += size;
}
totalColumnSize += size;
if (i === 0) {
summaryColumnSizeArray[i] = size;
} else {
summaryColumnSizeArray[i] = summaryColumnSizeArray[i - 1] + size;
}
});
var otlw = regionSize;
var otlh = this._getFreezeHeaderHeight();
var otrw = this._width - regionSize;
var otrh = this._getFreezeHeaderHeight();
var oblw = regionSize;
var oblh = this._height - otlh;
var obrw = this._width - regionSize;
var obrh = this._height - otrh;
var tlw = otlw + this._scrollBarSize;
var tlh = otlh + this._scrollBarSize;
var trw = otrw + this._scrollBarSize;
var trh = otrh + this._scrollBarSize;
var blw = oblw + this._scrollBarSize;
var blh = oblh + this._scrollBarSize;
var brw = obrw + this._scrollBarSize;
var brh = obrh + this._scrollBarSize;
var digest = function (el) {
el.element.css({
overflow: "scroll",
overflowX: "scroll",
overflowY: "scroll"
});
};
this.topLeft.setWidth(otlw);
this.topLeft.setHeight(otlh);
this.topRight.setWidth(otrw);
this.topRight.setHeight(otrh);
this.bottomLeft.setWidth(oblw);
this.bottomLeft.setHeight(oblh);
this.bottomRight.setWidth(obrw);
this.bottomRight.setHeight(obrh);
this.topLeftGrid.setWidth(tlw);
this.topLeftGrid.setHeight(tlh);
this.topRightGrid.setWidth(trw);
this.topRightGrid.setHeight(trh);
this.bottomLeftGrid.setWidth(blw);
this.bottomLeftGrid.setHeight(blh);
this.bottomRightGrid.setWidth(brw);
this.bottomRightGrid.setHeight(brh);
digest(this.topLeftGrid);
digest(this.topRightGrid);
digest(this.bottomLeftGrid);
digest(this.bottomRightGrid);
this.topLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0);
this.topLeftGrid.setEstimatedRowSize(o.headerRowSize);
this.topRightGrid.setEstimatedColumnSize((o.columnSize.length - freezeColLength) > 0 ? (totalRightColumnSize / (o.columnSize.length - freezeColLength)) : 0);
this.topRightGrid.setEstimatedRowSize(o.headerRowSize);
this.bottomLeftGrid.setEstimatedColumnSize(freezeColLength > 0 ? totalLeftColumnSize / freezeColLength : 0);
this.bottomLeftGrid.setEstimatedRowSize(o.rowSize);
this.bottomRightGrid.setEstimatedColumnSize((o.columnSize.length - freezeColLength) > 0 ? (totalRightColumnSize / (o.columnSize.length - freezeColLength)) : 0);
this.bottomRightGrid.setEstimatedRowSize(o.rowSize);
this.topLeftGrid.setColumnCount(freezeColLength);
this.topRightGrid.setColumnCount(o.columnSize.length - freezeColLength);
this.bottomLeftGrid.setColumnCount(freezeColLength);
this.bottomRightGrid.setColumnCount(o.columnSize.length - freezeColLength);
var items = this.contextLayout.attr("items");
items[1].left = regionSize;
items[2].top = this._getFreezeHeaderHeight();
items[3].left = regionSize;
items[3].top = this._getFreezeHeaderHeight();
this.contextLayout.attr("items", items);
this.contextLayout.resize();
this.topLeftGrid._populate(this.header[0]);
this.topRightGrid._populate(this.header[1]);
this.bottomLeftGrid._populate(this.items[0]);
this.bottomRightGrid._populate(this.items[1]);
},
_populate: function () {
if (this._width <= 0 || this._height <= 0) {
return;
}
this._populateTable();
this._populateScrollbar();
},
getRegionSize: function () {
var o = this.options;
var regionSize = o.regionColumnSize[0] || 0;
if (o.isNeedFreeze === false || o.freezeCols.length === 0) {
return 0;
}
if (!regionSize) {
BI.each(o.freezeCols, function (i, col) {
regionSize += o.columnSize[col];
});
}
return regionSize;
},
setVerticalScroll: function (scrollTop) {
this.bottomLeftGrid.setScrollTop(scrollTop);
this.bottomRightGrid.setScrollTop(scrollTop);
this._populateScrollbar();
},
setLeftHorizontalScroll: function (scrollLeft) {
this.topLeftGrid.setScrollLeft(scrollLeft);
this.bottomLeftGrid.setScrollLeft(scrollLeft);
this._populateScrollbar();
},
setRightHorizontalScroll: function (scrollLeft) {
this.topRightGrid.setScrollLeft(scrollLeft);
this.bottomRightGrid.setScrollLeft(scrollLeft);
this._populateScrollbar();
},
getVerticalScroll: function () {
return this.bottomRightGrid.getScrollTop();
},
getLeftHorizontalScroll: function () {
return this.bottomLeftGrid.getScrollLeft();
},
getRightHorizontalScroll: function () {
return this.bottomRightGrid.getScrollLeft();
},
setWidth: function (width) {
BI.GridTable.superclass.setWidth.apply(this, arguments);
this._width = this.options.width - BI.GridTableScrollbar.SIZE;
},
setHeight: function (height) {
BI.GridTable.superclass.setHeight.apply(this, arguments);
this._height = this.options.height - BI.GridTableScrollbar.SIZE;
},
setColumnSize: function (columnSize) {
this.options.columnSize = columnSize;
this._isNeedDigest = true;
},
setRegionColumnSize: function (regionColumnSize) {
this.options.regionColumnSize = regionColumnSize;
this._isNeedDigest = true;
},
getColumnSize: function () {
return this.options.columnSize;
},
getRegionColumnSize: function () {
return this.options.regionColumnSize;
},
populate: function (items, header) {
var headerChanged = this.options.header !== header;
var itemsChanged = this.options.items !== items;
if(header && headerChanged) {
this.options.header = header;
}
if(items && itemsChanged) {
this.options.items = items;
}
if (items && itemsChanged) {
this.items = this._getItems();
this._restore();
}
if (header && headerChanged) {
this.header = this._getHeader();
this._restore();
}
this._populate();
},
_restore: function () {
this.topLeftGrid.restore();
this.topRightGrid.restore();
this.bottomLeftGrid.restore();
this.bottomRightGrid.restore();
},
restore: function () {
this._restore();
}
});
BI.shortcut("bi.grid_table", BI.GridTable);