UNPKG

@logicflow/extension

Version:
161 lines (160 loc) 8.11 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; import { jsx as _jsx } from "preact/jsx-runtime"; import { Component, observer } from '@logicflow/core'; import { forEach, merge } from 'lodash-es'; import Label from './Label'; import LabelModel from './LabelModel'; import { MediumEditor, defaultOptions, ColorPickerButton } from './mediumEditor'; // const { createUuid } = LogicFlowUtil // DONE: 解决问题,如果 LabelOverlay 设置为 Observer,拖拽 Label 时会导致 LabelOverlay 组件重新渲染,不知道为何 // 目前解决了。流程是 拖动 -> 更新 label 的数据信息到 element model -> 重新渲染 LabelOverlay // 这种目前存在的问题,会全量重新渲染,是否会影响性能 ❓❓❓ // 另一种解决方案是,在此组件中监听一些事件,当这些事件触发时,再重新渲染 LabelOverlay // 讨论一下 var LabelOverlay = /** @class */ (function (_super) { __extends(LabelOverlay, _super); function LabelOverlay(props) { var _this = _super.call(this, props) || this; _this.labelMap = new Map(); var lf = props.lf, graphModel = props.graphModel; _this.lf = lf; _this.graphModel = graphModel; _this.state = { tick: 0 }; return _this; } LabelOverlay.prototype.componentDidMount = function () { var _this = this; var graphModel = this.props.graphModel; // 1. 直接在此处初始化 RichTextEdit 工具 this.editor = new MediumEditor('.lf-label-editor', merge(defaultOptions, { autoLink: true, extensions: { colorPicker: new ColorPickerButton(), }, })); // TODO: 2. 在此处监听一些事件,当 node、edge 数据变化时,主动触发重新渲染,保证同步更新 // TODO: 3. 整理哪些事件应该触发 Label 的更新 // 不需要了,将当前组件设置成 @observer 后,graphModel 更新会自动触发更新 graphModel.eventCenter.on('text:update,node:mousemove,node:resize,node:rotate,node:drag,label:drop,node:drop', function () { // this.setState({ tick: this.state.tick + 1 }) }); graphModel.eventCenter.on('node:properties-change,node:properties-delete', function () { _this.setState({ tick: _this.state.tick + 1 }); }); }; LabelOverlay.prototype.componentDidUpdate = function () { var _a; // 在组件更新后,将新增的 label 元素添加到富文本编辑器中 if (this.editor && this.editor.elements.length > 0) { this.editor.addElements('.lf-label-editor'); } else { // FIX: 如果初始化的数据中没有 properties._label,需要重新初始化富文本编辑器 (_a = this.editor) === null || _a === void 0 ? void 0 : _a.destroy(); this.editor = new MediumEditor('.lf-label-editor', merge(defaultOptions, { autoLink: true, extensions: { colorPicker: new ColorPickerButton(), }, })); } }; LabelOverlay.prototype.componentWillUnmount = function () { var _a; // 组件销毁时,同时将富文本编辑器注销 (_a = this.editor) === null || _a === void 0 ? void 0 : _a.destroy(); }; /** * 获取当前画布上所有的 label * 1. 第一步,先把当前所有的 text 转换为 label 进行展示 * 2. 数据同步,text 编辑后,同步更新 label,并重新渲染 */ LabelOverlay.prototype.getLabels = function () { var _this = this; // 1. 通过 graphModel 获取当前画布上所有的 label 配置数据 var _a = this.props, extension = _a.lf.extension, graphModel = _a.graphModel; var elements = __spreadArray(__spreadArray([], __read(graphModel.nodes), false), __read(graphModel.edges), false); var curExtension = extension['label']; if (curExtension) { var labels_1 = []; // 保存所有的 Label 元素 // TODO: 筛选出当前画布上,textMode 为 TextMode.LABEL 的元素(在支持元素级别的 textMode 时,需要做这个筛选) // REMIND: 本期先只支持全局配置,所以判断全局的 textMode 即可 forEach(elements, function (element) { var _a, _b; var elementData = element.getData(); var labelConfig = (_b = (_a = elementData.properties) === null || _a === void 0 ? void 0 : _a._label) !== null && _b !== void 0 ? _b : []; forEach(labelConfig, function (config) { var labelMap = _this.labelMap; // 查找 labelModel 实例,如果是实例化过的,直接复用;如果是新的,创建实例 // let label: LabelModel // if (config.id && labelMap.has(config.id)) { // label = labelMap.get(config.id)! // } else { // label = new LabelModel(config, element, graphModel) // labelMap.set(label.id, label) // } var label = new LabelModel(config, element, graphModel); labelMap.set(label.id, label); labels_1.push(_jsx(Label, { label: label, element: element, graphModel: graphModel }, label.id)); }); }); return labels_1; } return null; }; LabelOverlay.prototype.render = function () { return (_jsx("foreignObject", { id: "lf-label-overlay", class: "lf-label-overlay", children: this.getLabels() })); }; LabelOverlay.toolName = 'label-edit-tool'; LabelOverlay = __decorate([ observer ], LabelOverlay); return LabelOverlay; }(Component)); export { LabelOverlay }; export default LabelOverlay;