gojs 流程图框架-基础绘图(一)

gojs 是一款很是优秀的流程图绘制 js 框架, 该框架没有中文版 api, 而且网上可查阅的资料很是少, 本文旨在带领读者了解整个框架结构, 以及基本的绘制方法. 本文对技术细节不做过多描述, 并会附上 api 地址以供参考.javascript

完成后的效果图: css

源码地址: github.com/muzqi/sampl…html

Step1 初始化画布

htmlvue

<div id="diagram" style="width: 1000px; height: 500px"></div>
复制代码

javascriptjava

// [1]
const $ = go.GraphObject.make

// [2]
const diagram = $(go.Diagram, 'diagram', {
   // 令绘制的元素相对画布居中
  'initialContentAlignment': go.Spot.Center, 
  
  // 是否可撤销编辑
  'undoManager.isEnabled': true
})
复制代码

代码注释:node

  1. gojs 有两种使用方法, 一种是使用本来的 go 对象, 第二种则是构造器方式建立, 即便用 go.GraphObject.make 对象建立,咱们将该对象赋值给 $, 固然为了不冲突也能够是其余符号
  2. $(go.Diagram, [selector], [options]), 该方法会执行 canvas 画布的初始化操做, 同时也提供了丰富的配置项使用, 详情参考Class Diagram

Step2 编写节点模板

所谓节点模板, 系指对节点创建一个统一的样式模板(集合); 若是用过 react 或 vue 等框架的童鞋天然很了解模板的意义, 在 gojs 中也同样, 咱们创建好公用模板后, 只须要数据传参便可react

gojs 一共有两种方式搭建节点模板 nodeTemplatenodeTemplateMapgit

这里只讲解 nodeTemplateMap, 它是一个节点模板集合, 里面能够自定义丰富的节点模板 它的使用方法相似 css 的类, 定义模板时定义类名, 调用时指定该类名便可github

小试牛刀

// [1]
diagram.nodeTemplateMap.add('templateName',
  $(go.Node, go.Panel.Auto,
    $(go.TextBlock, 
    { text: 'test' },
    /*[2]*/new go.Binding('text', 'text'))
  )
)

// [3]
const nodeDataArray = [
  { category: 'templateName', key: 'check', text: '审核' }
]

// [4]
const linkDataArray = []

// [5]
diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray)
复制代码

代码注释:canvas

1.diagram.nodeTemplateMap.add([name], [node])

  • ES6 Set 方法很是相似, add 即添加一个模板的意思, 第一个参数是模板的名字, 第二个参数是具体模板的配置
  • 第二个参数必须传递一个 $(go.Node, [Panel], [Elements]) 构造器

2.new go.Binding([origin], [target], [filter = Func])

  • 这是 gojs 中的数据绑定, 使用该方法实现了模板与真实数据之间的传递
  • 该方法能在任意构造器中使用
    • origin: 该构造器中的属性名
    • target: 须要绑定到数据集中的属性名
    • filter: 过滤函数

3.定义一个节点数据集,

  • key 属性是必填的且具备惟一性, 它将运用到链接线数据集
  • category 属性即对应了节点模板中模板的名称, 若不填, 则会默认使用第一组模板
  • textnew go.Binding 绑定的数据

4.链接线数据集, 这里为空, 暂不讨论

5.diagram.model 决定了页面中呈现哪些元素, 咱们建立一个普通连线实例 new go.GraphLinksModel 该构造函数接收两个参数, 即以前建立的 nodeDataArraylinkDataArray

实战演练

diagram.nodeTemplateMap.add('node1',
  $(go.Node, go.Panel.Position,
    // 规定该节点的宽高, 内容超出会被隐藏
    { width: 230, height: 240 },
    
    // 绑定节点的位置属性, 用来控制节点处于画布的哪一个位置
    new go.Binding('position'),

    // 背景图片与图标
    $(/*[1]*/go.Panel, /*[2]*/go.Panel.Auto,
      { position: new go.Point(0, 72) },
      $(go.Picture,
        {
          width: 178, height: 168,
        },
        new go.Binding('source', 'bgSrc')),
      $(go.Picture,
        {
          width: 64, height: 64,
        },
        new go.Binding('source', 'iconSrc'))
    ),

    // 文字背景与文本信息
    $(go.Panel, go.Panel.Position,
      { position: new go.Point(50, 0) },

      $(go.Picture,
        { width: 178, height: 100 },
        new go.Binding('source', 'textBgSrc')),

      $(go.TextBlock,
        {
          stroke: '#FFF',
          font: 'normal bold 24px Serif',
          position: new go.Point(80, 20)
        },
        new go.Binding('text'))
    )
  )
)

