UNPKG

chartx

Version:

Data Visualization Chart Library

284 lines (269 loc) 9.41 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = _default; var _canvax = _interopRequireDefault(require("canvax")); /** * @fileOverview 表格虚拟滚动控制器 * @author litao.lt@alibaba-in.com * @version 1.0 */ var Rect = _canvax.default.Shapes.Rect; function _default() { var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; // 当前滚动位置 var scrollTop = opt.scrollTop || 0; var scrollLeft = opt.scrollLeft || 0; // 总可滚动区域尺寸 var scrollHeight = 0; var scrollWidth = 0; // 可视区域尺寸 var viewportHeight = opt.viewportHeight || 0; var viewportWidth = opt.viewportWidth || 0; // 行高和缓冲区配置 var rowMinHeight = opt.rowMinHeight || 40; // 默认最小行高 var bufferSize = opt.bufferSize || 0; // 可视区域上下额外渲染的行数 var dataLength = opt.dataLength || 0; // 数据总长度 var viewportHeightShowRowsCount = Math.ceil(viewportHeight / rowMinHeight); // 当前已渲染的行范围 var renderedRange = { start: 0, end: Math.min(viewportHeightShowRowsCount + bufferSize, dataLength) - 1 }; var container = opt.container || null; var rightScrollBar, bottomScrollBar; var barMinLength = 10; var barLineWidth = 6; var scrollHandle = opt.scrollHandle || function () { return { x: 0, y: 0 }; }; if (container) { //添加一个右边的scrollBar 和 下面的scrollBar var x = container.context.width - barLineWidth; rightScrollBar = new Rect({ id: 'rightScrollBar', dragEnabled: true, hoverClone: false, context: { cursor: 'pointer', x: x, y: 0, width: barLineWidth, height: barMinLength, fillStyle: "#999", fillAlpha: 0.6, radius: [barLineWidth / 2, barLineWidth / 2, barLineWidth / 2, barLineWidth / 2], visible: false } }); rightScrollBar.hover(function () { if (scrollHeight <= viewportHeight) { return; } rightScrollBar.context.width = barLineWidth + 2; rightScrollBar.context.x = x - 2; }, function () { if (scrollHeight <= viewportHeight) { return; } rightScrollBar.context.width = barLineWidth; rightScrollBar.context.x = x; }); rightScrollBar.on('draging', function () { rightScrollBar.context.x = x - 2; if (rightScrollBar.context.y < 0) { rightScrollBar.context.y = 0; } if (rightScrollBar.context.y + rightScrollBar.context.height > viewportHeight) { rightScrollBar.context.y = viewportHeight - rightScrollBar.context.height; } //重新计算最新的scrollTop var preScrollTop = scrollTop; scrollTop = parseInt(rightScrollBar.context.y * (scrollHeight - viewportHeight) / (viewportHeight - rightScrollBar.context.height)); scrollHandle({ x: 0, y: preScrollTop - scrollTop }); }); container.addChild(rightScrollBar); var y = container.context.height - barLineWidth; bottomScrollBar = new Rect({ id: 'bottomScrollBar', dragEnabled: true, hoverClone: false, context: { cursor: 'pointer', x: 0, y: y, width: barMinLength, height: barLineWidth, fillStyle: "#999", fillAlpha: 0.6, radius: [barLineWidth / 2, barLineWidth / 2, barLineWidth / 2, barLineWidth / 2], visible: false } }); bottomScrollBar.hover(function () { if (scrollWidth <= viewportWidth) { return; } bottomScrollBar.context.height = barLineWidth + 2; bottomScrollBar.context.y = y - 2; }, function () { if (scrollWidth <= viewportWidth) { return; } bottomScrollBar.context.height = barLineWidth; bottomScrollBar.context.y = y; }); bottomScrollBar.on('draging', function () { bottomScrollBar.context.y = y - 2; if (bottomScrollBar.context.x < 0) { bottomScrollBar.context.x = 0; } if (bottomScrollBar.context.x + bottomScrollBar.context.width > viewportWidth) { bottomScrollBar.context.x = viewportWidth - bottomScrollBar.context.width; } //重新计算最新的scrollLeft var preScrollLeft = scrollLeft; scrollLeft = parseInt(bottomScrollBar.context.x * (scrollWidth - viewportWidth) / (viewportWidth - bottomScrollBar.context.width)); scrollHandle({ x: preScrollLeft - scrollLeft, y: 0 }); }); container.addChild(bottomScrollBar); } var updateScrollBar = function updateScrollBar() { // 修正滚动条位置的计算公式 // 纵向滚动条(rightScrollBar)的y坐标 if (rightScrollBar && scrollHeight) { if (scrollHeight <= viewportHeight) { rightScrollBar.context.visible = false; } else { var scrollBarHeight = viewportHeight * viewportHeight / scrollHeight; if (scrollBarHeight < barMinLength) { scrollBarHeight = barMinLength; } var maxScrollTop = Math.max(1, scrollHeight - viewportHeight); var maxBarY = viewportHeight - scrollBarHeight; var scrollBarY = 0; if (scrollHeight > viewportHeight) { scrollBarY = scrollTop / maxScrollTop * maxBarY; } else { scrollBarY = 0; } rightScrollBar.context.height = scrollBarHeight; rightScrollBar.context.y = scrollBarY; rightScrollBar.context.visible = true; } } // 横向滚动条(bottomScrollBar)的x坐标 if (bottomScrollBar && scrollWidth) { if (scrollWidth <= viewportWidth) { bottomScrollBar.context.visible = false; } else { var scrollBarWidth = viewportWidth * viewportWidth / scrollWidth; if (scrollBarWidth < barMinLength) { scrollBarWidth = barMinLength; } var maxScrollLeft = Math.max(1, scrollWidth - viewportWidth); var maxBarX = viewportWidth - scrollBarWidth; var scrollBarX = 0; if (scrollWidth > viewportWidth) { scrollBarX = scrollLeft / maxScrollLeft * maxBarX; } else { scrollBarX = 0; } bottomScrollBar.context.width = scrollBarWidth; bottomScrollBar.context.x = scrollBarX; bottomScrollBar.context.visible = true; } } }; // 更新滚动位置 var scrollTo = function scrollTo() { var left = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : scrollLeft; var top = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : scrollTop; // 限制滚动位置在有效范围内 scrollTop = Math.max(0, Math.min(top, scrollHeight - viewportHeight)); scrollLeft = Math.max(0, Math.min(left, scrollWidth - viewportWidth)); updateScrollBar(); return { scrollTop: scrollTop, scrollLeft: scrollLeft, renderedRange: renderedRange }; }; // 更新滚动区域尺寸 var setState = function setState() { var opt = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; if (opt.scrollHeight !== undefined) { scrollHeight = Math.max(0, opt.scrollHeight); updateScrollBar(); } if (opt.scrollWidth !== undefined) { scrollWidth = Math.max(0, opt.scrollWidth); updateScrollBar(); } if (opt.viewportHeight !== undefined) { viewportHeight = Math.max(0, opt.viewportHeight); } if (opt.viewportWidth !== undefined) { viewportWidth = Math.max(0, opt.viewportWidth); } if (opt.dataLength !== undefined) { dataLength = Math.max(0, opt.dataLength); } if (opt.rowMinHeight !== undefined) { rowMinHeight = Math.max(0, opt.rowMinHeight); } // 更新尺寸后确保滚动位置仍然有效 return scrollTo(); }; // 获取当前状态 var getState = function getState() { return { scrollTop: scrollTop, scrollLeft: scrollLeft, scrollHeight: scrollHeight, scrollWidth: scrollWidth, viewportHeight: viewportHeight, viewportWidth: viewportWidth, rowMinHeight: rowMinHeight, bufferSize: bufferSize, renderedRange: renderedRange }; }; var checkRowPositionIsInViewport = function checkRowPositionIsInViewport(row) { if (scrollTop == 482) {} //console.log( scrollTop ) if (!row) { return false; } var rowTop = row.position.y - scrollTop; var rowBottom = rowTop + row.size.height; //return rowBottom > - bufferSize * rowMinHeight && rowTop < viewportHeight + bufferSize*rowMinHeight return !(rowBottom < -bufferSize * rowMinHeight || rowTop > viewportHeight + bufferSize * rowMinHeight); }; var showScrollBar = function showScrollBar() { rightScrollBar.context.visible = true; bottomScrollBar.context.visible = true; }; var hideScrollBar = function hideScrollBar() { rightScrollBar.context.visible = false; bottomScrollBar.context.visible = false; }; // 暴露公共方法 this.scrollTo = scrollTo; this.setState = setState; this.getState = getState; this.showScrollBar = showScrollBar; this.hideScrollBar = hideScrollBar; this.checkRowPositionIsInViewport = checkRowPositionIsInViewport; }