e-virt-table
Version:
A powerful data table based on canvas. You can use it as data grid、Microsoft Excel or Google sheets. It supports virtual scroll、cell edit etc.
1,089 lines • 38.4 kB
JavaScript
import BaseCell from './BaseCell';
export default class Cell extends BaseCell {
constructor(ctx, rowIndex, colIndex, x, y, width, height, column, row, cellType = 'body') {
super(ctx, x, y, width, height, cellType, column.fixed);
Object.defineProperty(this, "formatter", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "formatterFooter", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "hoverIconName", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "operation", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "align", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "verticalAlign", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "fixed", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "type", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "editorType", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "editorProps", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "cellType", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "level", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "colspan", {
enumerable: true,
configurable: true,
writable: true,
value: 1
});
Object.defineProperty(this, "rowspan", {
enumerable: true,
configurable: true,
writable: true,
value: 1
});
Object.defineProperty(this, "mergeRow", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "mergeCol", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "relationRowKeys", {
enumerable: true,
configurable: true,
writable: true,
value: []
}); // 合并单元格关联key
Object.defineProperty(this, "relationColKeys", {
enumerable: true,
configurable: true,
writable: true,
value: []
}); // 合并单元格关联key
Object.defineProperty(this, "key", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "column", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "rowIndex", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "colIndex", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "rowKey", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "row", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "value", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "render", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "renderFooter", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "style", {
enumerable: true,
configurable: true,
writable: true,
value: {}
});
Object.defineProperty(this, "rules", {
enumerable: true,
configurable: true,
writable: true,
value: []
});
Object.defineProperty(this, "message", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "text", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "displayText", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "visibleWidth", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "visibleHeight", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "isHasChanged", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "drawX", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "drawY", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "drawCellBgColor", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "drawCellSkyBgColor", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "drawTextColor", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "drawTextX", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "drawTextY", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "drawImageX", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "drawImageY", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "drawImageWidth", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "drawImageHeight", {
enumerable: true,
configurable: true,
writable: true,
value: 0
});
Object.defineProperty(this, "drawImageName", {
enumerable: true,
configurable: true,
writable: true,
value: ''
});
Object.defineProperty(this, "drawImageSource", {
enumerable: true,
configurable: true,
writable: true,
value: void 0
});
Object.defineProperty(this, "ellipsis", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "rowExpand", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "rowHasChildren", {
enumerable: true,
configurable: true,
writable: true,
value: false
});
Object.defineProperty(this, "overflowTooltipShow", {
enumerable: true,
configurable: true,
writable: true,
value: true
});
Object.defineProperty(this, "overflowTooltipMaxWidth", {
enumerable: true,
configurable: true,
writable: true,
value: 500
});
Object.defineProperty(this, "overflowTooltipPlacement", {
enumerable: true,
configurable: true,
writable: true,
value: 'top'
});
this.visibleWidth = this.width;
this.visibleHeight = this.height;
this.colIndex = colIndex;
this.rowIndex = rowIndex;
this.key = column.key;
this.type = column.type || '';
this.editorType = column.editorType || 'text';
this.editorProps = column.editorProps || {};
this.cellType = cellType;
this.align = column.align || 'center';
this.verticalAlign = column.verticalAlign || 'middle';
this.fixed = column.fixed;
this.level = column.level || 0;
this.operation = column.operation || false;
this.column = column;
this.rules = column.rules || [];
this.row = row;
this.rowKey =
this.cellType === 'body'
? this.ctx.database.getRowKeyForRowIndex(rowIndex)
: `${this.cellType}_${this.rowIndex}`;
this.value = this.getValue();
this.render = column.render;
this.overflowTooltipShow = column.overflowTooltipShow === false ? false : true;
this.overflowTooltipMaxWidth = column.overflowTooltipMaxWidth || 500;
this.overflowTooltipPlacement = column.overflowTooltipPlacement || 'top';
this.renderFooter = column.renderFooter;
this.hoverIconName = column.hoverIconName;
this.formatter = column.formatter;
this.formatterFooter = column.formatterFooter;
this.update();
}
setWidthHeight(width, height) {
this.width = width;
this.height = height;
}
getValidationMessage() {
const errors = this.ctx.database.getValidationError(this.rowKey, this.key);
if (Array.isArray(errors) && errors.length) {
const [err] = errors;
this.message = err.message || '';
}
return this.message;
}
update() {
this.drawX = this.getDrawX();
this.drawY = this.getDrawY();
this.drawTextX = this.drawX;
this.drawTextY = this.drawY;
this.isHasChanged = this.ctx.database.isHasChangedData(this.rowKey, this.key);
this.updateSpan();
this.updateStyle();
this.updateType();
this.updateHoverIcon();
this.updateSelection();
this.updateTree();
this.updateEditor();
this.updateRender();
this.getValidationMessage();
this.updateContainer();
this.text = this.getText();
this.displayText = this.getDisplayText();
}
updateSpan() {
// 合计不合并
if (this.cellType === 'footer') {
return;
}
const { SPAN_METHOD } = this.ctx.config;
if (typeof SPAN_METHOD === 'function') {
const spanMethod = SPAN_METHOD;
const { colspan = 1, rowspan = 1, relationRowKeys, relationColKeys, mergeRow = false, mergeCol = false, } = spanMethod({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.getValue(),
headIndex: this.ctx.body.headIndex,
headPosition: this.ctx.database.getPositionForRowIndex(this.ctx.body.headIndex),
visibleRows: this.ctx.body.visibleRows,
visibleLeafColumns: this.ctx.header.visibleLeafColumns,
rows: this.ctx.body.data,
}) || {};
if (Array.isArray(relationRowKeys) && relationRowKeys.length > 0) {
this.relationRowKeys = relationRowKeys;
}
else {
this.relationRowKeys = [this.key];
}
if (Array.isArray(relationColKeys) && relationColKeys.length > 0) {
this.relationColKeys = relationColKeys;
}
else {
this.relationColKeys = [this.key];
}
this.mergeCol = mergeCol;
this.mergeRow = mergeRow;
this.colspan = colspan;
this.rowspan = rowspan;
this.visibleWidth = this.getWidthByColIndexColSpan(this.colIndex, this.colspan);
this.visibleHeight = this.ctx.database.getHeightByRowIndexRowSpan(this.rowIndex, this.rowspan);
}
}
updateSpanInfo() {
// 列合并单元格
if (this.mergeRow || this.mergeCol) {
const spanInfo = this.getSpanInfo();
this.height = spanInfo.height;
this.width = spanInfo.width;
this.drawX = this.getDrawX();
this.drawY = this.getDrawY();
this.drawY -= spanInfo.offsetTop;
this.drawX -= spanInfo.offsetLeft;
}
}
updateType() {
// 更改类型
const { BODY_CELL_TYPE_METHOD } = this.ctx.config;
if (typeof BODY_CELL_TYPE_METHOD === 'function') {
const cellTypeMethod = BODY_CELL_TYPE_METHOD;
const type = cellTypeMethod({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.getValue(),
});
// 可以动态改变类型
if (type !== undefined) {
this.type = type;
}
}
}
updateEditor() {
// 更改类型
const { BODY_CELL_EDITOR_METHOD } = this.ctx.config;
if (typeof BODY_CELL_EDITOR_METHOD === 'function') {
const CellEditorMethod = BODY_CELL_EDITOR_METHOD;
const editorProps = CellEditorMethod({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.getValue(),
});
// 可以动态改变类型
if (editorProps !== undefined) {
const { type, props = {} } = editorProps;
this.editorType = type;
this.editorProps = props;
}
}
}
updateRender() {
const { BODY_CELL_RENDER_METHOD } = this.ctx.config;
if (typeof BODY_CELL_RENDER_METHOD === 'function') {
const cellRenderMethod = BODY_CELL_RENDER_METHOD;
const render = cellRenderMethod({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.getValue(),
});
// 可以动态改变类型
if (render !== undefined) {
this.render = render;
}
}
}
validate() {
this.ctx.database
.getValidator(this.rowKey, this.key)
.then(() => {
this.ctx.database.setValidationError(this.rowKey, this.key, []);
this.message = '';
})
.catch((errors) => {
if (Array.isArray(errors) && errors.length) {
const [err] = errors;
this.message = err.message;
this.ctx.database.setValidationError(this.rowKey, this.key, errors);
}
})
.finally(() => {
this.ctx.emit('draw');
});
}
/**
* 更新样式
*/
updateStyle() {
this.style = this.getOverlayerViewsStyle();
}
updateTree() {
const { CELL_PADDING = 0 } = this.ctx.config;
const { rowKey, cellType } = this;
let icon = undefined;
let iconOffsetX = 0;
let iconName = '';
if (this.type === 'tree' && cellType === 'body') {
const row = this.ctx.database.getRowForRowKey(rowKey);
const { expand = false, hasChildren = false, expandLoading = false, level = 0 } = row || {};
this.rowExpand = expand;
this.rowHasChildren = hasChildren;
if (expandLoading) {
const loadingIcon = this.ctx.icons.get('loading');
iconName = 'loading';
icon = loadingIcon;
iconOffsetX = level * 8;
}
else if (hasChildren) {
const expandIcon = this.ctx.icons.get('expand');
const shrinkIcon = this.ctx.icons.get('shrink');
icon = !expand ? expandIcon : shrinkIcon;
iconName = !expand ? 'expand' : 'shrink';
iconOffsetX = level * 8;
}
else {
iconOffsetX = level * 8;
}
let iconWidth = 20;
let iconHeight = 20;
if (icon) {
let iconX = this.drawX + iconOffsetX + CELL_PADDING;
let iconY = this.drawY + (this.visibleHeight - iconHeight) / 2;
this.ctx.paint.drawImage(icon, iconX, iconY, iconWidth, iconHeight);
this.drawImageX = iconX;
this.drawImageY = iconY;
this.drawImageWidth = iconWidth;
this.drawImageHeight = iconHeight;
this.drawImageName = iconName;
this.drawImageSource = icon;
}
// 更改文本距离
this.align = 'left';
this.drawTextX = iconOffsetX + this.drawX + iconWidth - 0.5;
}
}
updateContainer() {
const { BODY_BG_COLOR, EDIT_BG_COLOR, BODY_CELL_STYLE_METHOD, FOOTER_CELL_STYLE_METHOD, READONLY_TEXT_COLOR, FOOTER_BG_COLOR, HIGHLIGHT_SELECTED_ROW, HIGHLIGHT_SELECTED_ROW_COLOR, HIGHLIGHT_HOVER_ROW, HIGHLIGHT_HOVER_ROW_COLOR, } = this.ctx.config;
if (this.cellType === 'footer') {
let bgColor = FOOTER_BG_COLOR;
let textColor = READONLY_TEXT_COLOR;
if (typeof FOOTER_CELL_STYLE_METHOD === 'function') {
const footerCellStyleMethod = FOOTER_CELL_STYLE_METHOD;
const { backgroundColor, color } = footerCellStyleMethod({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.getValue(),
}) || {};
if (backgroundColor) {
bgColor = backgroundColor;
}
// 文字颜色
if (color) {
textColor = color;
}
}
// 合计底部背景色
this.drawCellSkyBgColor = 'transparent';
this.drawCellBgColor = bgColor;
this.drawTextColor = textColor;
return;
}
// 高亮行,在背景色上加一层颜色
let drawCellSkyBgColor = 'transparent';
// 高亮行
const focusCell = this.ctx.focusCell;
const hoverCell = this.ctx.hoverCell;
if (HIGHLIGHT_HOVER_ROW && hoverCell?.rowKey === this.rowKey) {
drawCellSkyBgColor = HIGHLIGHT_HOVER_ROW_COLOR;
}
if (HIGHLIGHT_SELECTED_ROW && focusCell?.rowKey === this.rowKey) {
drawCellSkyBgColor = HIGHLIGHT_SELECTED_ROW_COLOR;
}
this.drawCellSkyBgColor = drawCellSkyBgColor;
// 恢复默认背景色
let bgColor = BODY_BG_COLOR;
let textColor = READONLY_TEXT_COLOR;
// 只读
if (['index', 'index-selection', 'selection'].includes(this.type)) {
this.drawCellBgColor = BODY_BG_COLOR;
this.drawTextColor = READONLY_TEXT_COLOR;
return;
}
if (!this.ctx.database.getReadonly(this.rowKey, this.key)) {
bgColor = EDIT_BG_COLOR;
textColor = READONLY_TEXT_COLOR;
}
if (typeof BODY_CELL_STYLE_METHOD === 'function') {
const cellStyleMethod = BODY_CELL_STYLE_METHOD;
const { backgroundColor, color } = cellStyleMethod({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
isHasChanged: this.isHasChanged,
value: this.getValue(),
}) || {};
if (backgroundColor) {
bgColor = backgroundColor;
}
// 文字颜色
if (color) {
textColor = color;
}
}
this.drawCellBgColor = bgColor;
this.drawTextColor = textColor;
// if (change) {
// this.setBackgroundColor("red");
// }
}
updateSelection() {
const { visibleWidth, visibleHeight, rowspan, colspan, cellType, type, rowIndex, rowKey } = this;
//合并的选框不显示
if (rowspan === 0 || colspan === 0) {
return;
}
// 合计不显示
if (cellType === 'footer') {
return;
}
// 选中框类型
if (['index-selection', 'selection'].includes(type)) {
const check = this.ctx.database.getRowSelection(rowKey);
const selectable = this.ctx.database.getRowSelectable(rowKey);
const { CHECKBOX_SIZE = 0 } = this.ctx.config;
const _x = this.drawX + (visibleWidth - CHECKBOX_SIZE) / 2;
const _y = this.drawY + (visibleHeight - CHECKBOX_SIZE) / 2;
let checkboxImage = this.ctx.icons.get('checkbox-uncheck');
let checkboxName = 'checkbox-uncheck';
if (check && selectable) {
checkboxImage = this.ctx.icons.get('checkbox-check');
checkboxName = 'checkbox-check';
}
else if (check && selectable) {
checkboxImage = this.ctx.icons.get('checkbox-check-disabled');
checkboxName = 'checkbox-check-disabled';
}
else if (!check && selectable) {
checkboxImage = this.ctx.icons.get('checkbox-uncheck');
checkboxName = 'checkbox-uncheck';
}
else {
checkboxImage = this.ctx.icons.get('checkbox-disabled');
checkboxName = 'checkbox-disabled';
}
if (checkboxImage && type == 'index-selection') {
if ((this.ctx.hoverCell && this.ctx.hoverCell.rowIndex === rowIndex) ||
['checkbox-disabled', 'checkbox-check'].includes(checkboxName)) {
this.drawImageX = _x;
this.drawImageY = _y;
this.drawImageWidth = CHECKBOX_SIZE;
this.drawImageHeight = CHECKBOX_SIZE;
this.drawImageName = checkboxName;
this.drawImageSource = checkboxImage;
}
}
else if (checkboxImage && 'selection' === type) {
this.drawImageX = _x;
this.drawImageY = _y;
this.drawImageWidth = CHECKBOX_SIZE;
this.drawImageHeight = CHECKBOX_SIZE;
this.drawImageName = checkboxName;
this.drawImageSource = checkboxImage;
}
}
}
updateHoverIcon() {
const { BODY_CELL_HOVER_ICON_METHOD, CELL_HOVER_ICON_SIZE, CELL_PADDING } = this.ctx.config;
if (typeof BODY_CELL_HOVER_ICON_METHOD === 'function') {
const hoverIconMethod = BODY_CELL_HOVER_ICON_METHOD;
const hoverIconName = hoverIconMethod({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.getValue(),
});
// 可以动态改变hoverIconName
if (hoverIconName !== undefined) {
this.hoverIconName = hoverIconName;
}
}
// 永远放在右边
const _x = this.drawX + this.width - CELL_HOVER_ICON_SIZE - CELL_PADDING;
const _y = this.drawY + (this.height - CELL_HOVER_ICON_SIZE) / 2;
if (this.hoverIconName) {
if (this.ctx.hoverCell && this.ctx.hoverCell.rowIndex === this.rowIndex) {
const drawImageSource = this.ctx.icons.get(this.hoverIconName);
this.drawImageX = _x;
this.drawImageY = _y;
this.drawImageWidth = CELL_HOVER_ICON_SIZE;
this.drawImageHeight = CELL_HOVER_ICON_SIZE;
this.drawImageName = this.hoverIconName;
this.drawImageSource = drawImageSource;
}
}
}
// 过去跨度配置
getSpanInfo() {
return this.ctx.database.getSpanInfo(this);
}
/**
* 获取显示文本
* @returns
*/
getDisplayText() {
if (this.cellType === 'footer') {
// 插槽不显示文本
if (this.renderFooter) {
return '';
}
if (this.text === null || this.text === undefined) {
return '';
}
return this.text;
}
else {
// cellType === "body"
// 被跨度单元格
if (this.rowspan === 0 || this.colspan === 0) {
return '';
}
// 插槽不显示文本
if (this.render) {
return '';
}
//
if (this.type === 'index-selection' &&
((this.ctx.hoverCell && this.ctx.hoverCell.rowIndex === this.rowIndex) ||
['checkbox-disabled', 'checkbox-check'].includes(this.drawImageName))) {
return '';
}
if (this.text === null || this.text === undefined) {
return '';
}
return `${this.text}`;
}
}
/**
* 获取文本
* @returns
*/
getText() {
if (this.cellType === 'footer') {
if (typeof this.formatterFooter === 'function') {
const _text = this.formatterFooter({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.row[this.key],
});
return _text;
}
return this.row[this.key];
}
// cellType === "body"
// formatter优先等级比较高
if (typeof this.formatter === 'function') {
const _text = this.formatter({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.getValue(),
});
return _text;
}
const { BODY_CELL_FORMATTER_METHOD } = this.ctx.config;
if (typeof BODY_CELL_FORMATTER_METHOD === 'function') {
const formatterMethod = BODY_CELL_FORMATTER_METHOD;
const _text = formatterMethod({
row: this.row,
rowIndex: this.rowIndex,
colIndex: this.colIndex,
column: this.column,
value: this.getValue(),
});
return _text;
}
if (['index-selection', 'index'].includes(this.type)) {
const str = `${this.rowIndex + 1}`; // 索引
return str; // 索引
}
this.value = this.ctx.database.getItemValue(this.rowKey, this.key);
return this.value;
}
getValue() {
return this.ctx.database.getItemValue(this.rowKey, this.key);
}
// 拓展格子可设置数据
setValue(value) {
this.ctx.setItemValueByEditor(this.rowKey, this.key, value);
}
/**
* 获取样式
*/
getOverlayerViewsStyle() {
let left = `${this.drawX - this.ctx.fixedLeftWidth}px`;
let top = `${this.drawY - this.ctx.body.y}px`;
// 固定列
if (this.fixed === 'left') {
left = `${this.drawX}px`;
}
else if (this.fixed === 'right') {
left = `${this.drawX - (this.ctx.stageWidth - this.ctx.fixedRightWidth)}px`;
}
// 合计
if (this.cellType === 'footer') {
if (this.ctx.config.FOOTER_FIXED) {
top = `${this.drawY - this.ctx.footer.y}px`;
}
}
return {
position: 'absolute',
overflow: 'hidden',
left,
top,
width: `${this.visibleWidth}px`,
height: `${this.visibleHeight}px`,
pointerEvents: 'initial',
userSelect: 'none',
};
}
draw() {
const { paint, config: { BORDER_COLOR }, } = this.ctx;
const { drawX, drawY } = this;
// 绘制单元格
paint.drawRect(drawX, drawY, this.visibleWidth, this.visibleHeight, {
borderColor: BORDER_COLOR,
fillColor: this.drawCellBgColor,
});
paint.drawRect(drawX, drawY, this.width, this.height, {
borderColor: 'transparent',
borderWidth: 1,
fillColor: this.drawCellSkyBgColor,
});
// 画选中框
this.drawText();
this.drawImage();
this.drawSelector();
this.drawAutofillPiont();
this.drawErrorTip();
}
/**
* 根据列的索引获取列的宽度
* @param {Number} colIndex
*/
getWidthByColIndexColSpan(colIndex, colSpan) {
if (colSpan === 0) {
return 0;
}
let width = 0;
for (let i = colIndex; i < colIndex + colSpan; i++) {
const cellHeader = this.ctx.header.leafCellHeaders[i];
width += cellHeader.width;
}
return width;
}
drawText() {
const { CELL_PADDING, BODY_FONT } = this.ctx.config;
const { ellipsis } = this.ctx.paint.handleEllipsis(this.text, this.width, CELL_PADDING, BODY_FONT);
this.ellipsis = ellipsis;
return this.ctx.paint.drawText(this.displayText, this.drawTextX, this.drawTextY, this.visibleWidth, this.visibleHeight, {
font: BODY_FONT,
padding: CELL_PADDING,
align: this.align,
verticalAlign: this.verticalAlign,
color: this.drawTextColor,
});
}
drawImage() {
if (!this.drawImageSource) {
return;
}
this.ctx.paint.drawImage(this.drawImageSource, this.drawImageX, this.drawImageY, this.drawImageWidth, this.drawImageHeight);
}
drawAutofillPiont() {
if (this.cellType === 'footer') {
return;
}
const { SELECT_BORDER_COLOR, ENABLE_AUTOFILL, ENABLE_SELECTOR, AUTOFILL_POINT_BORDER_COLOR } = this.ctx.config;
if (!ENABLE_SELECTOR) {
return;
}
if (!ENABLE_AUTOFILL) {
return;
}
const show = true;
const { xArr, yArr } = this.ctx.selector;
const maxX = xArr[1];
const maxY = yArr[1];
const { colIndex, rowIndex, drawX, drawY } = this;
// 绘制自动填充点
if (show && colIndex === maxX && rowIndex === maxY) {
this.ctx.paint.drawRect(drawX + this.width - 6, drawY + this.height - 6, 6, 6, {
borderColor: AUTOFILL_POINT_BORDER_COLOR,
fillColor: SELECT_BORDER_COLOR,
});
}
}
drawSelector() {
if (this.cellType === 'footer') {
return;
}
const { ENABLE_SELECTOR } = this.ctx.config;
if (!ENABLE_SELECTOR) {
return;
}
const { xArr, yArr, xArrCopy, yArrCopy } = this.ctx.selector;
// 复制线
this.drawBorder({
xArr: xArrCopy,
yArr: yArrCopy,
borderColor: this.ctx.config.SELECT_BORDER_COLOR || 'rgb(82,146,247)',
fillColor: 'transparent',
borderWidth: 1,
lineDash: [4, 4],
});
// 填充线
this.drawBorder({
xArr: this.ctx.autofill.xArr,
yArr: this.ctx.autofill.yArr,
borderColor: this.ctx.config.SELECT_BORDER_COLOR || 'rgb(82,146,247)',
fillColor: 'transparent',
borderWidth: 1,
lineDash: [4, 4],
});
// 选择线
this.drawBorder({
xArr,
yArr,
borderColor: this.ctx.config.SELECT_BORDER_COLOR || 'rgb(82,146,247)',
fillColor: 'transparent',
borderWidth: 1,
});
// 选择区背景颜色
const [minX, maxX] = xArr;
const [minY, maxY] = yArr;
const isOne = minX === maxX && minY === maxY;
if (!isOne &&
this.colIndex >= minX &&
this.colIndex <= maxX &&
this.rowIndex >= minY &&
this.rowIndex <= maxY) {
this.ctx.paint.drawRect(this.drawX, this.drawY, this.width, this.height, {
borderColor: 'transparent',
fillColor: this.ctx.config.SELECT_AREA_COLOR || 'rgba(82,146,247,0.1)',
});
}
if (this.operation && this.rowIndex >= minY && this.rowIndex <= maxY) {
this.ctx.paint.drawRect(this.drawX, this.drawY, this.visibleWidth, this.visibleHeight, {
borderColor: 'transparent',
fillColor: this.ctx.config.SELECT_ROW_COL_BG_COLOR || 'transparent',
});
}
}
drawErrorTip() {
// 合计不显示
if (this.cellType === 'footer') {
return;
}
// 没有错误消息
if (!this.message) {
return;
}
if (this.rowspan === 0 || this.colspan === 0) {
return;
}
const { ERROR_TIP_ICON_SIZE, ERROR_TIP_COLOR } = this.ctx.config;
const { width } = this;
const x = this.drawX;
const y = this.drawY;
const points = [
x + width - ERROR_TIP_ICON_SIZE - 0.5,
y,
x + width - 0.5,
y,
x + width - 0.5,
y + ERROR_TIP_ICON_SIZE,
];
this.ctx.paint.drawLine(points, {
borderColor: ERROR_TIP_COLOR,
fillColor: ERROR_TIP_COLOR,
borderWidth: 1,
lineCap: 'round',
lineJoin: 'round',
});
}
drawBorder(options) {
const { drawX, drawY, width, rowIndex, colIndex } = this;
let x = drawX + 0.5;
let y = drawY + 0.5;
let height = this.height;
// 第一行减去1,不然会被表头覆盖
if (rowIndex === 0) {
y = this.y + 1;
height = height - 1;
}
// 最后一列减去1,不然会被右边滚动条覆盖
if (colIndex === this.ctx.maxColIndex) {
x = x - 1;
}
const { xArr, yArr, lineDash = [], borderWidth = 1, borderColor, fillColor } = options;
const minX = xArr[0];
const maxX = xArr[1];
const minY = yArr[0];
const maxY = yArr[1];
// 选择
if (colIndex >= minX && colIndex <= maxX && rowIndex === minY) {
this.ctx.paint.drawLine([x, y, x + width - 2, y], {
borderColor,
fillColor,
borderWidth,
lineCap: 'round',
lineJoin: 'round',
lineDash,
});
}
// bottom border
if (colIndex >= minX && colIndex <= maxX && rowIndex === maxY) {
this.ctx.paint.drawLine([x, y + height - 1.5, x + width, y + height - 1.5], {
borderColor,
fillColor,
borderWidth,
lineCap: 'round',
lineJoin: 'round',
lineDash,
});
}
// left border
if (colIndex === minX && rowIndex >= minY && rowIndex <= maxY) {
this.ctx.paint.drawLine([x, y, x, y + height - 1], {
borderColor,
fillColor,
borderWidth,
lineCap: 'round',
lineJoin: 'round',
lineDash,
});
}
// right border
if (colIndex === maxX && rowIndex >= minY && rowIndex <= maxY) {
this.ctx.paint.drawLine([x + width - 1.5, y, x + width - 1.5, y + height - 1.5], {
borderColor,
fillColor,
borderWidth,
lineCap: 'round',
lineJoin: 'round',
lineDash,
});
}
}
}
//# sourceMappingURL=Cell.js.map