mthb-canvas-table
Version:
1,308 lines • 78.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const CanvasTableColum_1 = require("./CanvasTableColum");
const CanvasTableMode_1 = require("./CanvasTableMode");
const CustomCanvasIndex_1 = require("./CustomCanvasIndex");
const defaultConfig = {
backgroundColor: "white",
font: "arial",
fontColor: "black",
fontSize: 14,
fontStyle: "",
groupItemArrowColor: "black",
groupItemBackgroundColor: "#F9D3CB",
groupItemFontColor: "back",
headerBackgroundColor: "#add8e6",
headerDrawSortArrow: true,
headerDrawSortArrowColor: "purple",
headerFont: "arial",
headerFontColor: "black",
headerFontSize: 14,
headerFontStyle: "bold",
howerBackgroundColor: "#DCDCDC",
lineColor: "black",
rowGroupItemArrowColor: "black",
rowGroupItemBackgroundColor: "#F9D3CB",
rowGroupItemFontColor: "black",
selectLineColor: "green",
sepraBackgroundColor: "#ECECEC",
};
class CustomCanvasTable {
constructor(config) {
this.r = 1;
this.data = [];
this.allowEdit = false;
this.headerHeight = 18;
this.cellHeight = 20;
this.dataIndex = undefined;
this.config = defaultConfig;
this.column = [];
this.eventDblClick = [];
this.eventClick = [];
this.eventClickHeader = [];
this.eventReCalcForScrollView = [];
this.eventEdit = [];
this.needToCalc = true;
this.needToCalcFont = true;
this.isFocus = false;
this.minFontWidth = 1;
this.maxFontWidth = 1;
this.orgColum = [];
this.selectRowValue = null;
this.lastCursor = "";
this.canvasHeight = 0;
this.canvasWidth = 0;
this.editData = {};
this.tableMode = CanvasTableMode_1.CanvasTableMode.ColMode;
this.updateConfig(config);
}
getScrollView() {
return this.scrollView;
}
/**
* To customize style of CanvasTable
* @param config config
*/
updateConfig(config) {
this.config = Object.assign(Object.assign({}, defaultConfig), config);
}
/**
* Is CanvasTable goging to redraw in next frame
*/
isPlanToRedraw() {
if (!this.requestAnimationFrame) {
return false;
}
return (this.drawconf !== undefined && this.drawconf.fulldraw);
}
/**
* Let CanvasTable redraw
* @param config
*/
askForReDraw(config) {
if (config === undefined || (this.drawconf !== undefined && this.drawconf.fulldraw)) {
this.drawconf = { fulldraw: true };
}
else {
if (this.drawconf === undefined) {
this.drawconf = Object.assign(Object.assign({}, config), { fulldraw: false });
}
else {
// this.drawconf = ...this.drawconf, ...config;
}
}
if (this.requestAnimationFrame) {
return;
}
this.requestAnimationFrame = requestAnimationFrame(() => {
this.drawCanvas();
});
}
/**
* Recalc index and then redraw
* You need to call this if size of the data was change or columns witch was change is in active groupby or sort
*/
askForReIndex() {
this.calcIndex();
this.askForReDraw();
}
setAllowEdit(allowEdit) {
this.allowEdit = allowEdit;
}
setRowColStyle(style) {
if (style === null) {
style = undefined;
}
if (this.customRowColStyle !== style) {
this.customRowColStyle = style;
this.askForReDraw();
}
}
setFilter(filter) {
if (filter === null) {
filter = undefined;
}
if (this.customFilter !== filter) {
this.customFilter = filter;
this.askForReIndex();
}
}
setCustomSort(customSort) {
if (customSort === null) {
customSort = undefined;
}
this.customSort = customSort;
this.sortCol = undefined;
this.askForReIndex();
}
setSort(sortCol) {
this.sortCol = sortCol;
this.customSort = undefined;
this.askForReIndex();
}
/**
* Set group by data
* @param col
*/
setGroupBy(col) {
if (!col) {
col = [];
}
const list = [];
let i;
for (i = 0; i < col.length; i++) {
const item = col[i];
if (typeof item === "string") {
list.push({ field: item });
}
else {
list.push(item);
}
}
this.groupByCol = list;
this.askForReIndex();
}
setRowTableGroup(row) {
if (typeof row === "string") {
this.rowTableGroup = { field: row };
}
else {
this.rowTableGroup = row;
}
this.askForReIndex();
}
setTableMode(tableMode) {
if (tableMode !== this.tableMode) {
this.tableMode = tableMode;
this.askForReIndex();
}
}
getTableMode() {
return this.tableMode;
}
/**
* Set new Data and then reindex and redraw
* @param data new Data
*/
setData(data) {
if (data !== undefined) {
this.data = data;
}
this.askForReIndex();
}
/**
* Change the visibility of the column
* @param col index of colum or the column it self
* @param visible show or hide the colum
*/
setColumnVisible(col, visible) {
if (typeof col === "number") {
if (col < 0 || col >= this.orgColum.length) {
throw new Error("out of range");
}
if (visible && this.orgColum[col].visible === true) {
return;
}
if (!visible && !this.orgColum[col].visible) {
return;
}
this.orgColum[col].visible = visible;
this.updateColumns(this.orgColum);
return;
}
const v = col.visible === undefined ? true : false;
if (v !== visible) {
col.visible = v;
this.updateColumns(this.orgColum);
return;
}
}
updateColumns(col) {
this.orgColum = col;
this.column = [];
let i;
for (i = 0; i < col.length; i++) {
if (col[i].visible === false) {
continue;
}
const index = this.column.length;
this.column[index] = Object.assign({
align: CanvasTableColum_1.Align.left,
allowEdit: true,
index,
leftPos: 0,
orginalCol: col[i],
rightPos: 0,
width: 50,
}, col[i]);
if (this.column[index].field === "__idxnum__" || this.column[index].field === "__rownum__") {
this.column[index].allowEdit = false;
}
}
this.needToCalc = true;
this.resize();
this.calcColum();
}
/**
* Expend All data in tree mode
*/
expendAll() {
const dataIndex = this.dataIndex;
if (dataIndex === undefined) {
return;
}
if (dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode) {
const index = dataIndex.index;
if (index.type === CustomCanvasIndex_1.CanvasTableIndexType.GroupItems) {
this.changeChildExpend(index, true);
this.reCalcForScrollView();
this.askForReDraw();
return;
}
}
else {
this.changeChildExpend(dataIndex.index, true);
this.reCalcForScrollView();
this.askForReDraw();
}
}
/**
* Collapse All data in tree mode
*/
collapseAll() {
const dataIndex = this.dataIndex;
if (dataIndex === undefined) {
return;
}
if (dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode) {
const index = dataIndex.index;
if (index.type === CustomCanvasIndex_1.CanvasTableIndexType.GroupItems) {
this.changeChildExpend(index, false);
this.reCalcForScrollView();
this.askForReDraw();
return;
}
}
else {
this.changeChildExpend(dataIndex.index, false);
this.reCalcForScrollView();
this.askForReDraw();
}
}
addEvent(eventName, event) {
this.getEvent(eventName).push(event);
}
removeEvent(eventName, event) {
const e = this.getEvent(eventName);
const index = e.indexOf(event);
if (index !== -1) {
e.splice(index, 1);
}
}
setUpdateData(row, field, data) {
const oldData = this.getUpdateDataOrData(row, field);
if (!this.editData[row]) {
this.editData[row] = {};
}
this.editData[row][field] = data;
this.fireEdit(row, field, data, oldData);
}
getUpdateData(row, field) {
const rowData = this.editData[row];
if (!rowData) {
return undefined;
}
if (rowData.hasOwnProperty(field)) {
return { data: rowData[field] };
}
return undefined;
}
getUpdateDataOrData(row, field) {
const rowData = this.editData[row];
if (rowData && rowData.hasOwnProperty(field)) {
return rowData[field];
}
return this.data[row][field];
}
getEditData() {
return this.editData;
}
clearEditData() {
this.editData = {};
this.askForReIndex();
}
logError(value, value2, value3) {
// tslint:disable-next-line: no-console
console.log(value, value2, value3);
}
setOverRow(value) {
if (value !== this.overRowValue) {
const temp = this.overRowValue;
this.overRowValue = value;
if (value !== undefined && temp !== undefined) {
this.askForReDraw({ drawOnly: [temp, value] });
return;
}
if (value !== undefined) {
this.askForReDraw({ drawOnly: [value] });
return;
}
if (temp !== undefined) {
this.askForReDraw({ drawOnly: [temp] });
return;
}
}
}
setR(r) {
if (this.r === r) {
return;
}
this.r = r;
this.needToCalc = true;
this.needToCalcFont = true;
}
getColumnByCanvasTableColumnConf(column) {
let i;
for (i = 0; i < this.column.length; i++) {
if (this.column[i].orginalCol === column) {
return this.column[i];
}
}
return undefined;
}
setIsFocus(isFocus) {
if (this.isFocus !== isFocus) {
this.isFocus = isFocus;
if (this.allowEdit) {
this.askForReDraw();
}
}
}
fireEdit(row, col, newData, oldData) {
let i;
for (i = 0; i < this.eventEdit.length; i++) {
try {
this.eventEdit[i](this, row, col, newData, oldData);
}
catch (_a) {
this.logError("eventEdit");
}
}
}
fireDblClick(row, col) {
let i;
for (i = 0; i < this.eventDblClick.length; i++) {
try {
this.eventDblClick[i](this, row, col === null ? null : col.orginalCol);
}
catch (_a) {
this.logError("fireDblClick");
}
}
}
fireClick(row, col) {
let i;
for (i = 0; i < this.eventClick.length; i++) {
try {
this.eventClick[i](this, row, col === null ? null : col.orginalCol);
}
catch (_a) {
this.logError("fireClick");
}
}
}
fireClickHeader(col) {
let i;
for (i = 0; i < this.eventClick.length; i++) {
try {
this.eventClickHeader[i](this, col === null ? null : col.orginalCol);
}
catch (_a) {
this.logError("fireClickHeader");
}
}
}
fireReCalcForScrollView(width, height) {
const scrollView = this.scrollView;
if (scrollView) {
let i;
for (i = 0; i < this.eventReCalcForScrollView.length; i++) {
try {
this.eventReCalcForScrollView[i](this, width, height, scrollView);
}
catch (_a) {
this.logError("fireReCalcForScrollView");
}
}
}
}
clickOnHeader(col) {
if (col) {
if (this.sortCol && this.sortCol.length === 1 &&
this.sortCol[0].col === col.orginalCol && this.sortCol[0].sort === CanvasTableColum_1.Sort.ascending) {
this.setSort([{ col: col.orginalCol, sort: CanvasTableColum_1.Sort.descending }]);
}
else {
this.setSort([{ col: col.orginalCol, sort: CanvasTableColum_1.Sort.ascending }]);
}
}
}
wheel(deltaMode, deltaX, deltaY) {
if (this.scrollView) {
this.scrollView.onScroll(deltaMode, deltaX, deltaY);
}
}
dblClick(x, y) {
const col = this.findColByPos(x);
if (y <= this.headerHeight) {
return;
}
const row = this.findRowByPos(y);
if (this.allowEdit && row && typeof row.select === "number" && col !== null) {
if (!col.allowEdit) {
return;
}
this.updateForEdit(col, row.select);
}
this.fireDblClick(row === null ? null : row.select, col);
}
mouseDown(x, y) {
if (this.dataIndex === undefined) {
return;
}
if (this.scrollView && this.scrollView.onMouseDown(x, y)) {
return;
}
if (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode) {
const dataIndex = this.dataIndex.index;
const col = this.findColByPos(x);
if (y <= this.headerHeight) {
const colSplit = this.findColSplit(x);
if (colSplit !== null) {
this.columnResize = { x, col: this.column[colSplit] };
this.askForExtentedMouseMoveAndMaouseUp();
this.fireClickHeader(col);
return;
}
this.clickOnHeader(col);
this.fireClickHeader(col);
return;
}
const row = this.findRowByPos(y);
if (row && typeof row.select === "number" && col !== null) {
if (this.selectColValue !== col || this.selectRowValue !== row) {
this.selectColValue = col;
this.selectRowValue = row;
this.askForReDraw();
}
}
else {
if (dataIndex.type === CustomCanvasIndex_1.CanvasTableIndexType.GroupItems) {
if (row !== null && typeof row.select === "object") {
row.select.isExpended = !row.select.isExpended;
this.askForReDraw();
this.reCalcForScrollView();
}
}
}
this.fireClick(row === null ? null : row.select, col);
}
else {
const result = this.findColAndRowInRowMode(x, y);
if (result === null) {
return;
}
const { row, col } = result;
if (col === null) {
row.isExpended = !row.isExpended;
this.askForReDraw();
this.reCalcForScrollView();
}
}
}
mouseMove(x, y) {
if (!this.scrollView) {
return;
}
if (this.resizeColIfNeed(x)) {
return;
}
if (this.scrollView.onMouseMove(x, y)) {
this.updateCursor();
this.setOverRow(undefined);
return;
}
if (y < this.headerHeight) {
this.setOverRow(undefined);
if (this.findColSplit(x) === null) {
this.updateCursor();
}
else {
this.updateCursor("col-resize");
}
return;
}
else {
this.updateCursor();
const result = this.findRowByPos(y);
if (result && typeof result.select === "number") {
this.setOverRow(result.select);
return;
}
this.setOverRow(undefined);
}
}
mouseUp(x, y) {
if (this.columnResize) {
this.columnResize = undefined;
this.askForNormalMouseMoveAndMaouseUp();
}
if (this.scrollView && this.scrollView.onMouseUp(x, y)) {
return;
}
}
mouseMoveExtended(x, y) {
if (this.resizeColIfNeed(x)) {
return;
}
if (this.scrollView && this.scrollView.onExtendedMouseMove(x, y)) {
return;
}
}
mouseUpExtended(x, y) {
if (this.columnResize) {
this.columnResize = undefined;
this.askForNormalMouseMoveAndMaouseUp();
}
if (this.scrollView && this.scrollView.onExtendedMouseUp(x, y)) {
return;
}
}
mouseLeave() {
this.setOverRow(undefined);
if (this.columnResize === undefined) {
this.updateCursor();
}
if (this.scrollView) {
this.scrollView.onMouseLeave();
}
}
keydown(keycode) {
if (this.scrollView !== undefined &&
this.selectColValue !== undefined &&
this.selectRowValue !== null &&
this.selectRowValue.mode === CanvasTableMode_1.CanvasTableMode.ColMode &&
typeof this.selectRowValue.select === "number") {
const index = this.selectRowValue.path[this.selectRowValue.path.length - 1];
if (index.type === CustomCanvasIndex_1.CanvasTableIndexType.Index) {
let y;
switch (keycode) {
case 40: // Down
if (this.selectRowValue.index === index.list.length - 1) {
return;
}
this.selectRowValue.index++;
this.selectRowValue.select = index.list[this.selectRowValue.index];
y = this.findTopPosByRow(this.selectRowValue);
if (y !== undefined) {
y = y - (this.canvasHeight -
((this.headerHeight +
(this.scrollView.getHasScrollBarX() ? this.scrollView.getScrollbarSize() : 0))
* this.r));
if (this.scrollView.getPosY() < y) {
this.scrollView.setPosY(y);
}
}
this.askForReDraw();
break;
case 38: // Up
if (this.selectRowValue.index === 0) {
return;
}
this.selectRowValue.index--;
this.selectRowValue.select = index.list[this.selectRowValue.index];
y = this.findTopPosByRow(this.selectRowValue);
if (y !== undefined) {
y = y - this.headerHeight * this.r;
if (this.scrollView.getPosY() > y) {
this.scrollView.setPosY(y);
}
}
this.askForReDraw();
break;
case 37: // Left
if (this.selectColValue.index === 0) {
return;
}
this.selectColValue = this.column[this.selectColValue.index - 1];
if (this.selectColValue.leftPos < this.scrollView.getPosX()) {
this.scrollView.setPosX(this.selectColValue.leftPos);
}
this.askForReDraw();
break;
case 39: // Right
if (this.selectColValue.index === this.column.length - 1) {
return;
}
this.selectColValue = this.column[this.selectColValue.index + 1];
if (this.selectColValue.rightPos > this.scrollView.getPosX() + this.canvasWidth) {
this.scrollView.setPosX(this.selectColValue.rightPos - this.canvasWidth);
}
this.askForReDraw();
break;
case 13: // Enter
if (this.allowEdit && typeof this.selectRowValue.select === "number") {
if (!this.selectColValue.allowEdit) {
return;
}
this.updateForEdit(this.selectColValue, this.selectRowValue.select);
}
default:
// console.log(keycode);
break;
}
}
}
else {
if (this.scrollView && this.scrollView.OnKeydown(keycode)) {
this.setOverRow(undefined);
}
}
}
TouchStart(e, offsetLeft, offsetTop) {
if (this.scrollView && this.scrollView.OnTouchStart(e, offsetLeft, offsetTop)) {
return;
}
if (e.changedTouches.length === 1) {
const y = e.changedTouches[0].pageY - offsetTop;
const x = e.changedTouches[0].pageX - offsetLeft;
this.touchClick = { timeout: setTimeout(() => {
if (this.dataIndex === undefined) {
return;
}
if (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode) {
const row = this.findRowByPos(y);
const col = this.findColByPos(x);
if (y > this.headerHeight) {
if (row !== null && typeof row.select === "object") {
row.select.isExpended = !row.select.isExpended;
this.askForReDraw();
this.reCalcForScrollView();
}
this.fireClick(row === null ? null : row.select, col);
}
else {
const colSplit = this.findColSplit(x);
if (colSplit !== null) {
this.columnResize = { x, col: this.column[colSplit] };
return;
}
this.clickOnHeader(col);
this.fireClickHeader(col);
}
}
else {
const result = this.findColAndRowInRowMode(x, y);
if (result === null) {
return;
}
const { col, row } = result;
if (col === null) {
row.isExpended = !row.isExpended;
this.askForReDraw();
this.reCalcForScrollView();
}
}
}, 250), x, y };
}
else {
this.clearTouchClick();
}
}
TouchMove(e, offsetLeft, offsetTop) {
const x = e.changedTouches[0].pageX - offsetLeft;
if (this.resizeColIfNeed(x)) {
return;
}
if (this.scrollView) {
this.scrollView.OnTouchMove(e, offsetLeft, offsetTop);
}
if (this.touchClick) {
if (e.changedTouches.length !== 1) {
this.clearTouchClick();
return;
}
const y = e.changedTouches[0].pageY - offsetTop;
if (Math.abs(x - this.touchClick.x) > 4 || Math.abs(y - this.touchClick.y) > 4) {
this.clearTouchClick();
}
}
}
TouchEnd(e, offsetLeft, offsetTop) {
this.columnResize = undefined;
if (this.scrollView) {
this.scrollView.OnTouchEnd(e);
}
}
calcRect(col, row) {
if (!this.scrollView) {
return;
}
const topPos = this.findTopPosByRow(row);
if (topPos === undefined) {
return;
}
const y = (topPos - this.scrollView.getPosY()) / this.r;
const x = -(this.scrollView.getPosX() / this.r) + (col.leftPos / this.r);
const top = y;
const left = x;
let clipTop;
const clipRight = undefined;
const clipBottom = undefined;
let clipLeft;
if (y < this.headerHeight) {
// rect(<top>, <right>, <bottom>, <left>)
if (x < 0) {
clipTop = -y + this.headerHeight;
clipLeft = -x;
}
else {
clipTop = -y + this.headerHeight;
}
}
else if (x < 0) {
clipLeft = -x;
}
return {
cellHeight: this.cellHeight,
clipBottom,
clipLeft,
clipRight,
clipTop,
left,
top,
width: col.width,
x,
y,
};
}
findColSplit(x) {
if (this.scrollView === undefined) {
return null;
}
const posXNeg = -this.scrollView.getPosX();
for (let i = 0; i < this.column.length; i++) {
const d = ((posXNeg + this.column[i].rightPos) / this.r) - x;
if (-3 <= d && d <= 3) {
return i;
}
}
return null;
}
findColAndRowInRowMode(x, y) {
if (this.dataIndex === undefined || this.scrollView === undefined) {
return null;
}
if (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode) {
return null;
}
let pos = -this.scrollView.getPosY() / this.r;
const cellHeight = this.cellHeight;
const find = (index) => {
let i;
if (index.type === CustomCanvasIndex_1.CanvasTableIndexType.GroupItems) {
for (i = 0; i < index.list.length; i++) {
const item = index.list[i];
if (pos < y && y < pos + cellHeight) {
return { row: item, col: null };
}
pos += cellHeight;
if (item.isExpended) {
const result = find(item.child);
if (result != null) {
return result;
}
}
}
}
else {
for (i = 0; i < index.list.length; i++) {
const item = index.list[i];
if (pos < y && y < pos + cellHeight) {
return { row: item, col: null };
}
pos += cellHeight;
if (item.isExpended) {
let col;
for (col = 0; col < this.column.length; col++) {
if (pos < y && y < pos + cellHeight) {
return { row: item, col: this.column[col] };
}
pos += cellHeight;
}
}
}
}
return null;
};
return find(this.dataIndex.index);
}
findColByPos(x) {
if (this.scrollView === undefined) {
return null;
}
const pos = this.scrollView.getPosX() / this.r + x;
let w = 0;
let i;
for (i = 0; i < this.column.length; i++) {
w += this.column[i].width;
if (w >= pos) {
return this.column[i];
}
}
return null;
}
findRowByPos(y) {
if (this.dataIndex === undefined || this.scrollView === undefined) {
return null;
}
if (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.RowMode) {
return null;
}
const mode = this.dataIndex.mode;
let pos = -this.scrollView.getPosY() / this.r + this.headerHeight;
const cellHeight = this.cellHeight;
const find = (items) => {
let i;
switch (items.type) {
case CustomCanvasIndex_1.CanvasTableIndexType.Index:
const h = items.list.length * cellHeight;
if (y > pos + h) {
pos += h;
}
else {
i = Math.trunc((-pos + y) / cellHeight);
pos += i * cellHeight;
if (i < items.list.length) {
return { mode, path: [items], select: items.list[i], index: i };
}
return null;
}
break;
case CustomCanvasIndex_1.CanvasTableIndexType.GroupItems:
for (i = 0; i < items.list.length; i++) {
if (pos < y && y < pos + cellHeight) {
return { mode, path: [items], select: items.list[i], index: i };
}
pos += cellHeight;
if (!items.list[i].isExpended) {
continue;
}
const f = find(items.list[i].child);
if (f !== null) {
f.path.unshift(items);
return f;
}
}
break;
}
return null;
};
return find(this.dataIndex.index);
}
findTopPosByRow(rowValue) {
if (this.dataIndex === undefined || this.scrollView === undefined || rowValue === null) {
return undefined;
}
if (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.RowMode) {
return undefined;
}
let row;
let rowGroup;
if (typeof rowValue === "number") {
row = rowValue;
}
else {
if (typeof rowValue.select === "number") {
row = rowValue.select;
}
else {
rowGroup = rowValue.select;
}
}
let pos = this.headerHeight * this.r;
const cellHeight = this.cellHeight * this.r;
const find = (items) => {
let i;
switch (items.type) {
case CustomCanvasIndex_1.CanvasTableIndexType.Index:
if (row === undefined) {
pos += cellHeight * items.list.length;
}
else {
for (i = 0; i < items.list.length; i++) {
if (items.list[i] === row) {
return pos;
}
pos += cellHeight;
}
}
break;
case CustomCanvasIndex_1.CanvasTableIndexType.GroupItems:
for (i = 0; i < items.list.length; i++) {
if (items.list[i] === rowGroup) {
return pos;
}
pos += cellHeight;
if (!items.list[i].isExpended) {
continue;
}
const f = find(items.list[i].child);
if (f !== undefined) {
return f;
}
}
break;
}
return undefined;
};
return find(this.dataIndex.index);
}
reCalcIndexIfNeed(field) {
let i;
if (this.customFilter || this.customSort) {
this.calcIndex();
return;
}
if (this.groupByCol) {
for (i = 0; i < this.groupByCol.length; i++) {
if (this.groupByCol[i].field === field) {
this.calcIndex();
return;
}
}
}
if (this.sortCol) {
for (i = 0; i < this.sortCol.length; i++) {
if (this.sortCol[i].col.field === field) {
this.calcIndex();
return;
}
}
}
}
calcIndex() {
if (this.data === undefined) {
return;
}
const index = [];
let i;
if (this.customFilter) {
for (i = 0; i < this.data.length; i++) {
if (this.customFilter(this.data, this.data[i], this.orgColum, i, this.editData[i] || {})) {
index[index.length] = i;
}
}
}
else {
for (i = 0; i < this.data.length; i++) {
index[index.length] = i;
}
}
if (this.customSort) {
const customSort = this.customSort;
index.sort((a, b) => {
return customSort(this.data, this.data[a], this.data[b], a, b);
});
}
else {
const sortCol = this.sortCol;
if (sortCol && sortCol.length) {
index.sort((a, b) => {
let sortColIndex;
for (sortColIndex = 0; sortColIndex < sortCol.length; sortColIndex++) {
let d;
const col = sortCol[sortColIndex];
switch (col.col.field) {
case "__rownum__":
d = a - b;
if (d !== 0) {
return d * col.sort;
}
break;
default:
const da = this.getUpdateDataOrData(a, col.col.field);
const db = this.getUpdateDataOrData(b, col.col.field);
if (da === undefined || da === null) {
if (db === undefined || db === null) {
continue;
}
return col.sort;
}
if (db === undefined || db === null) {
return -1 * col.sort;
}
if (typeof da === "string" && typeof db === "string") {
if (da === "") {
if (db === "") {
continue;
}
return col.sort;
}
if (db === "") {
return -1 * col.sort;
}
d = da.localeCompare(db);
if (d !== 0) {
return d * col.sort;
}
continue;
}
if (da > db) {
return col.sort;
}
if (da < db) {
return -1 * col.sort;
}
}
}
return 0;
});
}
}
if (this.rowTableGroup && this.tableMode === CanvasTableMode_1.CanvasTableMode.RowMode) {
if (this.groupByCol && this.groupByCol.length > 0) {
const groupItems = { type: CustomCanvasIndex_1.CanvasTableIndexType.GroupItems, list: [] };
this.groupRow(groupItems, index, 0, this.groupByCol, this.rowTableGroup, (this.dataIndex !== undefined && this.dataIndex.index.type === CustomCanvasIndex_1.CanvasTableIndexType.GroupItems) ?
this.dataIndex.index : undefined);
this.dataIndex = {
index: groupItems,
mode: CanvasTableMode_1.CanvasTableMode.RowMode,
};
}
else {
const groupItems = { type: CustomCanvasIndex_1.CanvasTableIndexType.GroupRows, list: [] };
this.groupRowItem(groupItems, index, this.rowTableGroup, (this.dataIndex !== undefined && this.dataIndex.index.type === CustomCanvasIndex_1.CanvasTableIndexType.GroupRows) ?
this.dataIndex.index : undefined);
this.dataIndex = {
index: groupItems,
mode: CanvasTableMode_1.CanvasTableMode.RowMode,
};
}
}
else {
if (this.groupByCol && this.groupByCol.length > 0) {
const groupByCol = this.groupByCol;
const groupItems = { type: CustomCanvasIndex_1.CanvasTableIndexType.GroupItems, list: [] };
let oldIndex;
if (this.dataIndex &&
this.dataIndex.index.type === CustomCanvasIndex_1.CanvasTableIndexType.GroupItems) {
oldIndex = this.dataIndex.index;
}
this.group(groupItems, index, 0, groupByCol, oldIndex);
this.dataIndex = { mode: CanvasTableMode_1.CanvasTableMode.ColMode, index: groupItems };
}
else {
this.dataIndex = {
index: { type: CustomCanvasIndex_1.CanvasTableIndexType.Index, list: index },
mode: CanvasTableMode_1.CanvasTableMode.ColMode,
};
}
}
this.reCalcForScrollView();
}
reCalcForScrollView() {
if (this.dataIndex === undefined) {
return;
}
let w = 1;
if (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode) {
if (this.column) {
let i;
for (i = 0; i < this.column.length; i++) {
w += this.column[i].width * this.r + 0;
}
}
else {
w = undefined;
}
}
let h = 0;
const cellHeight = this.cellHeight;
const calc = (index) => {
let i;
switch (index.type) {
case CustomCanvasIndex_1.CanvasTableIndexType.Index:
h += cellHeight * index.list.length;
break;
case CustomCanvasIndex_1.CanvasTableIndexType.GroupItems:
for (i = 0; i < index.list.length; i++) {
h += cellHeight;
if (index.list[i].isExpended) {
calc(index.list[i].child);
}
}
break;
case CustomCanvasIndex_1.CanvasTableIndexType.GroupRows:
for (i = 0; i < index.list.length; i++) {
h += cellHeight;
if (index.list[i].isExpended) {
h += cellHeight * this.column.length;
}
}
break;
}
};
calc(this.dataIndex.index);
if (this.scrollView && w !== undefined) {
this.scrollView.setSize(this.r, this.canvasWidth, this.canvasHeight, w, h * this.r);
this.fireReCalcForScrollView(w / this.r, h + this.headerHeight);
}
}
setCanvasSize(width, height) {
this.canvasWidth = width;
this.canvasHeight = height;
this.reCalcForScrollView();
}
doReize(width, height) {
this.setCanvasSize(width * this.r, height * this.r);
}
drawCanvas() {
if (!this.scrollView || !this.context || !this.dataIndex) {
return;
}
if (this.needToCalc) {
this.calcColum();
}
this.context.font = this.config.fontStyle + " " + this.config.fontSize * this.r + "px " + this.config.font;
const posX = this.scrollView.getPosX();
if (this.needToCalcFont) {
this.minFontWidth = this.context.measureText("i").width;
this.maxFontWidth = this.context.measureText("Æ").width;
}
if (this.drawconf !== undefined && this.drawconf.fulldraw) {
this.drawconf = undefined;
}
const drawConf = this.drawconf;
this.drawconf = undefined;
this.requestAnimationFrame = undefined;
if (this.scrollView.beforeDraw()) {
this.askForReDraw();
}
const headderHeight = this.headerHeight * this.r;
const offsetLeft = 5 * this.r;
if (drawConf === undefined) {
this.context.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
}
this.context.fillStyle = this.config.fontColor;
this.context.strokeStyle = this.config.lineColor;
const colStart = 0;
const colEnd = this.column.length;
const height = this.cellHeight * this.r;
const index = this.dataIndex.index;
let pos;
let i;
let maxPos;
switch (index.type) {
case CustomCanvasIndex_1.CanvasTableIndexType.Index:
maxPos = this.canvasHeight + this.cellHeight + 5 * this.r;
i = Math.floor(this.scrollView.getPosY() / (height));
pos = (-this.scrollView.getPosY() + (i + 1) * height);
pos += 14 * this.r;
while (pos < maxPos) {
if (i < index.list.length) {
this.drawRowItem(this.context, index.list[i], i, pos, posX, height, offsetLeft, colStart, colEnd, drawConf);
}
else {
break;
}
pos += height;
i++;
}
this.context.beginPath();
const end = pos - height + 4 * this.r;
const firstLine = -this.scrollView.getPosX() + this.column[colStart].leftPos;
this.context.moveTo(firstLine, headderHeight);
this.context.lineTo(firstLine, end);
for (let col = colStart; col < colEnd; col++) {
const rightPos = -this.scrollView.getPosX() + this.column[col].rightPos;
this.context.moveTo(rightPos, headderHeight);
this.context.lineTo(rightPos, end);
}
this.context.stroke();
break;
case CustomCanvasIndex_1.CanvasTableIndexType.GroupItems:
pos = -this.scrollView.getPosY();
maxPos = this.canvasHeight + this.cellHeight + 5 * this.r;
pos += (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode ? 14 : -4) * this.r + height;
i = 0;
const w = (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode) ? Math.min(-posX +
this.column[this.column.length - 1].rightPos, this.canvasWidth)
: this.canvasWidth;
while (pos < maxPos && index.list.length > i) {
const item = index.list[i];
pos = this.drawGroupItem(this.context, 1, item, pos, posX, w, height, maxPos, offsetLeft, colStart, colEnd, drawConf);
i++;
}
break;
case CustomCanvasIndex_1.CanvasTableIndexType.GroupRows:
pos = -this.scrollView.getPosY() + height - 4 * this.r;
this.drawGroupRowsItem(this.context, 1, index, pos, posX, height, offsetLeft, drawConf);
break;
}
if (this.dataIndex.mode === CanvasTableMode_1.CanvasTableMode.ColMode) {
// Headder
pos = 14 * this.r;
this.context.font = this.config.headerFontStyle + " " +
(this.config.headerFontSize * this.r) + "px " + this.config.headerFont;
this.context.fillStyle = this.config.headerFontColor;
this.context.clearRect(0, 0, this.canvasWidth, headderHeight);
this.context.beginPath();
this.context.strokeStyle = this.config.lineColor;
const leftPos = -this.scrollView.getPosX() + this.column[colStart].leftPos;
this.context.moveTo(leftPos, 0);
this.context.lineTo(leftPos, headderHeight);
for (let col = colStart; col < colEnd; col++) {
const rightPos = -this.scrollView.getPosX() + this.column[col].rightPos;
this.context.moveTo(rightPos, 0);
this.context.lineTo(rightPos, headderHeight);
}
this.context.stroke();
this.context.textAlign = "left";
for (let col = colStart; col < colEnd; col++) {
let needClip;
const colItem = this.column[col];
const colWidth = this.column[col].width * this.r - offsetLeft * 2;
const data = this.column[col].header;
if (colWidth > data.length * this.maxFontWidth) {
needClip = false;
}
else if (colWidth < data.length * this.minFontWidth) {
needClip = true;
}
else {
needClip = colWidth < this.context.measureText(data).width;
}
this.context.fillStyle = this.config.headerBackgroundColor;
if (needClip) {
this.context.fillRect(-posX + colItem.leftPos + 1, pos - height + 4 * this.r + 1, colItem.width * this.r - 1 * 2, height - 3);
this.context.save();
this.context.beginPath();
this.context.rect(-this.scrollView.getPosX() + colItem.leftPos + offsetLeft, pos - height, colItem.width * this.r - offsetLeft * 2, height);
this.context.clip();
this.context.fillStyle = this.config.headerFontColor;
this.context.fillText(data, -this.scrollView.getPosX() + colItem.leftPos + offsetLeft, pos);
this.context.restore();
}
else {
this.context.fillRect(-posX + colItem.leftPos + 1, pos - height + 4 * this.r + 1, colItem.width * this.r - 1 * 2, height - 3);
this.context.fillStyle = this.config.headerFontColor;
this.context.fillText(data, -this.scrollView.getPosX() + colItem.leftPos + offsetLeft, pos);
}
if (this.config.headerDrawSortArrow) {
let sort;
if (this.sortCol) {
let sortIndex;
for (sortIndex = 0; sortIndex < this.sortCol.length; sortIndex++) {
if (this.sortCol[sortIndex].col === this.column[col].orginalCol) {
sort = this