UNPKG

butterfly-dag

Version:

一个基于数据驱动的节点式编排组件库,让你有方便快捷定制可视化流程图表

215 lines (187 loc) 6.14 kB
'use strict'; const $ = require('jquery'); const _ = require('lodash'); class GuidelineService { constructor(opts) { this.root = opts.root; this.canvas = opts.canvas; this.dom = null; this.cxt = null; this.isActive = false; this.limitNum = opts.limitNum; this.theme = { lineColor: '#9fd1ff', lineWidth: 1 }; } _resize() { this.canvasHeight = $(this.root).height(); this.canvasWidth = $(this.root).width(); $(this.guideLineCanvas).attr('width', this.canvasWidth); $(this.guideLineCanvas).attr('height', this.canvasHeight); } create(options = {}) { this.theme = _.merge(this.theme, options.theme || {}); if (!this.dom) { this.dom = $('<div class="butterfly-gird-canvas-wrapper"></div>')[0]; this.guideLineCanvas = $('<canvas class="butterfly-guideline-canvas"></canvas>')[0]; this._resize(); $(this.guideLineCanvas).appendTo(this.dom); $(this.dom).appendTo(this.root); } this.cxt = this.guideLineCanvas.getContext('2d'); this.cxt.strokeStyle = this.theme.lineColor || '#000'; this.cxt.lineWidth = this.theme.lineWidth || 1; this.isActive = true; } guidLine( moveTo = [0, 0], lineTo = [0, 0] ) { const process = (coord) => { return Math.floor(coord) + 0.5; }; this.cxt.beginPath(); this.cxt.moveTo(process(moveTo[0]), process(moveTo[1])); this.cxt.lineTo(process(lineTo[0]), process(lineTo[1])); this.cxt.stroke(); this.cxt.closePath(); } draw(item, type) { this.cxt.clearRect(0, 0, this.canvasWidth, this.canvasHeight); let _left = parseInt(item.left); let _right = parseInt(item.left + item.getWidth()); let _top = parseInt(item.top); let _bottom = parseInt(item.top + item.getHeight()); let _leftDis = Infinity; let _rightDis = Infinity; let _topDis = Infinity; let _bottomDis = Infinity; let _leftItem = null; let _rightItem = null; let _topItem = null; let _bottomItem = null; let groups = this.canvas.groups; let nodes = this.canvas.nodes; groups.forEach((_group) => { if (type === 'group' && item.id === _group.id) { return; } let _groupLeft = parseInt(_group.left); let _groupRight = parseInt(_group.left + _group.getWidth()); let _groupTop = parseInt(_group.top); let _groupBottom = parseInt(_group.top + _group.getHeight()); // 向左对齐的元素 if (_left === _groupLeft) { if (Math.abs(_groupTop - _top) < _topDis) { _topDis = Math.abs(_groupTop - _top); _leftItem = _group; } } // 向右对齐的元素 if (_right === _groupRight) { if (Math.abs(_groupBottom - _bottom) < _bottomDis) { _bottomDis = Math.abs(_groupBottom - _bottom); _rightItem = _group; } } // 向上对齐的元素 if (_top === _groupTop) { if (Math.abs(_groupLeft - _left) < _leftDis) { _leftDis = Math.abs(_groupLeft - _left); _topItem = _group; } } // 向下对齐的元素 if (_bottom === _groupBottom) { if (Math.abs(_groupRight - _right) < _rightDis) { _rightDis = Math.abs(_groupRight - _right); _bottomItem = _group; } } }); nodes.forEach((_node) => { if (type === 'node' && item.id === _node.id) { return; } let _nodeLeft = parseInt(_node.left); let _nodeRight = parseInt(_node.left + _node.getWidth()); let _nodeTop = parseInt(_node.top); let _nodeBottom = parseInt(_node.top + _node.getHeight()); if (_node._group) { _nodeLeft += _node._group.left; _nodeRight += _node._group.left; _nodeTop += _node._group.top; _nodeBottom += _node._group.top; } // 向左对齐的元素 if (_left === _nodeLeft) { if (Math.abs(_nodeTop - _top) < _topDis) { _topDis = Math.abs(_nodeTop - _top); _leftItem = _node; } } // 向右对齐的元素 if (_right === _nodeRight) { if (Math.abs(_nodeBottom - _bottom) < _bottomDis) { _bottomDis = Math.abs(_nodeBottom - _bottom); _rightItem = _node; } } // 向上对齐的元素 if (_top === _nodeTop) { if (Math.abs(_nodeLeft - _left) < _leftDis) { _leftDis = Math.abs(_nodeLeft - _left); _topItem = _node; } } // 向下对齐的元素 if (_bottom === _nodeBottom) { if (Math.abs(_nodeRight - _right) < _rightDis) { _rightDis = Math.abs(_nodeRight - _right); _bottomItem = _node; } } }); if (_leftItem) { let startY = _top > _leftItem.top ? _leftItem.top : _top; let endY = _top > _leftItem.top ? _bottom : _leftItem.top + _leftItem.getHeight(); this.guidLine([_left, startY], [_left, endY]); } if (_rightItem) { let startY = _top > _rightItem.top ? _rightItem.top : _top; let endY = _top > _rightItem.top ? _bottom : _rightItem.top + _rightItem.getHeight(); this.guidLine([_right, startY], [_right, endY]); } if (_topItem) { let startX = _left > _topItem.left ? _topItem.left : _left; let endX = _left > _topItem.left ? _right : _topItem.left + _topItem.getWidth(); this.guidLine([startX, _top], [endX, _top]); } if (_bottomItem) { let startX = _left > _bottomItem.left ? _bottomItem.left : _left; let endX = _left > _bottomItem.left ? _right : _bottomItem.left + _bottomItem.getWidth(); this.guidLine([startX, _bottom], [endX, _bottom]); } } zoom(scale) { $(this.dom).css({ transform: `scale(${scale})` }); this.clearCanvas(); } move(x, y) { $(this.dom) .css('left', x) .css('top', y); this.clearCanvas(); } clearCanvas() { this.cxt && this.cxt.clearRect(0, 0, this.canvasWidth, this.canvasHeight); } destroy() { $(this.dom).destroy(); this.isActive = false; } } export default GuidelineService;