在线流程图和思维导图开发技术详解(二)
一、项目概述
二、项目架构
三、几何计算难点
四、鼠标事件处理
五、数据保存与导出
六、文本处理
二、项目架构
2.1 系统架构
项目系统架构如下图所示:
UI元素即HTML DOM元素。项目打开时,画面虽然是一片空白的,但实际上UI元素并不空白。一些可复用不需动态创建的元素可预先定义好。例如选择框、对齐线等,出现的时候它们只是位置发生了改变,不需动态创建,可预先定义好,节省开销。
UI元素使用ID标注(Vue里使用ref),然后注册到UI管理器中。后面对UI管理器中相应的对象进行修改时,UI元素就会发生改变。
对UI元素的所有操作,例如动一下鼠标、点一下按钮、按一下键盘,所有的这些事件都会交给事件处理器处理。事件处理器包括鼠标事件、基本编辑事件、画布事件、图元属性改变事件、分组操作事件、锁定操作事件、层次操作事件等。
事件处理器不会对UI直接产生作用,它们会调用各种管理器去完成任务。每种元素都会有一个管理器,包括画布、光标、历史记录、整图、选择、状态、选框、文字、变换等。
管理器中会使用到一些比较复杂的操作或计算,这些功能由工具类提供。例如几何计算、思维导图位置计算、path数据生成等。
管理器最后会对UI管理器进行操作,达到改变UI的最终效果。
以下,我们以鼠标点击一个矩形为例,说明框架的运行细节。
HTML中定义了一个选择框,包括一个虚线矩形和八个实线小矩形。
上述图元注册到UI管理器中。
当鼠标点击矩形时,触发了MouseDown事件,这个事件会调用鼠标事件处理器。
鼠标事件处理器利用目标工具类,判断当前鼠标点击了什么目标。
鼠标事件处理器利用状态管理器获取当前状态,继而改变当前状态。
鼠标事件处理器利用光标管理器修改当前光标。
鼠标事件处理器利用选框管理器,显示选择框。
选框管理器调用UI管理器中注册的元素,把选择框显示出来。
2.2 图元数据定义
图元数据描述是本项目开发的一个难点。图元数据的特点包括:
(1)图元种类众多,每种图元有自己独特的属性。
(2)某些种类的图元存在公共的属性。例如矩形、图片的位置都是通过一个矩形来描述的。
(3)管理器对图元有共同的操作。例如把图片数据转化为可视HTML,鼠标拖动时的平移动作等。这些操作在图元内部的实现并不一致。
(4)图元存在一些即使而不需要保存的属性,例如是否选中,这是一个不需要保存,每次打开时都有默认值的属性。
在本项目中,图元具有以下的数据定义:
class Component {public id: string = "";public type: ComponentType = "rect";public props: { [key: string]: string } = {};public connectAnchors: Array<AnchorDirPos> = []; }
这就是图元的基类。可以看到,属性是相当少的。在这里,需要说明几种跟TypeScript语法相关的设计特性:
(1)图元基类只有属性,没有方法。这是因为图元需要进行复制操作,复制时方法是无法实现的。
(2)很多特有的属性被设计到props属性中,这是一个Object。实际上Map也能实现相同的功能,但因为Map同样不能被复制,所以使用Object。props中只存放字符串类型的属性,其他属性(例如位置)如果使用字符串,还需要转换,浪费资源。
对于存在公共属性的图元,定义了继承Component的新的基类。例如,用矩形去描述位置的图元,都继承于以下的基类:
class RectPositionComponent extends Component {public position: Rect = new Rect(0, 0, 0, 0);public originPosition: Rect = new Rect(0, 0, 0, 0); public mindChildren1: Array<MindElement> = [];public mindChildren2: Array<MindElement> = []; public constructor() {super(); this.props[PreDefine.MindType] = PreDefine.DefaultMindType;} }
在这里,我们可以看到,这个类有一个position属性,它是一个矩形。还有一个originPosition属性,是用在变换图元时标记原始位置的属性。
这个基类还描述了思维导图的数据结构。本项目的思维导图,只能在矩形类型的图元下创建。思维导图存在树在两侧的展示方式,所以有两棵树(mindChildren1和mindChildren2)去描述思维导图的结点。
以下是矩形类的定义:
class RectComponent extends RectPositionComponent {public constructor() {super(); this.type = "rect";this.id = CommonFunc.GetId(); this.props[PreDefine.Fill] = PreDefine.DefaultFill;this.props[PreDefine.Stroke] = PreDefine.DefaultStroke;this.props[PreDefine.StrokeWidth] = PreDefine.DefaultStrokeWidth;this.props[PreDefine.StrokeDash] = PreDefine.DefaultStrokeDash;this.props[PreDefine.CornerRadius] = PreDefine.DefaultCornerRadius; this.props[PreDefine.TextHorAlign] = PreDefine.DefaultTextHorAlign;this.props[PreDefine.TextVerAlign] = PreDefine.DefaultTextVerAlign;this.props[PreDefine.FontFamily] = PreDefine.DefaultFontFamily;this.props[PreDefine.FontSize] = PreDefine.DefaultFontSize;this.props[PreDefine.FontColor] = PreDefine.DefaultFontColor;this.props[PreDefine.FontBold] = PreDefine.DefaultFontBold;this.props[PreDefine.FontUnderline] = PreDefine.DefaultFontUnderline;} public textPos: AnchorPos = new AnchorPos();public textExist: boolean = false;public textHtml: string = ""; }
矩形的样式,需要通过填充颜色、描边宽度等属性去定义。另外,矩形中还有文字,文字又有字体大小、字体颜色等属性。这些属性都在图元初始化时添加到props属性中。而文字的位置等属性,由于其存在一定的数据结构,如果定义在props中,还需要转化,浪费资源,所以独立定义。事实上,这种区分定义还有一个重要原因,就是在菜单中能修改的属性都在props中。
对图元的操作由一个接口去定义。以下是该接口的部分方法:
interface IComponentOperate {ChangeId(): void;Create(obj: unknown): void; Html(): string;UpdateHtml(): void;DeleteHtml(): void; Move(diagramX: number, diagramY: number): void;MoveOffset(offsetX: number, offsetY: number): void;UpdateInnerPosition(): void;MarkOrigin(): void;ChangeCoordinate(origin: Rect, target: Rect): void; }
Html()方法是返回图元的HTML内容。例如矩形使用一个<rect>
标签定义,形状一般使用<path>
标签定义,而图片使用<image>
标签定义。又如,UpdateInnerPosition()方法一般是用在组类型的图元上的。一个组进行变换之后,其内部的所有图元都要跟随变换。但矩形这种图形,内容并没有子,也就不需要执行额外的操作。
操作方法跟图元,通过图元的ID和类型进行绑定。图元的类型确定了接口实例化的方法类,而方法类要处理哪个图元,又通过ID去确定。
在线流程图和思维导图开发技术详解(二)相关推荐
- 在线流程图和思维导图开发技术详解(三)
一.项目概述 二.项目架构 三.几何计算难点 四.鼠标事件处理 五.数据保存与导出 六.文本处理 三.几何计算难点 3.1 矩形变换 我们先来看没有旋转的情况.不旋转的情况是比较简单的,只是情况比较多 ...
- 在线流程图和思维导图开发技术详解(五)
一.项目概述 二.项目架构 三.几何计算难点 四.鼠标事件处理 五.数据保存与导出 六.文本处理 五.数据保存与导出 5.1 数据保存 一张流程图,实际是一个图元列表,也就是Array<Comp ...
- 在线流程图和思维导图开发技术详解(六)
一.项目概述 二.项目架构 三.几何计算难点 四.鼠标事件处理 五.数据保存与导出 六.文本处理 六.文本处理 6.1 两种富文本展示方式 本项目显示的文本皆是富文本,也就是在一个框里面,文本有多种样 ...
- 在线流程图和思维导图开发技术详解(四)
一.项目概述 二.项目架构 三.几何计算难点 四.鼠标事件处理 五.数据保存与导出 六.文本处理 四.鼠标事件处理 在所有处理器中,鼠标事件处理器是最为复杂的,因为在整个页面中,基本可以使用鼠标完成所 ...
- 推荐一个在线创作流程图、思维导图软件—ProcessOn
转载自 推荐一个在线创作流程图.思维导图软件-ProcessOn 最近要画流程图,破解了半天Visio2016没搞定,2016的估计都被封了,Visio收费又过贵,又不想折腾低版本的破解,所以找了个在 ...
- 推荐一个在线绘图工具ProcessOn----支持流程图、思维导图、UML等
我们常用来绘制流程图等的工具一版会使用visio等,但是它是一款收费软件,而且不是太易用,今天推荐一款在线绘图工具ProcessOn,不仅功能强大,而且快捷易用,还有大量优秀的模板可供使用. 邀请连接 ...
- 免费在线作图,思维导图,流程图,实时协作
www.processon.com 免费在线作图,思维导图,流程图,实时协作
- 流程图、思维导图、网络拓扑图、组织结构图——ProcessOn在线工具及增加文件数方法
可网页在线画流程图之类的,还有模版可以参考. ProcessOn 支持流程图.思维导图.原型图.UML.网络拓扑图.组织结构图等 ProcessOn在线工具: https://www.processo ...
- confluence 制作流程图_「每周开方」 高效制作流程图、思维导图
提升工作效率,并且可以自成一套职场PPT的导图.流程图! 这周的「每周开方」公子要分享强大的"思维导图"及"流程图"制作网站!在职场中导图的重要性应该不需要公子 ...
最新文章
- 1.2 内置异常类,异常方法
- zabbix监控oracle缓冲区,Zabbix监控oracle各服务器连接数
- Hadoop tutorial - 3 Hello MapReduce- 2015-3-30
- Kotlin — 适用于Android 开发
- unity shader base pass and additional pass
- 单片机编程软件很简单(19),keil单片机编程软件3点介绍
- 移动支付的方式有哪些拾方易告诉你
- 数据耦合的代码例子c语言,代码耦合的处理
- 1.Python基础
- Centos7升级OpenSSL 1.0.2k-fips
- 解决SVN Can’t open file ‘/XXX/xxx/db/txn-current-lock’错误
- python+selenium移动滑块代码【杭州多测师_王sir】【杭州多测师】
- Cadence原理图层次化设计
- 2.Python-简单数据类型
- 【SAP Abap】SAP增强开发总结
- 【Cocos Creator 3.x】 Shader 中的 layout(set = N, binding = M) 是什么意思?
- 经典俄罗斯方块游戏使用手册
- matlab粒子群加约束条件_matlab粒子群编程,等式约束如何加入
- 安装智能消费机服务器连接,消费一卡通系统/消费机布线安装方法
- reverse(一)——apk逆向
热门文章
- python爬虫学习日记(1) scrapy爬取时,报错Filtered offsite request
- 二维码简介_二维码基本概念_二维码基本原理
- Confluence 6 自定义站点和空间布局
- 本地代码如何提交到远程,克隆的和不克隆,两种方法
- 快手小程序研发总结页面跳转参数携带需注意
- Uint8Array截取,Uint8Array有的手机不支持slice方法,如何截取?
- 在线招聘:庞大市场,“渺小”平台
- 离线安装wxpython4.0.6_离线安装wxpython
- Ansible的安装及使用
- 保安日记:前端学习第三篇之CSS选择器