gojs 流程圖框架-基礎繪圖(一)


 

gojs 流程圖框架-基礎繪圖(一)

gojs 是一款非常優秀的流程圖繪制 js 框架, 該框架沒有中文版 api, 並且網上可查閱的資料非常少, 本文旨在帶領讀者了解整個框架結構, 以及基本的繪制方法. 本文對技術細節不作過多描述, 並會附上 api 地址以供參考.

完成后的效果圖:

 

源碼地址: github.com/muzqi/sampl…

Step1 初始化畫布

html

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

javascript

// [1] const $ = go.GraphObject.make // [2] const diagram = $(go.Diagram, 'diagram', { // 令繪制的元素相對畫布居中 'initialContentAlignment': go.Spot.Center, // 是否可撤銷編輯 'undoManager.isEnabled': true }) 復制代碼

代碼注釋:

  1. gojs 有兩種使用方法, 一種是使用原本的 go 對象, 第二種則是構造器方式創建, 即使用 go.GraphObject.make 對象創建,我們將該對象賦值給 $, 當然為了避免沖突也可以是其他符號
  2. $(go.Diagram, [selector], [options]), 該方法會執行 canvas 畫布的初始化操作, 同時也提供了豐富的配置項使用, 詳情參考Class Diagram

Step2 編寫節點模板

所謂節點模板, 系指對節點建立一個統一的樣式模板(集合); 如果用過 react 或 vue 等框架的童鞋自然很了解模板的意義, 在 gojs 中也一樣, 我們建立好公用模板后, 只需要數據傳參即可

gojs 一共有兩種方式搭建節點模板 nodeTemplate 和 nodeTemplateMap

這里只講解 nodeTemplateMap, 它是一個節點模板集合, 里面可以自定義豐富的節點模板 它的使用方法類似 css 的類, 定義模板時定義類名, 調用時指定該類名即可

小試牛刀

// [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) 復制代碼

代碼注釋:

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 屬性即對應了節點模板中模板的名稱, 若不填, 則會默認使用第一組模板
  • text 即 new go.Binding 綁定的數據

4.連接線數據集, 這里為空, 暫不討論

5.diagram.model 決定了頁面中呈現哪些元素, 我們創建一個普通連線實例 new go.GraphLinksModel 該構造函數接收兩個參數, 即之前創建的 nodeDataArray 和 linkDataArray

實戰演練

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

與節點模板一樣, 連接線模板也分 linkTemplate 和 linkTemplateMap 這里我們只介紹 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 相關的屬性, 則表示連接線的模板
  • 如果引入了 fromArrow 或 toArrow 則表示設置線段兩端的箭頭, 官方 figure 示例

3.同樣, 我們可以在線段中添加 Picture TextBlock Shape Panel 等任何元素, 並且編寫方式與節點模板是一致的, 只不過如果你想控制這些元素的偏移量, 你需要設置 alignmentFocus 屬性

4.之前說過, nodeDataArray 中的 key 是必填的, 因為我們需要在 linkDataArray 中通過這個 key 來絕點各個節點的連接線如何相連

下期繼續講 gojs 的編輯類模板

(未完待續)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM