chartx
Version:
Data Visualization Chart Library
1,267 lines (1,204 loc) • 136 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf"));
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
var _canvax = _interopRequireDefault(require("canvax"));
var _tools = require("../../../utils/tools");
var _text = require("../../../utils/text");
var _index = _interopRequireDefault(require("../index"));
var _zoom = _interopRequireDefault(require("../../../utils/zoom"));
var _scroll = _interopRequireDefault(require("./scroll"));
var _color = require("../../../utils/color");
var _popover2 = _interopRequireDefault(require("../../../components/popover"));
var _tableDataFrame = _interopRequireDefault(require("../../../core/tableDataFrame"));
var _format = _interopRequireDefault(require("../../../utils/format"));
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
/**
* 1, 虚拟滚动,目前测试数据量10000条,滚动流畅
* 2,canvax离屏渲染
* 3,Text文本的离屏渲染( 有效问题,提供是否开启 )
*/
/**
* 给到外部调用的方法
* refreshAllCellStyle 刷新所有单元格样式
* renderTable 渲染表格
* draw 重新计算布局然后重新绘制
*/
var _ = _canvax.default._,
event = _canvax.default.event;
var animation = _canvax.default.animation;
var Rect = _canvax.default.Shapes.Rect;
var Line = _canvax.default.Shapes.Line;
var BrokenLine = _canvax.default.Shapes.BrokenLine;
function isParent(b, a) {
var maxDepth = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1000;
if (!a || !b) return false;
var depth = 0;
var current = a.parent;
while (current && depth < maxDepth) {
if (current === b) return true;
current = current.parent;
depth++;
}
return false;
}
var TableGraphs = /*#__PURE__*/function (_GraphsBase) {
function TableGraphs(opt, app) {
var _this;
(0, _classCallCheck2.default)(this, TableGraphs);
_this = _callSuper(this, TableGraphs, [opt, app]);
_this.type = "table";
_.extend(true, _this, (0, _tools.getDefaultProps)(TableGraphs.defaultProps()), opt);
_this.initOptHandle();
_this.init();
_this.initScroll();
window.d = performance.now();
window.table = _this;
_this._activeCellPopover = new _popover2.default(_this.activeCellPopoverInfo, _this.app);
return _this;
}
(0, _inherits2.default)(TableGraphs, _GraphsBase);
return (0, _createClass2.default)(TableGraphs, [{
key: "initOptHandle",
value: function initOptHandle(opt) {
//外部调用的时候会有opt
if (opt) {
_.extend(true, this, opt);
}
if (!this.columns) {
this.columns = [Object.keys(this.dataFrame.list[0] || {}).map(function (key) {
return {
field: key,
content: key,
width: 'auto'
};
})];
} else {
var _columns = this.columns;
if (!Array.isArray(_columns[0])) {
_columns = [_columns];
}
var newColumns = [];
_columns.forEach(function (columnsRowData, rowInd) {
var rowColumns = columnsRowData.map(function (cellData) {
return _objectSpread(_objectSpread({}, cellData), {}, {
field: cellData.field,
content: cellData.text || cellData.content || cellData.title || cellData.field,
width: cellData.width || 'auto'
});
});
newColumns.push(rowColumns);
});
this.columns = newColumns;
}
if (this.showIndexCol) {
this.columns[0].unshift({
field: '_index',
title: '',
rowspan: this.columns.length,
width: 30
});
this.dataFrame.list.forEach(function (row, index) {
row._index = index + 1;
});
this.leftColSticky++;
}
}
}, {
key: "init",
value: function init() {
var me = this;
var width = this.width,
height = this.height;
if (!width) {
width = this.app.width;
}
if (!height) {
height = this.app.height;
}
var borderLineWidth = this.style.border.width;
var _width = width - borderLineWidth;
var _height = height - borderLineWidth;
var _x = 0;
var _y = 0;
this.induce = new Rect({
id: 'induce',
context: {
x: _x,
y: _y,
width: _width,
height: _height,
lineWidth: borderLineWidth,
strokeStyle: this.style.border.color,
radius: this.style.border.radius,
fillStyle: 'rgba(0,0,0,0)'
}
});
this.sprite.addChild(this.induce);
//监听事件, 不做任何处理,主要用来冒泡到sprite
this.induce.on(event.types.get(), function (e) {
var scrollState = me.scroll.getState();
var point = {
x: e.point.x + scrollState.scrollLeft,
y: e.point.y + scrollState.scrollTop
};
var cell;
e.preventDefault();
var _contextmenu = me.app.getComponent({
name: 'contextmenu'
});
var eventIsInPopover = false;
if (me.app.canvax.domView !== e.srcElement && me.app.canvax.domView.contains(e.srcElement)) {
eventIsInPopover = true;
}
if (!(_contextmenu && _contextmenu.isShow || eventIsInPopover)) {
cell = me._getTargetCell(point);
if (e.type == 'mousedown') {
if (!cell) {
return;
}
//判断是否按住了command键或ctrl键,如果没有则清空选中
//cell = me._getTargetCell( point )
if (cell.type == 'th' && cell.col.colIndex == 0 && me.showIndexCol) {
//如果之前有全选,就删除掉 checkedAll为true的选项,如果没有就加一个 checkedAll为true的选项
var checkedAll = me.selected.allrows.checkedAll;
me.activeCellId = null;
me.unselect();
if (!checkedAll) {
me.select({
type: 'allrows',
checkedAll: !checkedAll,
excludeCellIds: []
});
}
} else {
var cellRowIsSelected = me.checkRowIsSelected(cell.row);
me.induce.toFront();
if (me.activeCellId) {
var activeCellId = me.activeCellId;
me.activeCellId = null;
if ((e.metaKey || e.ctrlKey) && cell.type == 'td' && cell.field != '_index') {
me.select({
type: 'cell',
cellIds: [activeCellId]
});
}
}
if (cell) {
if (cell.field == '_index') {
if (cell.type == 'td') {
if (!cellRowIsSelected) {
var currRowInd = cell.row.cells.findIndex(function (_cell) {
return _cell == cell;
});
var nextCell = cell.row.cells[currRowInd + 1];
me.activeCellId = nextCell.id;
me.select({
type: 'row',
rowId: cell.row.id
});
} else {
me.activeCellId = null;
me.unselect({
type: 'row',
rowId: cell.row.id
});
}
} else {
if (!(e.metaKey || e.ctrlKey)) {
me.unselect();
}
}
} else {
me.activeCellId = cell.id;
if (!(e.metaKey || e.ctrlKey)) {
me.unselect();
}
}
if (cell.field != '_index') {
me._dragBeginPoint = point;
me._dragBeginCell = cell;
}
if (cell.type == 'th') {
me.select({
type: 'col',
colCellId: cell.id
});
}
}
me.refreshAllCellStyle();
}
}
if (e.type == 'mouseup') {
var _me$_dragSelectedCell;
me.induce.toBack();
if (me._dragBeginCell && me._dragBeginCell.type == 'th') {
if (cell.col.colIndex >= me.leftColSticky) {
var transposDirection = 'left';
//如果中心偏右,则把point的x坐标设置为cell的x坐标+cell的宽度
if (point.x > cell.position.x + cell.size.width / 2) {
transposDirection = 'right';
}
// let columns = me.layoutData.rowData.columns.rows.find( row => row.cells.find( cell => cell.field == me._dragBeginCell.field ) )
// if( columns ){
// // 找到目标cell在columns中的索引
// let targetIndex = columns.cells.findIndex(col => col.field == cell.field);
// let transposIndex = columns.cells.findIndex(col => col.field == me._dragBeginCell.field);
// if (targetIndex !== -1 && transposIndex !== -1 && targetIndex !== transposIndex) {
// // 先移除要移动的列
// let [movedCol] = columns.cells.splice(transposIndex, 1);
// // 计算插入位置
// let insertIndex = targetIndex;
// if (transposDirection === 'right') {
// // 如果是右侧插入,且原位置在目标前面,插入索引要+1
// insertIndex = targetIndex + (transposIndex < targetIndex ? 0 : 1);
// } else {
// // left,插入到目标前面
// insertIndex = targetIndex + (transposIndex < targetIndex ? -1 : 0);
// }
// columns.cells.splice(insertIndex, 0, movedCol);
// // 更新每一个cell的colIndex
// columns.cells.forEach((cell, idx) => {
// cell.col.colIndex = idx;
// });
// me.renderTable()
// }
// }
// debugger
//把 _transposCell 的字段插入到 columns 的 cell 的 transposDirection 位置
var _columns2 = me.columns.find(function (columnGroup) {
return columnGroup.find(function (column) {
return column.field == me._dragBeginCell.field;
});
});
if (_columns2) {
// 找到目标cell在columns中的索引
var targetIndex = _columns2.findIndex(function (col) {
return col.field == cell.field;
});
var transposIndex = _columns2.findIndex(function (col) {
return col.field == me._dragBeginCell.field;
});
if (targetIndex !== -1 && transposIndex !== -1 && targetIndex !== transposIndex) {
// 先移除要移动的列
var _columns2$splice = _columns2.splice(transposIndex, 1),
_columns2$splice2 = (0, _slicedToArray2.default)(_columns2$splice, 1),
movedCol = _columns2$splice2[0];
// 计算插入位置
var insertIndex = targetIndex;
if (transposDirection === 'right') {
// 如果是右侧插入,且原位置在目标前面,插入索引要-1
insertIndex = targetIndex + (transposIndex < targetIndex ? 0 : 1);
} else {
// left,插入到目标前面
insertIndex = targetIndex + (transposIndex < targetIndex ? -1 : 0);
}
_columns2.splice(insertIndex, 0, movedCol);
// 触发表格重绘或相关更新
me.draw();
me.action({
type: 'transposColumn',
info: {
column: cell.col,
movedCol: movedCol,
transposIndex: transposIndex,
targetIndex: targetIndex,
transposDirection: transposDirection,
columns: _columns2
}
});
}
}
}
}
me._dragBeginPoint = null;
me._dragBeginCell = null;
if ((_me$_dragSelectedCell = me._dragSelectedCells) !== null && _me$_dragSelectedCell !== void 0 && _me$_dragSelectedCell.length) {
me.select({
type: 'cell',
cellIds: me._dragSelectedCells.map(function (item) {
return item.id;
})
});
}
me._dragSelectedCells = [];
// me._rectCloneImg.destroy()
// me._rectCloneImg = null
var transposThRect_clone = me.graphsView.getChildById('transposThRect_clone');
if (transposThRect_clone) {
transposThRect_clone.destroy();
}
var dragSplitLine = me.graphsView.getChildById('dragSplitLine');
if (dragSplitLine) {
dragSplitLine.destroy();
}
}
if (e.type == 'mouseout') {
var _me$_dragSelectedCell2;
me.induce.toBack();
me._dragBeginPoint = null;
me._dragBeginCell = null;
if ((_me$_dragSelectedCell2 = me._dragSelectedCells) !== null && _me$_dragSelectedCell2 !== void 0 && _me$_dragSelectedCell2.length) {
me.select({
type: 'cell',
cellIds: me._dragSelectedCells.map(function (item) {
return item.id;
})
});
}
me._dragSelectedCells = [];
// me._rectCloneImg.destroy()
// me._rectCloneImg = null
var _transposThRect_clone = me.graphsView.getChildById('transposThRect_clone');
if (_transposThRect_clone) {
_transposThRect_clone.destroy();
}
var _dragSplitLine = me.graphsView.getChildById('dragSplitLine');
if (_dragSplitLine) {
_dragSplitLine.destroy();
}
}
if (e.type == 'mousemove') {
//在表格中按下了,开始拖拽鼠标
if (me._dragBeginPoint) {
if (me._dragBeginCell.type == 'td') {
//首先把原来的hover行取消掉
var preHoverRow = me._hoverRow;
me._hoverRow = null;
if (preHoverRow) {
preHoverRow.cells.forEach(function (cell) {
me._setCellStyle(cell);
});
}
//把前面临时选中的 me._dragSelectedCells 取消选中
me.unselect(me._dragSelectedCells);
me._dragSelectedCells = [];
var _scrollState = me.scroll.getState();
// 获取拖拽的起始点和当前点坐标
var startX = Math.min(me._dragBeginPoint.x, point.x);
var startY = Math.min(me._dragBeginPoint.y, point.y);
var endX = Math.max(me._dragBeginPoint.x, point.x);
var endY = Math.max(me._dragBeginPoint.y, point.y);
var selectedCells = [];
// 只检查渲染范围内的数据行,表头不需要处理
for (var i = _scrollState.renderedRange.start; i <= _scrollState.renderedRange.end; i++) {
var row = me.layoutData.rowData.list.rows[i];
if (row) {
row.cells.forEach(function (cell) {
if (cell.position.x < endX && cell.position.x + cell.size.width > startX && cell.position.y < endY && cell.position.y + cell.size.height > startY) {
if (me.showIndexCol && cell.col.colIndex == 0) {
//索引单元格不能拖拽选中
} else {
selectedCells.push(cell);
}
}
});
}
}
me.select({
type: 'cell',
cellIds: selectedCells.map(function (item) {
return item.id;
})
});
me._dragSelectedCells = selectedCells;
}
if (me._dragBeginCell.type == 'th') {
//拖拽表头,移动切换位置
//要创建一个和表头列一样宽的矩形,高度和当前可见的矩形最下面的td保持一致
var rectClone = me.graphsView.getChildById('transposThRect_clone');
if (!rectClone) {
rectClone = new Rect({
id: 'transposThRect_clone',
context: {}
});
me.graphsView.addChild(rectClone);
}
var h = Math.min(me.app.height, scrollState.scrollHeight - scrollState.scrollTop);
Object.assign(rectClone.context, {
x: me._dragBeginCell.position.x + (point.x - me._dragBeginPoint.x),
y: me._dragBeginCell.position.y + scrollState.scrollTop,
width: me._dragBeginCell.size.width,
height: h,
fillStyle: "#ccc",
fillAlpha: 0.4
});
var _dragSplitLine2 = me.graphsView.getChildById('dragSplitLine');
if (!_dragSplitLine2) {
_dragSplitLine2 = new BrokenLine({
id: 'dragSplitLine',
context: {
strokeStyle: me.style.transpos.splitLineStrokeStyle,
lineWidth: me.style.transpos.splitLineWidth
}
});
me.graphsView.addChild(_dragSplitLine2);
}
//如果point在cell的中心偏左,则把point的x坐标设置为cell的x坐标
var splitX = cell.position.x;
//如果中心偏右,则把point的x坐标设置为cell的x坐标+cell的宽度
if (point.x > cell.position.x + cell.size.width / 2) {
splitX = cell.position.x + cell.size.width;
}
//如果是最后一个列,splitX 还要 -1
if (cell.col.colIndex == me.columns[0].length - 1) {
splitX = splitX - 1;
}
Object.assign(_dragSplitLine2.context, {
pointList: [[splitX, me._dragBeginCell.position.y + scrollState.scrollTop], [splitX, h]]
});
//如果cell.col.colIndex 在左侧锁定列的范围内,则取消dragSplitLine的显示
if (cell.col.colIndex < me.leftColSticky) {
_dragSplitLine2.destroy();
}
// let rectCloneImg = me._rectCloneImg
// if( !rectCloneImg ){
// rectCloneImg = new Canvax.Display.Image({
// id: 'dragThRect_clone_img',
// context: {
// scaleX: 1/2,
// scaleY: 1/2,
// sx: me._dragBeginCell.position.x*2 + 4,
// sy: me._dragBeginCell.position.y + 2,
// sWidth:me._dragBeginCell.size.width*2,
// sHeight: me._dragBeginCell.size.height*2 + 2,
// x: me._dragBeginCell.position.x + ( point.x - me._dragBeginPoint.x ) + 2 ,
// y: me._dragBeginCell.position.y,
// width: me._dragBeginCell.size.width*2 ,
// height: me._dragBeginCell.size.height*2 + 2,
// fillStyle: me.style.tdSelected.backgroundColor,
// //globalAlpha: 0.5
// }
// }, me.app.stage.canvas)
// me._rectCloneImg = rectCloneImg
// me.graphsView.addChild( rectCloneImg )
// } else {
// Object.assign( rectCloneImg.context, {
// x: me._dragBeginCell.position.x + ( point.x - me._dragBeginPoint.x ) ,
// })
// }
//这个矩形跟随鼠标移动,然后判断这个矩形是否和其它的表头列有重叠,如果有重叠,则交换位置
}
} else {
//非拖拽的情况下,要执行hover行的逻辑了
//先用当前鼠标的位置,获取到当前鼠标所在的行
var _row2 = me.layoutData.rowData.list.rows.find(function (row) {
return row.cells.some(function (cell) {
return cell.position.y < point.y && cell.position.y + cell.size.height > point.y;
});
});
if (_row2 == me._hoverRow) {
return;
} else {
//首先把原来的hover行取消掉
var _preHoverRow = me._hoverRow;
me._hoverRow = _row2;
if (_preHoverRow) {
_preHoverRow.cells.forEach(function (cell) {
me._setCellStyle(cell);
});
}
if (_row2) {
_row2.cells.forEach(function (cell) {
me._setCellStyle(cell);
});
}
}
}
}
//滚轮
if (e.type == "wheel") {
// 添加时间间隔检查,避免过于频繁的更新
var now = Date.now();
if (now - _lastWheelTime < 16) {
// 约60fps
return;
}
_lastWheelTime = now;
if (!_ticking) {
requestAnimationFrame(function () {
//滚动的时候先把所有的popover 隐藏
var popover = me.app.getComponent({
name: 'popover'
});
if (popover) {
popover.hide(e);
}
if (me._activeCellPopover) {
me._activeCellPopover.hide(e);
}
var scrollState = me.scroll.getState();
var layoutHeight = scrollState.scrollHeight;
var layoutWidth = me.layoutData.rowData.columns.size.width;
// 控制最大滚动距离
var maxScrollStep = me.style.cell.minHeight * (scrollState.bufferSize || 1); // 比如限制为5行的高度
var deltaY = e.deltaY;
var deltaX = e.deltaX;
// 限制垂直滚动的最大距离
if (Math.abs(deltaY) > maxScrollStep) {
deltaY = maxScrollStep * Math.sign(deltaY);
}
var offsetPoint = {
x: -deltaX,
y: -deltaY
};
// 处理水平方向,如果向左滚动,则固定列需要保持在左侧
if (me.graphsView.context.x + offsetPoint.x > me.contentX) {
offsetPoint.x = me.contentX - me.graphsView.context.x;
}
// 处理水平方向,如果向右滚动,则固定列需要保持在右侧
// 只有当内容宽度大于视口宽度时才进行右边界限制,避免内容宽度小于视口时被强制右对齐
if (layoutWidth > scrollState.viewportWidth) {
if (me.graphsView.context.x + layoutWidth + offsetPoint.x < me.contentX + scrollState.viewportWidth) {
offsetPoint.x = me.contentX + scrollState.viewportWidth - (me.graphsView.context.x + layoutWidth);
}
} else {
// 当内容宽度小于等于视口宽度时,确保表格不会滚动到右边界之外
if (me.graphsView.context.x + offsetPoint.x < me.contentX) {
offsetPoint.x = me.contentX - me.graphsView.context.x;
}
}
// 处理垂直方向,如果向上滚动,则固定列需要保持在顶部
if (me.graphsView.context.y + offsetPoint.y > me.contentY) {
offsetPoint.y = me.contentY - me.graphsView.context.y;
}
//首先判断数据的长度比viewHeight要大
if (layoutHeight > scrollState.viewportHeight) {
//处理垂直方向,如果向下滚动,则最后一行需要保持在底部
if (me.graphsView.context.y + layoutHeight + offsetPoint.y < me.contentY + scrollState.viewportHeight) {
offsetPoint.y = me.contentY + scrollState.viewportHeight - (me.graphsView.context.y + layoutHeight);
}
}
if (layoutHeight < scrollState.viewportHeight) {
offsetPoint.y = 0;
}
var _me$zoom$offset = me.zoom.offset(offsetPoint),
x = _me$zoom$offset.x,
y = _me$zoom$offset.y;
me.graphsView.context.x = x;
me.graphsView.context.y = y;
// 处理固定列和表头的位置同步
me._syncStickyElements(cell);
//这个x y 中包含了初始值的偏移量的 me.style.border.width
me.scroll.scrollTo(-(x - me.style.border.width), -(y - me.style.border.width));
me.updateLayoutData();
_ticking = false;
});
_ticking = true;
}
}
;
if (cell) {
//从滚动状态中获取可视范围
e.eventInfo = {
trigger: me,
iNode: -1,
//TODO:这里设置了的话,会导致多graphs里获取不到别的graphs的nodes信息了
nodes: [cell]
};
//触发root统一设置e.eventInfo.nodes,所以上面不需要设置
me.app.fire(e.type, e);
}
}
});
this.graphsView = new _canvax.default.Display.Sprite({
context: {
x: _x,
y: _y
}
});
this.sprite.addChild(this.graphsView);
//设置表格的裁剪区域
var clipRect = new Rect({
context: {
x: _x,
y: _y,
width: _width,
height: _height,
fillStyle: 'green',
radius: this.style.border.radius
}
});
this.graphsView.clipTo(clipRect);
this.sprite.addChild(clipRect);
//主表格
this.listSp = new _canvax.default.Display.Sprite({
id: 'listSp'
});
this.graphsView.addChild(this.listSp);
//左边锁定列区域(不包含表头)
this.leftColStickySp = new _canvax.default.Display.Sprite({
id: 'leftColStickySp'
});
this.graphsView.addChild(this.leftColStickySp);
//普通列头
this.columnsSp = new _canvax.default.Display.Sprite({
id: 'columnsSp'
});
this.graphsView.addChild(this.columnsSp);
//创建固定列表头容器
this.fixedColHeaderSp = new _canvax.default.Display.Sprite({
id: 'fixedColHeaderSp'
});
this.graphsView.addChild(this.fixedColHeaderSp);
//设置主表格区域的选中层
this.selectedSp = new _canvax.default.Display.Sprite({
id: 'selectedSp'
});
this.graphsView.addChild(this.selectedSp);
//设置表格的裁剪区域
this.selectedSpClipRect = new Rect({
context: {
x: _x,
y: _y,
width: _width,
height: _height,
fillStyle: 'red',
alpha: 1
}
});
this.selectedSp.clipTo(this.selectedSpClipRect);
this.sprite.addChild(this.selectedSpClipRect);
if (this.domContainer) {
var _selectedDomContainer = document.createElement("div");
_selectedDomContainer.style.cssText = " ;position:absolute;width:left:-1000px;top:-1000px;color:" + itemData.fillStyle + "";
_selectedDomContainer.innerHTML = textTxt;
me.domContainer.appendChild(_selectedDomContainer);
}
//设置 左侧固定 表格区域的选中层
this.leftSelectedSp = new _canvax.default.Display.Sprite({
id: 'leftSelectedSp'
});
this.graphsView.addChild(this.leftSelectedSp);
//设置表格的裁剪区域
this.leftSelectedSpClipRect = new Rect({
context: {
x: _x,
y: _y,
width: _width,
height: _height,
fillStyle: 'red',
alpha: 0.1
}
});
this.leftSelectedSp.clipTo(this.leftSelectedSpClipRect);
this.sprite.addChild(this.leftSelectedSpClipRect);
//汇总区域
//汇总的普通列区域
var summaryTop = _height - this.summary.height;
this.summaryColumnsSp = new _canvax.default.Display.Sprite({
id: 'summaryColumnsSp',
context: {
y: summaryTop
}
});
this.graphsView.addChild(this.summaryColumnsSp);
//汇总的左边固定列区域
this.summaryLeftColStickySp = new _canvax.default.Display.Sprite({
id: 'summaryLeftColStickySp',
context: {
y: summaryTop
}
});
this.graphsView.addChild(this.summaryLeftColStickySp);
this.contentX = _x;
this.contentY = _y;
this.layoutData = {
rowData: {
columns: [],
list: []
},
colData: [],
colDataMap: new Map()
};
//滚轮缩放相关
var _ticking = false;
var _lastWheelTime = 0;
this.zoom = new _zoom.default();
//初始值为_x _y,所以要先同步到zoom里
me.zoom.offset({
x: _x,
y: _y
});
this.sprite.on(event.types.get(), function (e) {
var _contextmenu = me.app.getComponent({
name: 'contextmenu'
});
if (!_contextmenu || !_contextmenu.isShow) {
e.preventDefault();
if (e.type == 'mouseover') {
//进入表格
if (e.fromTarget && isParent(me.sprite, e.fromTarget)) {
return;
}
me.scroll.showScrollBar();
}
if (e.type == 'mouseout') {
//移出表格
if (e.toTarget && isParent(me.sprite, e.toTarget)) {
return;
}
me.scroll.hideScrollBar();
}
}
});
//设置滚动条的容器sprite
this.scrollSp = new _canvax.default.Display.Sprite({
id: 'scrollSp',
context: {
x: _x,
y: _y,
width: _width,
height: _height
}
});
this.sprite.addChild(this.scrollSp);
}
}, {
key: "initScroll",
value: function initScroll() {
var me = this;
this.scrollSp.removeAllChildren();
var _width = this.induce.context.width;
var _height = this.induce.context.height;
this.scroll = new _scroll.default(_objectSpread(_objectSpread({}, this.scroll), {}, {
viewportHeight: _height,
viewportWidth: _width,
rowMinHeight: this.style.cell.minHeight,
scrollLeft: 0,
scrollTop: 0,
dataLength: this.dataFrame.length,
container: this.scrollSp,
scrollHandle: function scrollHandle(offset) {
var _me$zoom$offset2 = me.zoom.offset(offset),
x = _me$zoom$offset2.x,
y = _me$zoom$offset2.y;
me.graphsView.context.x = x;
me.graphsView.context.y = y;
// 处理固定列和表头的位置同步
me._syncStickyElements();
me.updateLayoutData();
}
}));
}
}, {
key: "_syncStickyElements",
value: function _syncStickyElements(cell) {
var _this$summary;
var scrollState = this.scroll.getState();
// 同步固定列的位置
if (this.leftColSticky > 0) {
var leftOffset = 0;
// 处理水平方向
if (this.graphsView.context.x < this.contentX) {
leftOffset = -this.graphsView.context.x + this.contentX;
// 同步固定列数据和表头的水平位置
this.leftColStickySp.context.x = leftOffset;
this.leftSelectedSp.context.x = leftOffset;
this.fixedColHeaderSp.context.x = leftOffset;
this.summaryLeftColStickySp.context.x = leftOffset;
} else {
this.leftColStickySp.context.x = 0;
this.leftSelectedSp.context.x = 0;
this.fixedColHeaderSp.context.x = 0;
this.summaryLeftColStickySp.context.x = 0;
}
// 处理垂直方向
if (this.graphsView.context.y < this.contentY) {
// 固定列表头需要固定在顶部
if (this.theadSticky) {
this.fixedColHeaderSp.context.y = -this.graphsView.context.y + this.contentY;
}
} else {
this.fixedColHeaderSp.context.y = 0;
}
}
// 同步普通表头位置
if (this.theadSticky) {
if (this.graphsView.context.y < this.contentY) {
this.columnsSp.context.y = -this.graphsView.context.y + this.contentY;
} else {
this.columnsSp.context.y = 0;
}
}
//同步汇总区域的位置
if ((_this$summary = this.summary) !== null && _this$summary !== void 0 && _this$summary.enable) {
var summaryTop = scrollState.viewportHeight - this.graphsView.context.y - this.summary.height;
this.summaryColumnsSp.context.y = summaryTop;
this.summaryLeftColStickySp.context.y = summaryTop;
}
if (cell) {
if (cell.col.colIndex < this.leftColSticky) {
//如果这个
}
}
var _currentCellHighlightRightPopover = this.graphsView.getChildById("_currentCellHighlightRightPopover");
if (_currentCellHighlightRightPopover) {
//如果cell是左侧的固定列单元格,那么x要减去scrollLeft
if (_currentCellHighlightRightPopover.cell.col.colIndex < this.leftColSticky) {
_currentCellHighlightRightPopover.context.x = _currentCellHighlightRightPopover._pos.x + this.scroll.getState().scrollLeft;
}
}
}
}, {
key: "resetData",
value: function resetData(data) {
//数据变化
var me = this;
this.app.dataFrame = this.dataFrame = (0, _tableDataFrame.default)(data);
me.graphsView.context.x = 0;
me.graphsView.context.y = 0;
this.initScroll();
// 处理固定列和表头的位置同步
me._syncStickyElements();
this.draw();
}
}, {
key: "draw",
value: function draw() {
var _this$summary2;
//先更具内容区域的宽高,然后用最小行高,计算出至少要首屏渲染多少条数据,列数据全部都计算,列的数量一般可控,
//首屏至少要渲染这么多条数据
this._layouted = false;
debugger;
this.layoutData = this.getLayoutData();
window.layoutData = this.layoutData;
//第一次预估出来的layoutData会有一部分误差,可以更新一次
this.updateLayoutData();
this._layouted = true;
debugger;
this.renderTable();
var scrollState = this.scroll.getState();
var scrollHeight = (this.dataFrame.list.length - (scrollState.renderedRange.end - scrollState.renderedRange.start + 1)) * this.style.cell.minHeight + this.layoutData.rowData.list.size.height + this.layoutData.rowData.columns.size.height;
if ((_this$summary2 = this.summary) !== null && _this$summary2 !== void 0 && _this$summary2.enable) {
scrollHeight += this.summary.height + 2;
}
this.scroll.setState({
scrollHeight: scrollHeight,
scrollWidth: this.layoutData.rowData.columns.size.width
});
//渲染完后, 计算出来固定行的高 和 固定列的宽,用固定列的高作为top,固定列的width做为left,放一个sprite,用来渲染一些选中单元格的边框等元素
// 计算固定行的高(表头高度)和固定列的宽
var fixedHeaderHeight = this.layoutData.rowData.columns.size.height;
var fixedColWidth = 0;
if (this.leftColSticky > 0 && this.layoutData.rowData.columns.rows.length > 0) {
// 计算固定列的总宽度(取第一行的前N列宽度之和)
var firstHeaderRow = this.layoutData.rowData.columns.rows[0];
for (var i = 0; i < this.leftColSticky; i++) {
var cell = firstHeaderRow.cells[i];
if (cell && cell.size && typeof cell.size.width === 'number') {
fixedColWidth += cell.size.width;
}
}
}
var borderLineWidth = this.style.border.width;
this.selectedSpClipRect.context.x = fixedColWidth + borderLineWidth - 1;
this.selectedSpClipRect.context.y = fixedHeaderHeight + borderLineWidth - 1;
this.selectedSpClipRect.context.width = this.layoutData.rowData.columns.size.width - fixedColWidth;
this.selectedSpClipRect.context.height = scrollState.viewportHeight - fixedHeaderHeight + 1;
//然后设置下左侧固定列的选中层的位置尺寸
this.leftSelectedSpClipRect.context.x = -1;
this.leftSelectedSpClipRect.context.y = fixedHeaderHeight + borderLineWidth - 1;
this.leftSelectedSpClipRect.context.width = fixedColWidth + borderLineWidth + 2;
this.leftSelectedSpClipRect.context.height = scrollState.viewportHeight - fixedHeaderHeight + 1;
this.scroll.hideScrollBar();
this.fire("complete");
}
}, {
key: "renderTable",
value: function renderTable() {
var _this2 = this;
//先把几个容易的原来可能的单元格都清除掉
this.fixedColHeaderSp.removeAllChildren();
this.columnsSp.removeAllChildren();
this.leftColStickySp.removeAllChildren();
this.listSp.removeAllChildren();
this.selectedSp.removeAllChildren();
this.leftSelectedSp.removeAllChildren();
this.summaryColumnsSp.removeAllChildren();
this.summaryLeftColStickySp.removeAllChildren();
//先绘制columns
this.layoutData.rowData.columns.rows.forEach(function (row, rowIndex) {
row.cells.forEach(function (cell, colIndex) {
if (cell.cellData.isEmpty) {
return;
}
var cellSp = _this2._createCellSp(cell);
if (colIndex < _this2.leftColSticky) {
//先把固定列的colSticky设置为true
cell.col.colSticky = true;
// 固定列的表头放入专门的容器
_this2.fixedColHeaderSp.addChild(cellSp);
} else {
_this2.columnsSp.addChild(cellSp);
}
// 创建完单元格后,检查并应用正确的样式(包括选中状态)
_this2._setCellStyle(cell);
});
});
var scrollState = this.scroll.getState();
for (var i = scrollState.renderedRange.start; i <= scrollState.renderedRange.end; i++) {
var row = this.layoutData.rowData.list.rows[i];
this.drawRow(row);
}
//绘制汇总区域
//循环layoutData.colData,如果有固定列, 固定列的合并渲染到summaryLeftColStickySp, 普通列的合并渲染到summaryColumnsSp
this.layoutData.rowData.summary.rows.forEach(function (row, rowIndex) {
row.cells.forEach(function (cell, colIndex) {
if (cell.cellData.isEmpty) {
return;
}
var cellSp = _this2._createCellSp(cell);
if (colIndex < _this2.leftColSticky) {
//先把固定列的colSticky设置为true
cell.col.colSticky = true;
// 固定列的表头放入专门的容器
_this2.summaryLeftColStickySp.addChild(cellSp);
} else {
_this2.summaryColumnsSp.addChild(cellSp);
}
// 创建完单元格后,检查并应用正确的样式(包括选中状态)
_this2._setCellStyle(cell);
});
});
}
}, {
key: "_getTargetCell",
value: function _getTargetCell(point) {
var me = this;
var targetCell = null;
var scrollState = me.scroll.getState();
//先查是不是点击了某个列头,如果是的话,则返回对应的列头
for (var i = 0; i < me.layoutData.rowData.columns.rows.length; i++) {
var row = me.layoutData.rowData.columns.rows[i];
if (!row) continue;
if (point.y - scrollState.scrollTop < row.position.y || point.y - scrollState.scrollTop > row.position.y + row.size.height) continue;
//遍历行内的所有单元格
var _iterator = _createForOfIteratorHelper(row.cells),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var cell = _step.value;
var cellPosition = _objectSpread({}, cell.position);
if (me.leftColSticky > 0 && cell.col.colIndex < me.leftColSticky) {
cellPosition.x += scrollState.scrollLeft;
}
cellPosition.y += scrollState.scrollTop;
//检查点是否在当前cell的矩形范围内
if (point.x >= cellPosition.x && point.x <= cellPosition.x + cell.size.width && point.y >= cellPosition.y && point.y <= cellPosition.y + cell.size.height) {
targetCell = cell;
break;
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
if (targetCell) break;
}
if (!targetCell && scrollState !== null && scrollState !== void 0 && scrollState.renderedRange) {
var _scrollState$rendered = scrollState.renderedRange,
start = _scrollState$rendered.start,
end = _scrollState$rendered.end;
//遍历可视范围内的所有行
for (var _i = start; _i <= end; _i++) {
var _row3 = me.layoutData.rowData.list.rows[_i];
if (!_row3) continue;
if (point.y < _row3.position.y || point.y > _row3.position.y + _row3.size.height) continue;
//遍历行内的所有单元格
var _iterator2 = _createForOfIteratorHelper(_row3.cells),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var _cell2 = _step2.value;
var _cellPosition = _objectSpread({}, _cell2.position);
if (me.leftColSticky > 0 && _cell2.col.colIndex < me.leftColSticky) {
_cellPosition.x += scrollState.scrollLeft;
}
//检查点是否在当前cell的矩形范围内
if (point.x >= _cellPosition.x && point.x <= _cellPosition.x + _cell2.size.width && point.y >= _cellPosition.y && point.y <= _cellPosition.y + _cell2.size.height) {
targetCell = _cell2;
break;
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
if (targetCell) break;
}
}
if (targetCell && targetCell.cellData.isEmpty) {
targetCell = targetCell.cellData.spanOriginCell || targetCell;
}
return targetCell;
}
}, {
key: "checkCellIsSelected",
value: function checkCellIsSelected(cell) {
/**这个检查单元格是否已经被选中的方法有三种情况要判断, 如果this.selectedCells中的所有type为cell的选中项目中有value和这个cell.id相等的,就判断是选中, 如果type是row的话,要检测这个cell.row.id是否存在,有也认为是被选中了(选中行),如果有type是col的数据,要检测这个cell.col.id是否存在,有存在的也认为是被选中了(列选中) */
//如果没有选中数据,直接返回false
var isSelected = false;
//if( !(this.selected.cellIds.length == 0 && this.selected.row.length == 0 && this.selected.col.length == 0) ){
if ((0, _typeof2.default)(cell) != 'object') {
cell = this.getCellById(cell);
}
//先检查是否有全选行的选中
//let checkedAllItem = this.selected.row.find(item => item.type == 'allrows' && item.checkedAll)
if (this.selected.allrows.checkedAll && !this.selected.allrows.excludeRowIds.includes(cell.row.id)) {
isSelected = true;
return isSelected;
}
// if( this.selected.allrows.checkedAll
// && ( !checkedAllItem.excludeRowIds || !checkedAllItem.excludeRowIds.includes( cell.row.id )) ){
// isSelected = true;
// return isSelected;
// }
//先检查列选中
for (var i = 0; i < this.selected.col.length; i++) {
var _selectedCol$excludeC;
var selectedCol = this.selected.col[i];
if (cell.col.fieldCellIdStack.includes(selectedCol.colCellId) && (!selectedCol.excludeCellIds || !((_selectedCol$excludeC = selectedCol.excludeCellIds) !== null && _selectedCol$excludeC !== void 0 && _selectedCol$excludeC.includes(cell.id)))) {
var activeCellIndInFields = cell.col.fieldCellIdStack.indexOf(this.activeCellId);
if (cell.type == 'th' && activeCellIndInFields > -1) {
//如果activeCellId是当前单元格的父级,则认为是选中
var cellIdIndex = cell.col.fieldCellIdStack.indexOf(cell.id);
if (cellIdIndex >= activeCellIndInFields) {
isSelected = true;
return isSelected;
}
} else {
isSelected = true;
return isSelected;
}
}
}
//再检查行选中
for (var _i2 = 0; _i2 < this.selected.row.length; _i2++) {
var _selectedRow$excludeC;
var selectedRow = this.selected.row[_i2];
if (selectedRow.rowId == cell.row.id && !((_selectedRow$excludeC = selectedRow.excludeCellIds) !== null && _selectedRow$excludeC !== void 0 && _selectedRow$excludeC.includes(cell.id))) {
isSelected = true;
return isSelected;
}
}
//最后检查单元格选中
if (this.selected.cellIds.includes(cell.id)) {
isSelected = true;
return isSelected;
}
//}
}
}, {
key: "checkRowIsSelected",
value: function checkRowIsSelected(row) {
return this.selected.row.find(function (item) {
return item.type == 'row' && item.rowId == row.id;
}) || this.selected.allrows.checkedAll && !this.selected.allrows.excludeRowIds.includes(row.id);
}
}, {
key: "unselect",
value: function unselect(list) {
var _this3 = this;
if (!this.selected.enabled) {
return;
}
if (list == undefined) {
//没有传入参数,则清空所有选中
this.selected.cellIds = [];
this.selected.row = [];
this.selected.col = [];
this.selected.allrows.excludeRowIds = [];
this.selected.allrows.checkedAll = false;
} else {
if (!Array.isArray(list)) {
list = [list];
}
list.forEach(function (item) {
if (item.type == 'col') {
//删除this.selected.col中对应的item
_this3.selected.col.splice(_this3.selected.col.indexOf(_this3.selected.col.find(function (col) {
return col.colCellId == item.colCellId;
})), 1);
return;
}
if (item.type == 'row') {
//删除this.selected.row中对应的item
_this3.selected.row.splice(_this3.selected.row.indexOf(_this3.selected.row.find(function (row) {
return row.rowId == item.rowId;
})), 1);
return;
}
var cell;
if ((0, _typeof2.default)(item) != 'object') {
cell = _this3.getCellById(item);
} else {
cell = item;
}
if (!_this3.selected.cellIds.includes(cell.id)) {
return;
}
_this3.selected.cellIds.splice(_this3.selected.cellIds.indexOf(cell.id), 1);
});
}
this.refreshAllCellStyle();
this.action({
type: 'unSelect',
info: {
selected: this.selected
}
});
}
}, {
key: "select",
value: function select(list) {
var _this4 = this;
if (!this.selected.enabled) {
return;
}
if (!Array.isArray(list)) {
list = [list];
}
list.forEach(function (item) {
if (item.type == 'allrows') {
Object.assign(_this4.selected.allrows, item);
return;
}
if (item.type == 'col') {
if (!_this4.selected.col.find(function (col) {
return col.colCellId == item.colCellId;
})) {
_this4.selected.col.push(item);
}
return;
}
if (item.type == 'row') {
if (!_this4.selected.row.find(function (row) {
return row.rowId == item.rowId;
})) {
_this4.selected.row.push(item);
}
return;
}
//下面都是select单元格的逻辑
if (item.type == 'cell') {
var newIds = item.cellIds;