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


    一、项目概述

    二、项目架构

    三、几何计算难点

    四、鼠标事件处理

    五、数据保存与导出

    六、文本处理

    五、数据保存与导出

    5.1 数据保存

    一张流程图,实际是一个图元列表,也就是Array这样的数据结构。保存数据时,把这个数组转换成字符串(JSON.stringify),再存起来即可。

    由于我们项目还有一个列表页,如下图所示:

    这里需要显示流程图的缩略图。有两个方法可以制作缩略图:

    1. 把原图的svg存起来,作为一张图片,然后使用引用。

    2. 把原图的svg存起来,再转为小规格的png图片,然后使用引用。

    经测试,方法1行不通。如果流程图只有图形数据(没有图片),那这个方法很好。当存在图片时,img引用一个svg,svg又引用一张图片,就会显示不出现。当然,也可以把图片转换成base64数据的方式来解决。但如果图片是svg时,这个方法仍然行不通。

    所以项目最终采用了方法2。

    5.2 数据导出

    本项目可以把编辑好的图导出png、jpg、svg等格式。实际上,导出svg格式是最重要的,其他格式可以由svg格式转换。在上一节中,我们已经提到,在数据保存时,svg数据也保存了下来。那么,导出svg图片就是什么也不需要做,直接引用这个文件的路径即可。

    svg转png和jpg是在后端完成的。项目后端使用.NET开发,在NuGet中引用一个名为Svg的库,即可实现svg的转换。代码如下:

    var doc = SvgDocument.Open(file);
    var svgImage = doc.Draw();
    GetImagePos(svgImage.Width, svgImage.Height, out int bw, out int bh, out int bx, out int by);
    using (var bmp = new Bitmap(IMG_WIDTH, IMG_HEIGHT))
    {
        using (var g = Graphics.FromImage(bmp))
        {
            g.Clear(Color.Transparent);
            g.DrawImage(svgImage, new Rectangle(bx, by, bw, bh));
        }
        bmp.Save(Locations.DiagramThumb(id), ImageFormat.Png);
    }
    svgImage.Dispose();

    5.3 撤销功能

    为什么要在此处提撤销功能?因为撤销功能用到了数据保存。

    当我们按下Ctrl+Z,最新的操作会被撤销,恢复操作之前的流程图。那我们是怎样保存之前的图呢?有一种方式是,保存一张初始图,然后把每次的操作都记录下来。当需要撤销时,把这些操作反向操作。这种做法是非常省空间的,但可能会相当复杂。因为编辑操作很多,这个“反操作”就会很复杂,要记下的内容也五花八门。例如拖动一个图元移动,那需要记录之前的位置。如果是删除一个图元,那应该记下那个图元的信息。如果是合并一个组,那又要记录是哪些图元合成组了。每种操作记录的信息不一样,撤销功能难以实现。

    还有一种方法,也是本项目所采用的方法,就是把所有图元的信息保存起来,序列化成一个字符串。这个字符串存放在一个Stack里面。当需要撤销时,从Stack里取出字符串,反序列化成图元信息,覆盖当前的图元信息,重新加载和渲染。显示,这种方式在性能上似乎比较低效,但已经没有更好的方法了。

  • 相关阅读:
    Vega Prime入门教程14.01:调用VAPS XT DLL
    连新手小白都知道的电子画册一键生成器,你还不知道吗?
    Python零基础入门-8 错误和异常
    TypeScript 中 type 和 interface 有什么区别?
    Java Character.SubSet equals()方法具有什么功能呢?
    【JavaWeb】FilterConfig应用示例
    (一)Neo4j下载安装以及初次使用
    PyTorch 与 TensorFlow:机器学习框架之战
    文字转语音怎么做?分享三种配音方法,真人语音很逼真
    基于Python的热门音乐特征数据分析
  • 原文地址:https://blog.csdn.net/lweiyue/article/details/126955349