基于乐吾乐meta2d从零实现可视化流程图编辑器(九)

641 阅读7分钟

概要

可视化编辑器已成为前端发展趋势,相关产品层出不穷,但是用户较难根据自身需求去完整实现一个功能较为全面的可视化编辑器,我将采用乐吾乐开源的meta2d.js可视化库来实现一个简单的流程图编辑器,通过这个案例来介绍meta2d的相关功能,并向读者展示如何用meta2d从零出发搭建一个较为完整的项目,让我们在实际项目中来体验meta2d的强大之处吧。

$MUTB]6JJ667KR$SC95VH(1.png

什么是乐吾乐meta2d.js

meta2d是乐吾乐开源的2D图元组成的可视化引擎,集实时数据展示、动态交互、数据管理等一体的全功能2D可视化引擎。能够快速实现数字孪生、大屏可视化、Web组态、SCADA等解决方案。具有实时监控、多样、变化、动态交互、高效、可扩展、支持自动算法、跨平台等特点,最大程度减少研发和运维的成本,并致力于普通业务人员 0 代码开发实现物联网、工业互联网、电力能源、水利工程、智慧农业、智慧医疗、智慧城市等可视化解决方案。

乐吾乐已将其meta2d核心库完全免费开源,本系列教程就是基于meta2d从零实现web端可视化流程图编辑器。

乐吾乐 meta2d开源项目地址:github.com/le5le-com/m…

乐吾乐 meta2d官方文档:doc.le5le.com/document/11…

项目地址

此可视化流程图编辑器项目地址:github.com/Grnetsky/me…

在线体验地址: editor.xroot.top/

往期教程

  1. 基本环境搭建: juejin.cn/spost/72617…
  2. 主界面布局及其初始化: juejin.cn/post/726219…
  3. Meta2d核心库图元注册流程及相关概念: juejin.cn/spost/72629…
  4. 侧边栏功能开发:juejin.cn/post/726441…
  5. Nav组件功能实现:juejin.cn/post/726495…
  6. Nav组件扩展-添加工具栏:juejin.cn/post/726569…
  7. setting组件框架搭建及其Map组件实现:juejin.cn/post/726741…
  8. 引入自定义图元库详解:juejin.cn/post/726794…

9.Global全局配置组件实现

在本章,我们将学习meta2d提供的Options属性,进行全局配置组件的开发。由于之前配置的框架使得本章内容十分简单,我们一起来看看。

Options属性介绍

在之前我们就提到过Options属性,并且利用setOptions方法进行了一些功能的设置,Options属性是挂载到meta2d.store身上的一个可视化引擎配置选项,他身上包含了关于可视化组件引擎的所有配置,具体有下面这些:

名称类型描述
colorstring画笔默认颜色,如果没特别设置,颜色包括:文字和边框
activeColorstring画笔选中颜色
activeBackgroundstring画笔选中背景颜色
hoverColorstring鼠标移动到画笔上的颜色
hoverBackgroundstring鼠标移动到画笔上的背景颜色
anchorColorstring锚点颜色
anchorRadiusnumber锚点半径
anchorBackgroundstring锚点背景颜色
dockColorstring辅助线颜色
dragColorstring鼠标框选多个节点时,边框颜色
animateColorstring连线动画颜色
textColorstring文字颜色
fontFamilystring文字字体
fontSizenumber文字大小
lineHeightnumber文字行高
textAlignstring文字水平对齐方式
textBaselinestring文字垂直对齐方式
rotateCursorstring旋转控制点的鼠标样式
hoverCursorstring鼠标经过画笔的样式
disableInputboolean禁用双击弹出输入框
disableRotateboolean禁止旋转
disableAnchorboolean禁止显示锚点
autoAnchorboolean连线时,自动选中节点锚点
disableEmptyLineboolean禁止存在两端关联缺少的连线
disableRepeatLineboolean禁止存在关联重复的连线
disableScaleboolean禁止画布缩放
disableTranslateboolean禁止画布移动
disableDockLineboolean取消辅助线
minScalenumber画布最小缩放比例
maxScalenumber画布最大缩放比例
keydownKeydownType快捷键监听对象,默认 document;-1 不监听快捷键,需在 Meta2d 初始化时配置
gridboolean是否显示网格
gridColorstring网格颜色
gridSizenumber网格大小
ruleboolean是否显示标尺
ruleColorstring标尺颜色
drawingLineNamestring默认连线类型名称
fromArrowstring默认连线起始箭头
toArrowstring默认连线终点箭头
autoPolylineboolean是否自动计算多线段锚点
intervalnumber绘画帧时长
animateIntervalnumber动画帧时长
dragAllInboolean框选画笔时,是否需要全部在框选区域内
scrollboolean默认是否显示滚动条。与默认缩放互斥
defaultAnchorsPoint[]默认图形的默认锚点,例如:正方形等。
moveConnectedLineboolean是否允许拖动连接线
mouseRightActiveboolean是否允许右键选中节点,默认true允许
disableClipboardboolean是否禁止系统剪切板,默认false不禁止
drawingLineLengthnumber画线过程中允许的最大长度,为0表示不限
disableTouchPadScaleboolean是否禁止触控板双指缩放,默认false
domShapesstring[]扩展的dom画笔name,处理dom移动过程中会产生新的dom问题
textRotateboolean文字是否选择,默认true
textFlipboolean文字是否镜像,默认true

meta2d为我们提供了相关方法用于设置和访问其身上的属性:

  1. setOptions:用于设置配置项

image.png

  1. getOptions:用于获取相关配置

image.png

我们可以利用这两个方法进行引擎配置的更改。

Optiuon组件实现

我们可以将配置分为几大类:画笔、锚点、辅助线、文字、禁止、鼠标样式、画布设置、其他配置。

下面是配置内容

<script setup>
import Form from "../Form.vue";
import {computed, onMounted, reactive} from "vue";

import { globalConfigProps } from "../../data/defaultsConfig.js";
let m = reactive(globalConfigProps)

// 同步核心库配置,若本地配置则采用本地配置
function loadOptionsFromMeta2d(options,target){
  for(let i in target){
    if(target[i])continue
    target[i] = (options[i] || target[i])
  }
}
onMounted(()=>{
  // 初始化
  init()
})
function init() {
  const options = meta2d.getOptions()
  loadOptionsFromMeta2d(options,m)
  for(let p in m){
    meta2d.setOptions({
      [p]:m[p]
    })
  }
  meta2d.render()
}
function setOptionFunc(prop) {
  return (value)=>{
    meta2d.setOptions({
      [prop]:value
    })
    meta2d.render()
  }
}
const map = computed(()=>{
  return [
    {
      title:"画笔", //显示名
      children:[
        {
          title:"默认颜色",
          type:"color",
          prop:"color",
          bindProp:m,// 绑定的属性
          event:"change",
          func:setOptionFunc('color')
        },
        {
          title:"选中颜色",
          type:"color",
          prop:"activeColor",
          bindProp:m,// 绑定的属性
          event:"change",
          func:setOptionFunc('activeColor')
        },
        {
          title:"hover颜色",
          type:"color",
          prop:"hoverColor",
          bindProp:m,// 绑定的属性
          event:"change",
          func:setOptionFunc("hoverColor")
        },
        {
          title:"hover背景颜色",
          type:"color",
          prop:"hoverBackground",
          bindProp:m,// 绑定的属性
          event:"change",
          func:setOptionFunc('hoverBackground')
        }
      ]
    }, {
      title:"锚点", //显示名
      children:[
        {
          title:"锚点颜色",
          type:"color",
          prop:"anchorColor",
          event:"change",
          bindProp:m, // 绑定的属性
          func:setOptionFunc('anchorColor')
        },
        {
          title:"锚点半径",
          type:"number",
          prop:"anchorRadius",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('anchorRadius')
        },
        {
          title:"锚点背景颜色",
          type:"color",
          prop:"anchorBackground",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('anchorBackground')
        }
      ]
    },
    {
      title:"辅助线", //显示名
      children:[
        {
          title:"锚点颜色",
          type:"color",
          prop:"dockColor",
          event:"change",
          bindProp:m, // 绑定的属性
          func:setOptionFunc('dockColor')
        },
        {
          title:"框选颜色",
          type:"color",
          prop:"dragColor",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('dragColor')

        },
        {
          title:"连线动画颜色",
          type:"color",
          prop:"animateColor",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('animateColor')

        }
      ]
    },
    {
      title:"文字", //显示名
      children:[
        {
          title:"文字颜色",
          type:"color",
          prop:"textColor",
          event:"change",
          bindProp:m, // 绑定的属性
          func:setOptionFunc('textColor')

        },
        {
          title:"字体",
          type:"input",
          prop:"fontFamily",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('fontFamily')

        },
        {
          title:"文字大小",
          type:"number",
          prop:"fontSize",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('fontSize')

        },
        {
          title:"文字行高",
          type:"number",
          prop:"lineHeight",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('lineHeight')

        },
        {
          title:"文字水平对齐方式",
          type:"input",
          prop:"textAlign",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('textAlign')
        },
        {
          title:"文字垂直对齐方式",
          type:"input",
          prop:"textBaseline",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('textBaseline')
        }
      ]
    },
    {
      title:"鼠标样式", //显示名
      children:[
        {
          title:"旋转控制点的",
          type:"input",
          prop:"rotateCursor",
          event:"change",
          bindProp:m, // 绑定的属性
          func:setOptionFunc('rotateCursor')

        },
        {
          title:"hover样式",
          type:"input",
          prop:"hoverCursor",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('hoverCursor')
        }
      ]
    },
    {
      title:"禁止", //显示名
      children:[
        {
          title:"禁用双击弹出输入框",
          type:"switch",
          prop:"disableInput",
          event:"change",
          bindProp:m, // 绑定的属性
          func:setOptionFunc('disableInput')
        },
        {
          title:"禁止旋转",
          type:"switch",
          prop:"disableRotate",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('disableRotate')
        },{
          title:"禁止显示锚点",
          type:"switch",
          prop:"disableAnchor",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('disableAnchor')
        },
        {
          title:"禁止存在两端关联缺少的连线",
          type:"switch",
          prop:"disableEmptyLine",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('disableEmptyLine')
        },
        {
          title:"禁止存在关联重复的连线",
          type:"switch",
          prop:"disableRepeatLine",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('disableRepeatLine')

        },
        {
          title:"禁止画布缩放",
          type:"switch",
          prop:"disableScale",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('disableScale')
        },
        {
          title:"禁止辅助线",
          type:"switch",
          prop:"disableDockLine",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('disableDockLine')

        },
        {
          title:"禁止画布移动",
          type:"switch",
          prop:"disableTranslate",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('disableTranslate')

        }
      ]
    },
    {
      title:"画布设置", //显示名
      children:[
        {
          title:"画布最小缩放比例",
          type:"number",
          prop:"minScale",
          event:"change",
          bindProp:m, // 绑定的属性
          func:setOptionFunc('minScale')

        },
        {
          title:"画布最大缩放比例",
          type:"number",
          prop:"maxScale",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('maxScale')

        }
      ]
    },
    {
      title:"其他设置", //显示名
      children:[
        {
          title:"自动选中节点锚点",
          type:"switch",
          prop:"autoAnchor",
          event:"change",
          bindProp:m, // 绑定的属性
          func:setOptionFunc('autoAnchor')

        },
        {
          title:"绘画帧时长",
          type:"number",
          prop:"interval",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('interval')

        },
        {
          title:"动画帧时长",
          type:"number",
          prop:"animateInterval",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('animateInterval')

        },{
          title:"文字是否选择",
          type:"switch",
          prop:"textRotate",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('textRotate')

        },
        {
          title:"文字是否镜像",
          type:"switch",
          prop:"textFlip",
          bindProp:m, // 绑定的属性
          event:"change",
          func:setOptionFunc('textFlip')

        }
      ]
    },
  ]
})
</script>

<template>
  <div class="globalProps">
    <Form :form-list=map ></Form>
  </div>
</template>

<style scoped>
</style>

该map的结构在前面几章多次出现过,就不做额外解释了,由于整个属性设置都依赖setOptions方法,为了代码的简洁性和可维护性,我们将setOptions方法单独抽取出来设置为新的函数setOptionFunc,只需要在其中传参要修改的属性即可,另外需要注意的点是,我们在引擎加载的时候需要将其默认配置与我们自己的配置相融合(需要将默认配置属性赋值到我们自身配置),这样才能在初始化的时候同步到系统默认配置的数据。然后我们来看看defaultsConfig的相关字段配置代码

// defaultsConfig.js
export const globalConfigProps = {
  color:"",
  activeColor:"",
  hoverColor:"",
  hoverBackground:"",
  anchorColor:"",
  anchorRadius:"",
  anchorBackground:"",
  dockColor:"",
  dragColor:"",
  animateColor:"",
  textColor:"",
  fontFamily:"",
  fontSize:"",
  lineHeight:"",
  textAlign:"",
  textBaseline:"",
  rotateCursor:"",
  hoverCursor:"",
  disableInput:false,
  disableRotate:false,
  disableAnchor:false,
  disableEmptyLine:false,
  disableRepeatLine:false,
  disableScale:false,
  disableDockLine:false,
  disableTranslate:false,
  minScale:0.1,
  maxScale:10,
  autoAnchor:true,
  interval:60,
  animateInterval:60,
  textRotate:true,
  textFlip:true
}

就这样,我们就能够通过本组件去修改引擎的相关配置项了。

篇幅有限,我并没有将所有配置都写上去,而是将较为重要可能经常用到的配置布局上去了,可以看到,上面所有方法,都只调用了meta2d.setOptions方法,然后重新渲染一下,基本上这样我们就实现了简单的全局配置功能,很简单吧只依赖setOptions方法即可。让我们来看看实际效果:

globalconfig 00_00_00-00_00_30.gif

可以看到我们的设置列表已生成,并且更改功能生效,由于gif时长有限没办法挨个验证功能,读者可以在项目代码中自行进行功能的验证。

总结

在本章我们介绍了meta2d的Options属性,学会了使用meta2d的setOptions方法进行编辑器配置的修改,整体较为简单,稍微需要注意的的是如何将meta2d核心库默认配置与本地配置相融合,以及如何封装函数来简化我们的代码,到此我们的MapProps的内容就已经讲完,在下一章,我们将讲解PenProps的相关内容,让我们来为图元添加更多功能,各位下章见。

Meta2d.js 开源地址

给大家推荐一下 Meta2d.js是一个实时数据响应和交互的2d引擎,可用于Web组态,物联网,数字孪生等场景。

Github:github.com/le5le-com/m…

Gitee: gitee.com/le5le/meta2…

如果本篇文章帮助到了你,欢迎为meta2d项目star点星。