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 的編輯類模板

(未完待續)

相關文章
相關標籤/搜索