在线流程图和思维导图开发技术详解(二)

一、项目概述

二、项目架构

三、几何计算难点

四、鼠标事件处理

五、数据保存与导出

六、文本处理

二、项目架构

2.1 系统架构

项目系统架构如下图所示:

  1. UI元素即HTML DOM元素。项目打开时,画面虽然是一片空白的,但实际上UI元素并不空白。一些可复用不需动态创建的元素可预先定义好。例如选择框、对齐线等,出现的时候它们只是位置发生了改变,不需动态创建,可预先定义好,节省开销。

  2. UI元素使用ID标注(Vue里使用ref),然后注册到UI管理器中。后面对UI管理器中相应的对象进行修改时,UI元素就会发生改变。

  3. 对UI元素的所有操作,例如动一下鼠标、点一下按钮、按一下键盘,所有的这些事件都会交给事件处理器处理。事件处理器包括鼠标事件、基本编辑事件、画布事件、图元属性改变事件、分组操作事件、锁定操作事件、层次操作事件等。

  4. 事件处理器不会对UI直接产生作用,它们会调用各种管理器去完成任务。每种元素都会有一个管理器,包括画布、光标、历史记录、整图、选择、状态、选框、文字、变换等。

  5. 管理器中会使用到一些比较复杂的操作或计算,这些功能由工具类提供。例如几何计算、思维导图位置计算、path数据生成等。

  6. 管理器最后会对UI管理器进行操作,达到改变UI的最终效果。

以下,我们以鼠标点击一个矩形为例,说明框架的运行细节。

  1. HTML中定义了一个选择框,包括一个虚线矩形和八个实线小矩形。

  2. 上述图元注册到UI管理器中。

  3. 当鼠标点击矩形时,触发了MouseDown事件,这个事件会调用鼠标事件处理器。

  4. 鼠标事件处理器利用目标工具类,判断当前鼠标点击了什么目标。

  5. 鼠标事件处理器利用状态管理器获取当前状态,继而改变当前状态。

  6. 鼠标事件处理器利用光标管理器修改当前光标。

  7. 鼠标事件处理器利用选框管理器,显示选择框。

  8. 选框管理器调用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去确定。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
什么是MindV MindV是一款思维导图(心智图)工具。世界500强企业内部一直使用思维导图来提升员工的创造力。现在越来越多的人开始学习思维导图,学习这种21世纪的思维方式,引爆自己的灵感,提升自己的创造力,来改变自己,改变一个企业,甚至一个国家的竞争力。 MindV使用跨浏览器、跨平台的silverlight 4 技术开发,可以在所有流行的浏览器中运行。用户第一次在浏览器中点击链接运\行mindv时,如果您的机器没有安装 Silverliht 4,系统会提示您从微软网站下载并安装Silverlight 4;您只需按照提示一步一步执行;安装完Silverlight 4,MindV就可以运行了。 Mindv的部署:目前有两个网站提供用户注册,登录,购买,帮助等服务及并在主页提供运行Mindv的链接: mindv中国:http://www.mindv2.com/ 适合中国大陆人士为简体版本. mindv国际:http://www.mindv.com/ 适合中国大陆以外地区用户,为英语与繁体中文双语版本. 而Mindv应用本身部署在网站外的微软云计算平台中. 较本网站运\行更快速,为用户提供更稳健的服务和数据安全保护。 MindV可以帮我做些什么? 新的文档工具: MindV简单讲是一款新的文档工具,是Word,PPT,Excel之外另一种记录文档的工具。会议要点,各种提纲,读书笔记,整理思路,各种组织结构图等;文件格式符合Open XML规范;可以嵌入多媒体,超级链接,附件文档。 管理创意和设计:随时随地记录你的创意,将你的设计工作记录保存到本地或更为安全的云中。 解决每天的问题:将问题的各个组成部分可视化地列出,并深入研究它们之间的关系,找出一个创意的方案。 项目管理:从项目的开始到完成,都可以通过工具快速方便地设计和改进。 管理任务和优先级: 将任务划分成可管理的分任务,快速和方便地按照优先级排列。 可视化的教与学 :采用多媒体技术展示知识;方便学生记录学习重点。 团体合作与分享 :好的创意可以分享,用户可以将思维导图保存在云文件夹中并以网址的形式发布或者直接嵌入到网页中;团队成员可以就一个问题分别发表高见

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值