const nodeDataArray = [
  {
    position: new go.Point(0, 0),
    category: 'node1',
    key: 'check',
    bgSrc: './images/circle_1.png',
    iconSrc: './images/icon-apply.png',
    textBgSrc: './images/text-bg-1.png',

    text: '申请'
  }
]
复制代码

代码注释:

1.这里使用的 $(go.Panel) 你能够理解成 html 中的 div, 参见如下代码:

diagram.nodeTemplateMap.add('node1',
  $(go.Node, go.Panel.Position,
    { width: 230, height: 240 },
    new go.Binding('position'),

    // 背景图片与图标
    $(go.Panel, go.Panel.Auto,
      { position: new go.Point(0, 72) },
      $(go.Picture,
        {
          width: 178, height: 168,
        },
        new go.Binding('source', 'bgSrc'))
    )
  )
)
复制代码

gojs 中的 node 模板能够 '翻译' 成如下结构(若是你刚好熟悉 JSX 语法, 那就更好理解了)

<Node className="node1" layout="Position" style={{ width: 230, height: 240 }} position={position}>
    <Panel layout="Auto" style={{ position: new go.Point(0, 72) }}>
        <Picture source={bgSrc} style={{width: 178, height: 168}} />
    </Panel>
</Node>
复制代码

咱们只须要严格按照 gojs 的语法规则, 逐一嵌套, 便可绘制出任意你想要的节点模型

2.go.Panel.Auto 布局方法, 容许将 Panel 中的子元素逐一居中显示在 Node 包裹容器正中(你也能够设置偏移), 更多的布局规则, 如 Position Vertical Spot 等等, 请移步 Panels, 官方文档已经作了很详细的解释了

如下是当前的三个节点效果 如今就差节点之间的链接线了!

node


Step3 编写链接线模板

还记得以前定义的 linkDataArray 数组么? 这个数组装载全部链接线的信息 值的注意的是, 要先有 node 再有 link

与节点模板同样, 链接线模板也分 linkTemplatelinkTemplateMap 这里咱们只介绍 linkTemplateMap

实战演练

diagram.linkTemplateMap.add('link1',
  $(go.Link,  // [1]
    { routing: go.Link.Normal },
    new go.Binding('routing'),
    new go.Binding('fromSpot'),
    new go.Binding('toSpot'),

    // 线段模板
    $(go.Shape,  // [2]
      { strokeDashArray: [10, 20] },
      new go.Binding('stroke'),
      new go.Binding('strokeWidth')),

    // 箭头模板
    $(go.Shape,  // [2]
      { stroke: 'transparent', strokeWidth: 0 },
      new go.Binding('fromArrow'),
      new go.Binding('toArrow'),
      new go.Binding('scale', 'arrowScale'),
      new go.Binding('fill', 'arrowfill')),

    // 文字块
    $(go.Panel, go.Panel.Auto,  // [3]
      new go.Binding('alignmentFocus', 'textPos'),
      $(go.Shape, { fill: 'transparent' }, new go.Binding('stroke')),
      $(go.TextBlock, 
        { margin: 10 }, 
        new go.Binding('stroke'), 
        new go.Binding('text'))
    )
  )
)

const linkDataArray = [
  {
    category: 'link1',
    from: 'coor', to: 'apply',  // [4]

    routing: go.Link.Orthogonal,
    toArrow: 'Standard',
    arrowfill: 'orange',
    arrowScale: 2,
    fromSpot: new go.Spot(0, 0.42),
    toSpot: new go.Spot(0.42, 1),

    stroke: 'orange',
    strokeWidth: 2,

    text: '驳回',
    textPos: new go.Spot(0, 1, -100, 20)
  }
]
复制代码

代码注释:

1.go.Link 是链接线的包裹容器, 它全局为链接线定义一些属性

  • routing 定义链接线的链接方式, 直角或普通等等
  • fromSpot toSpot 定义链接线两端端头相对节点的位置
  • 还有许多可配置项, 参考Link

2.go.Link 容器中能够接收 go.Shape 构造器

  • 若是只设置该构造器 stroke 相关的属性, 则表示链接线的模板
  • 若是引入了 fromArrowtoArrow 则表示设置线段两端的箭头, 官方 figure 示例

3.一样, 咱们能够在线段中添加 Picture TextBlock Shape Panel 等任何元素, 而且编写方式与节点模板是一致的, 只不过若是你想控制这些元素的偏移量, 你须要设置 alignmentFocus 属性

4.以前说过, nodeDataArray 中的 key 是必填的, 由于咱们须要在 linkDataArray 中经过这个 key 来绝点各个节点的链接线如何相连

下期继续讲 gojs 的编辑类模板

(未完待续)

相关文章
相关标签/搜索