| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435 |
- var __values = (this && this.__values) || function(o) {
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
- if (m) return m.call(o);
- if (o && typeof o.length === "number") return {
- next: function () {
- if (o && i >= o.length) o = void 0;
- return { value: o && o[i++], done: !o };
- }
- };
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
- };
- import { throttle } from 'lodash-es';
- var MiniMap = /** @class */ (function () {
- function MiniMap(_a) {
- var _this = this;
- var lf = _a.lf, LogicFlow = _a.LogicFlow, options = _a.options;
- this.lf = null;
- this.container = null;
- this.miniMapWrap = null;
- this.miniMapContainer = null;
- this.lfMap = null;
- this.viewport = null;
- this.width = 150;
- this.height = 220;
- this.leftPosition = undefined;
- this.topPosition = undefined;
- this.rightPosition = undefined;
- this.bottomPosition = undefined;
- this.miniMapWidth = 450;
- this.miniMapHeight = 660;
- this.viewPortTop = 0;
- this.viewPortLeft = 0;
- this.startPosition = null;
- this.viewPortScale = 1;
- this.viewPortWidth = 150;
- this.viewPortHeight = 75;
- this.resetDataX = 0;
- this.resetDataY = 0;
- this.LogicFlow = null;
- this.isShow = false;
- this.isShowHeader = true;
- this.isShowCloseIcon = true;
- this.dragging = false;
- this.disabledPlugins = ['miniMap', 'control', 'selectionSelect'];
- /**
- * 显示mini map
- */
- this.show = function (leftPosition, topPosition) {
- _this.setView();
- if (!_this.isShow) {
- _this.createMiniMap(leftPosition, topPosition);
- }
- _this.isShow = true;
- };
- /**
- * 隐藏mini map
- */
- this.hide = function () {
- if (_this.isShow) {
- _this.removeMiniMap();
- }
- _this.isShow = false;
- };
- this.reset = function () {
- _this.lf.resetTranslate();
- _this.lf.resetZoom();
- _this.hide();
- _this.show();
- };
- this.startDrag = function (e) {
- document.addEventListener('mousemove', _this.drag);
- document.addEventListener('mouseup', _this.drop);
- _this.startPosition = {
- x: e.x,
- y: e.y,
- };
- };
- this.moveViewport = function (top, left) {
- var viewStyle = _this.viewport.style;
- _this.viewPortTop = top;
- _this.viewPortLeft = left;
- viewStyle.top = _this.viewPortTop + "px";
- viewStyle.left = _this.viewPortLeft + "px";
- };
- this.drag = function (e) {
- _this.dragging = true;
- var top = _this.viewPortTop + e.y - _this.startPosition.y;
- var left = _this.viewPortLeft + e.x - _this.startPosition.x;
- _this.moveViewport(top, left);
- _this.startPosition = {
- x: e.x,
- y: e.y,
- };
- var centerX = (_this.viewPortLeft + _this.viewPortWidth / 2)
- / _this.viewPortScale;
- var centerY = (_this.viewPortTop + _this.viewPortHeight / 2)
- / _this.viewPortScale;
- _this.lf.focusOn({
- coordinate: {
- x: centerX + _this.resetDataX,
- y: centerY + _this.resetDataY,
- },
- });
- };
- this.drop = function () {
- document.removeEventListener('mousemove', _this.drag);
- document.removeEventListener('mouseup', _this.drop);
- var top = _this.viewPortTop;
- var left = _this.viewPortLeft;
- if (_this.viewPortLeft > _this.width) {
- left = _this.width - _this.viewPortWidth;
- }
- if (_this.viewPortTop > _this.height) {
- top = _this.height - _this.viewPortHeight;
- }
- if (_this.viewPortLeft < -_this.width) {
- left = 0;
- }
- if (_this.viewPortTop < -_this.height) {
- top = 0;
- }
- _this.moveViewport(top, left);
- };
- this.mapClick = function (e) {
- if (_this.dragging) {
- _this.dragging = false;
- }
- else {
- var layerX = e.layerX, layerY = e.layerY;
- var ViewPortCenterX = layerX;
- var ViewPortCenterY = layerY;
- var graphData = _this.lf.getGraphRawData();
- var _a = _this.getBounds(graphData), left = _a.left, top_1 = _a.top;
- var resetGraphX = left + ViewPortCenterX / _this.viewPortScale;
- var resetGraphY = top_1 + ViewPortCenterY / _this.viewPortScale;
- _this.lf.focusOn({ coordinate: { x: resetGraphX, y: resetGraphY } });
- }
- };
- this.lf = lf;
- if (options && options.MiniMap) {
- this.setOption(options);
- }
- this.miniMapWidth = lf.graphModel.width;
- this.miniMapHeight = (lf.graphModel.width * this.height) / this.width;
- this.LogicFlow = LogicFlow;
- this.initMiniMap();
- }
- MiniMap.prototype.render = function (lf, container) {
- var _this = this;
- this.container = container;
- this.lf.on('history:change', function () {
- if (_this.isShow) {
- _this.setView();
- }
- });
- this.lf.on('graph:transform', throttle(function () {
- // 小地图已展示,并且没有拖拽小地图视口
- if (_this.isShow && !_this.dragging) {
- _this.setView();
- }
- }, 300));
- };
- MiniMap.prototype.init = function (option) {
- this.disabledPlugins = this.disabledPlugins.concat(option.disabledPlugins || []);
- };
- MiniMap.prototype.setOption = function (options) {
- var _a = options.MiniMap, _b = _a.width, width = _b === void 0 ? 150 : _b, _c = _a.height, height = _c === void 0 ? 220 : _c, _d = _a.isShowHeader, isShowHeader = _d === void 0 ? true : _d, _e = _a.isShowCloseIcon, isShowCloseIcon = _e === void 0 ? true : _e, _f = _a.leftPosition, leftPosition = _f === void 0 ? 0 : _f, _g = _a.topPosition, topPosition = _g === void 0 ? 0 : _g, rightPosition = _a.rightPosition, bottomPosition = _a.bottomPosition;
- this.width = width;
- this.height = height;
- this.isShowHeader = isShowHeader;
- this.isShowCloseIcon = isShowCloseIcon;
- this.viewPortWidth = width;
- this.leftPosition = leftPosition;
- this.topPosition = topPosition;
- this.rightPosition = rightPosition;
- this.bottomPosition = bottomPosition;
- };
- MiniMap.prototype.initMiniMap = function () {
- var miniMapWrap = document.createElement('div');
- miniMapWrap.className = 'lf-mini-map-graph';
- miniMapWrap.style.width = this.width + 4 + "px";
- miniMapWrap.style.height = this.height + "px";
- this.lfMap = new this.LogicFlow({
- width: this.lf.graphModel.width,
- height: (this.lf.graphModel.width * this.height) / this.width,
- container: miniMapWrap,
- isSilentMode: true,
- stopZoomGraph: true,
- stopScrollGraph: true,
- stopMoveGraph: true,
- hideAnchors: true,
- hoverOutline: false,
- disabledPlugins: this.disabledPlugins,
- });
- // minimap中禁用adapter。
- this.lfMap.adapterIn = function (a) { return a; };
- this.lfMap.adapterOut = function (a) { return a; };
- this.miniMapWrap = miniMapWrap;
- this.createViewPort();
- miniMapWrap.addEventListener('click', this.mapClick);
- };
- MiniMap.prototype.createMiniMap = function (left, top) {
- var miniMapContainer = document.createElement('div');
- miniMapContainer.appendChild(this.miniMapWrap);
- if (typeof left !== 'undefined' || typeof top !== 'undefined') {
- miniMapContainer.style.left = (left || 0) + "px";
- miniMapContainer.style.top = (top || 0) + "px";
- }
- else {
- if (typeof this.rightPosition !== 'undefined') {
- miniMapContainer.style.right = this.rightPosition + "px";
- }
- else if (typeof this.leftPosition !== 'undefined') {
- miniMapContainer.style.left = this.leftPosition + "px";
- }
- if (typeof this.bottomPosition !== 'undefined') {
- miniMapContainer.style.bottom = this.bottomPosition + "px";
- }
- else if (typeof this.topPosition !== 'undefined') {
- miniMapContainer.style.top = this.topPosition + "px";
- }
- }
- miniMapContainer.style.position = 'absolute';
- miniMapContainer.className = 'lf-mini-map';
- if (!this.isShowCloseIcon) {
- miniMapContainer.classList.add('lf-mini-map-no-close-icon');
- }
- if (!this.isShowHeader) {
- miniMapContainer.classList.add('lf-mini-map-no-header');
- }
- this.container.appendChild(miniMapContainer);
- this.miniMapWrap.appendChild(this.viewport);
- var header = document.createElement('div');
- header.className = 'lf-mini-map-header';
- header.innerText = MiniMap.headerTitle;
- miniMapContainer.appendChild(header);
- var close = document.createElement('span');
- close.className = 'lf-mini-map-close';
- close.addEventListener('click', this.hide);
- miniMapContainer.appendChild(close);
- this.miniMapContainer = miniMapContainer;
- };
- MiniMap.prototype.removeMiniMap = function () {
- this.container.removeChild(this.miniMapContainer);
- };
- /**
- * 计算所有图形一起,占领的区域范围。
- * @param data
- */
- MiniMap.prototype.getBounds = function (data) {
- var left = 0;
- var right = this.miniMapWidth;
- var top = 0;
- var bottom = this.miniMapHeight;
- var nodes = data.nodes;
- if (nodes && nodes.length > 0) {
- // 因为获取的节点不知道真实的宽高,这里需要补充一点数值
- nodes.forEach(function (_a) {
- var x = _a.x, y = _a.y, _b = _a.width, width = _b === void 0 ? 200 : _b, _c = _a.height, height = _c === void 0 ? 200 : _c;
- var nodeLeft = x - width / 2;
- var nodeRight = x + width / 2;
- var nodeTop = y - height / 2;
- var nodeBottom = y + height / 2;
- left = nodeLeft < left ? nodeLeft : left;
- right = nodeRight > right ? nodeRight : right;
- top = nodeTop < top ? nodeTop : top;
- bottom = nodeBottom > bottom ? nodeBottom : bottom;
- });
- }
- return {
- left: left,
- top: top,
- bottom: bottom,
- right: right,
- };
- };
- /**
- * 将负值的平移转换为正值。
- * 保证渲染的时候,minimap能完全展示。
- * 获取将画布所有元素平移到0,0开始时,所有节点数据
- */
- MiniMap.prototype.resetData = function (data) {
- var nodes = data.nodes, edges = data.edges;
- var left = 0;
- var top = 0;
- if (nodes && nodes.length > 0) {
- // 因为获取的节点不知道真实的宽高,这里需要补充一点数值
- nodes.forEach(function (_a) {
- var x = _a.x, y = _a.y, _b = _a.width, width = _b === void 0 ? 200 : _b, _c = _a.height, height = _c === void 0 ? 200 : _c;
- var nodeLeft = x - width / 2;
- var nodeTop = y - height / 2;
- left = nodeLeft < left ? nodeLeft : left;
- top = nodeTop < top ? nodeTop : top;
- });
- if (left < 0 || top < 0) {
- this.resetDataX = left;
- this.resetDataY = top;
- nodes.forEach(function (node) {
- node.x = node.x - left;
- node.y = node.y - top;
- if (node.text) {
- node.text.x = node.text.x - left;
- node.text.y = node.text.y - top;
- }
- });
- edges.forEach(function (edge) {
- if (edge.startPoint) {
- edge.startPoint.x = edge.startPoint.x - left;
- edge.startPoint.y = edge.startPoint.y - top;
- }
- if (edge.endPoint) {
- edge.endPoint.x = edge.endPoint.x - left;
- edge.endPoint.y = edge.endPoint.y - top;
- }
- if (edge.text) {
- edge.text.x = edge.text.x - left;
- edge.text.y = edge.text.y - top;
- }
- if (edge.pointsList) {
- edge.pointsList.forEach(function (point) {
- point.x = point.x - left;
- point.y = point.y - top;
- });
- }
- });
- }
- }
- return data;
- };
- /**
- * 显示导航
- * 显示视口范围
- * 1. 基于画布的范围比例,设置视口范围比例。宽度默认为导航宽度。
- */
- MiniMap.prototype.setView = function () {
- var e_1, _a;
- // 1. 获取到图中所有的节点中的位置,将其偏移到原点开始(避免节点位置为负的时候无法展示问题)。
- var graphData = this.lf.getGraphRawData();
- var data = this.resetData(graphData);
- // 由于随时都会有新节点注册进来,需要同步将注册的
- var viewMap = this.lf.viewMap;
- var modelMap = this.lf.graphModel.modelMap;
- var minimapViewMap = this.lfMap.viewMap;
- try {
- // todo: no-restricted-syntax
- for (var _b = __values(viewMap.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
- var key = _c.value;
- if (!minimapViewMap.has(key)) {
- this.lfMap.setView(key, viewMap.get(key));
- this.lfMap.graphModel.modelMap.set(key, modelMap.get(key));
- }
- }
- }
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
- finally {
- try {
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
- }
- finally { if (e_1) throw e_1.error; }
- }
- this.lfMap.render(data);
- // 2. 将偏移后的数据渲染到minimap画布上
- // 3. 计算出所有节点在一起的边界。
- var _d = this.getBounds(data), left = _d.left, top = _d.top, right = _d.right, bottom = _d.bottom;
- // 4. 计算所有节点的边界与minimap看板的边界的比例.
- var realWidthScale = this.width / (right - left);
- var realHeightScale = this.height / (bottom - top);
- // 5. 取比例最小的值,将渲染的画布缩小对应比例。
- var innerStyle = this.miniMapWrap.firstChild.style;
- var scale = Math.min(realWidthScale, realHeightScale);
- innerStyle.transform = "matrix(" + scale + ", 0, 0, " + scale + ", 0, 0)";
- innerStyle.transformOrigin = 'left top';
- innerStyle.height = bottom - Math.min(top, 0) + "px";
- innerStyle.width = right - Math.min(left, 0) + "px";
- this.viewPortScale = scale;
- this.setViewPort(scale, {
- left: left,
- top: top,
- right: right,
- bottom: bottom,
- });
- };
- // 设置视口
- MiniMap.prototype.setViewPort = function (scale, _a) {
- var left = _a.left, right = _a.right, top = _a.top, bottom = _a.bottom;
- var viewStyle = this.viewport.style;
- viewStyle.width = this.viewPortWidth + "px";
- viewStyle.height = (this.viewPortWidth) / (this.lf.graphModel.width / this.lf.graphModel.height) + "px";
- var _b = this.lf.getTransform(), TRANSLATE_X = _b.TRANSLATE_X, TRANSLATE_Y = _b.TRANSLATE_Y, SCALE_X = _b.SCALE_X, SCALE_Y = _b.SCALE_Y;
- var realWidth = right - left;
- // 视口宽 = 小地图宽 / (所有元素一起占据的真实宽 / 绘布宽)
- var viewPortWidth = (this.width) / (realWidth / this.lf.graphModel.width);
- // 实际视口宽 = 小地图宽 * 占宽度比例
- var realViewPortWidth = this.width * (viewPortWidth / this.width);
- var graphRatio = (this.lf.graphModel.width / this.lf.graphModel.height);
- // 视口实际高 = 视口实际宽 / (绘布宽 / 绘布高)
- var realViewPortHeight = realViewPortWidth / graphRatio;
- var graphData = this.lf.getGraphRawData();
- var _c = this.getBounds(graphData), graphLeft = _c.left, graphTop = _c.top;
- var viewportLeft = graphLeft;
- var viewportTop = graphTop;
- viewportLeft += TRANSLATE_X / SCALE_X;
- viewportTop += TRANSLATE_Y / SCALE_Y;
- this.viewPortTop = viewportTop > 0 ? 0 : (-viewportTop * scale);
- this.viewPortLeft = viewportLeft > 0 ? 0 : (-viewportLeft * scale);
- this.viewPortWidth = realViewPortWidth;
- this.viewPortHeight = realViewPortHeight;
- viewStyle.top = this.viewPortTop + "px";
- viewStyle.left = this.viewPortLeft + "px";
- viewStyle.width = realViewPortWidth / SCALE_X + "px";
- viewStyle.height = realViewPortHeight / SCALE_Y + "px";
- };
- // 预览视窗
- MiniMap.prototype.createViewPort = function () {
- var div = document.createElement('div');
- div.className = 'lf-minimap-viewport';
- div.addEventListener('mousedown', this.startDrag);
- this.viewport = div;
- };
- MiniMap.pluginName = 'miniMap';
- MiniMap.width = 150;
- MiniMap.height = 220;
- MiniMap.viewPortWidth = 150;
- MiniMap.viewPortHeight = 75;
- MiniMap.isShowHeader = true;
- MiniMap.isShowCloseIcon = true;
- MiniMap.leftPosition = 0;
- MiniMap.topPosition = 0;
- MiniMap.rightPosition = null;
- MiniMap.bottomPosition = null;
- MiniMap.headerTitle = '导航';
- return MiniMap;
- }());
- export default MiniMap;
- export { MiniMap };
|