gojs流程图绘制

//html 片段
//文件是自己做结合官网案例写的,好多地方可能不太正确。gojs感觉不是太好弄。配置感觉好繁琐
//里面有vue语法
  <div id="sample">
    <div style="width: 100%; display: flex; justify-content: space-between">
    //生成节点的面板盒子
      <div
        id="myPaletteDiv"
        style="width: 120px; margin-right: 2px; background-color: whitesmoke; border: solid 1px #606266"
      ></div>
      //gojs流程图显示区
      <div id="myDiagramDiv" style="flex-grow: 1; height: 620px; border: solid 1px #606266"></div>
    </div>
    //显示右上角的节点详情form表单
    <div  v-show="isShow" id="myInspectorDiv" class="inspector" style="position:fixed;top:100px;right:40px;z-index:2000;padding:30px;">
    </div>
  </div>
//JS代码片段 方法
 function init () {
     
      var $ = go.GraphObject.make // 用go.GraphObject.make来创建一个GoJS对象,如果$被占用了,可以使用其他名称
        
      // 创建图表对象,绑定HTML中的DIV,初始化图表风格
      this.myDiagram = $(
        go.Diagram,
        'myDiagramDiv', // must name or refer to the DIV HTML element
        {
        //点击初始化myDiagramDiv这个盒子区域非节点时触发
          click: () => {
            this.isShow = false 
          },
          //绘制网格
          grid: $(
            go.Panel,
            'Grid',
            $(go.Shape, 'LineH', { stroke: 'lightgray', strokeWidth: 0.5 }),
            $(go.Shape, 'LineH', {
              stroke: 'gray',
              strokeWidth: 0.5,
              interval: 10
            }),
            $(go.Shape, 'LineV', { stroke: 'lightgray', strokeWidth: 0.5 }),
            $(go.Shape, 'LineV', {
              stroke: 'gray',
              strokeWidth: 0.5,
              interval: 10
            })
          ),
          'draggingTool.dragsLink': true,
          'draggingTool.isGridSnapEnabled': true,
          'linkingTool.isUnconnectedLinkValid': true,
          'linkingTool.portGravity': 20,
          'relinkingTool.isUnconnectedLinkValid': true,
          'relinkingTool.portGravity': 20,
          'relinkingTool.fromHandleArchetype': $(go.Shape, 'Diamond', {
            segmentIndex: 0,
            cursor: 'pointer',
            desiredSize: new go.Size(8, 8),
            fill: 'tomato',
            stroke: 'darkred'
          }),
          'relinkingTool.toHandleArchetype': $(go.Shape, 'Diamond', {
            segmentIndex: -1,
            cursor: 'pointer',
            desiredSize: new go.Size(8, 8),
            fill: 'darkred',
            stroke: 'tomato'
          }),
          'linkReshapingTool.handleArchetype': $(go.Shape, 'Diamond', {
            desiredSize: new go.Size(7, 7),
            fill: 'lightblue',
            stroke: 'deepskyblue'
          }),
          'rotatingTool.handleAngle': 270,
          'rotatingTool.handleDistance': 30,
          'rotatingTool.snapAngleMultiple': 15,
          'rotatingTool.snapAngleEpsilon': 15,
          'undoManager.isEnabled': true
        }
      )
      var doClick = (e) => {
        this.isShow = true
      }
      // when the document is modified, add a "*" to the title and enable the "Save" button
      this.myDiagram.addDiagramListener('Modified', e => {
        var button = document.getElementById('SaveButton')
        if (button) button.disabled = !this.myDiagram.isModified
        var idx = document.title.indexOf('*')
        if (this.myDiagram.isModified) {
          if (idx < 0) document.title += '*'
        } else {
          if (idx >= 0) document.title = document.title.substr(0, idx)
        }
      })

       // 定义用于创建通常透明的“端口”的函数。
      // “ name”用作GraphObject.portId,“ spot”用于控制链接的连接方式
      // 端口在节点上的位置,以及布尔“ output”和“ input”参数
      // 控制用户是否可以从端口绘制链接或到端口。
        function makePort (name, spot, output, input) {
        // the port is basically just a small transparent circle
        return $(go.Shape, 'Circle', {
          fill: null, // 默认情况下不可见; 集由showSmallPorts半透明灰色,下面定义
          stroke: null,
          desiredSize: new go.Size(7, 7),
          alignment: spot, // 对齐在主形状的端口
          alignmentFocus: spot, // 只是在形状内部
          portId: name, // 将此对象声明为“端口”
          fromSpot: spot,
          toSpot: spot, // 声明链接可以在此端口连接的位置
          fromLinkable: output,
          toLinkable: input, // 声明用户是否可以在此处绘制到/从此处的链接
          cursor: 'pointer' // 显示不同的光标以指示潜在的链接点
        })
      }

      var nodeSelectionAdornmentTemplate = $(
        go.Adornment,
        'Auto',
        $(go.Shape, {
          fill: null,
          stroke: 'deepskyblue',
          strokeWidth: 1.5,
          strokeDashArray: [4, 2]
        }),
        $(go.Placeholder)
      )

      var nodeResizeAdornmentTemplate = $(
        go.Adornment,
        'Spot',
        { locationSpot: go.Spot.Right },
        $(go.Placeholder),
        $(go.Shape, {
          alignment: go.Spot.TopLeft,
          cursor: 'nw-resize',
          desiredSize: new go.Size(6, 6),
          fill: 'lightblue',
          stroke: 'deepskyblue'
        }),
        $(go.Shape, {
          alignment: go.Spot.Top,
          cursor: 'n-resize',
          desiredSize: new go.Size(6, 6),
          fill: 'lightblue',
          stroke: 'deepskyblue'
        }),
        $(go.Shape, {
          alignment: go.Spot.TopRight,
          cursor: 'ne-resize',
          desiredSize: new go.Size(6, 6),
          fill: 'lightblue',
          stroke: 'deepskyblue'
        }),

        $(go.Shape, {
          alignment: go.Spot.Left,
          cursor: 'w-resize',
          desiredSize: new go.Size(6, 6),
          fill: 'lightblue',
          stroke: 'deepskyblue'
        }),
        $(go.Shape, {
          alignment: go.Spot.Right,
          cursor: 'e-resize',
          desiredSize: new go.Size(6, 6),
          fill: 'lightblue',
          stroke: 'deepskyblue'
        }),

        $(go.Shape, {
          alignment: go.Spot.BottomLeft,
          cursor: 'se-resize',
          desiredSize: new go.Size(6, 6),
          fill: 'lightblue',
          stroke: 'deepskyblue'
        }),
        $(go.Shape, {
          alignment: go.Spot.Bottom,
          cursor: 's-resize',
          desiredSize: new go.Size(6, 6),
          fill: 'lightblue',
          stroke: 'deepskyblue'
        }),
        $(go.Shape, {
          alignment: go.Spot.BottomRight,
          cursor: 'sw-resize',
          desiredSize: new go.Size(6, 6),
          fill: 'lightblue',
          stroke: 'deepskyblue'
        })
      )

      var nodeRotateAdornmentTemplate = $(
        go.Adornment,
        { locationSpot: go.Spot.Center, locationObjectName: 'ELLIPSE' },
        $(go.Shape, 'Circle', {
          name: 'ELLIPSE',
          cursor: 'pointer',
          desiredSize: new go.Size(7, 7),
          fill: 'lightblue',
          stroke: '#ccc'
        }),
        $(go.Shape, {
          geometryString: 'M3.5 7 L3.5 30',
          isGeometryPositioned: true,
          stroke: '#ccc',
          strokeWidth: 1
          //   strokeDashArray: [4, 2]
        })
      )
		// 绘制默认节点信息
      this.myDiagram.nodeTemplate = $(
        go.Node,
        'Spot',
        { locationSpot: go.Spot.Center },
        new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(
          go.Point.stringify
        ),
        {
          selectable: true,
          selectionAdornmentTemplate: nodeSelectionAdornmentTemplate
        },
        {
          click: doClick
        },
        {
          resizable: true,
          resizeObjectName: 'PANEL',
          resizeAdornmentTemplate: nodeResizeAdornmentTemplate
        },
        {
          rotatable: true,
          rotateAdornmentTemplate: nodeRotateAdornmentTemplate
        },
        new go.Binding('angle').makeTwoWay(),
        // the main object is a Panel that surrounds a TextBlock with a Shape
        $(
          go.Panel,
          'Auto',
          { name: 'PANEL' },
          new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(
            go.Size.stringify
          ),
          $(
            go.Shape,
            'RoundedRectangle', // default figure
            {
              portId: '', // the default port: if no spot on link data, use closest side
              fromLinkable: true,
              toLinkable: true,
              cursor: 'pointer',
              fill: 'white', // default color
              stroke: '#ccc',
              strokeWidth: 1
            },
            new go.Binding('figure'),
            new go.Binding('fill')
          ),
          $(
            go.TextBlock,
            {
              font: 'bold 11pt Helvetica, Arial, sans-serif',
              margin: 2,
              maxSize: new go.Size(160, NaN),
              wrap: go.TextBlock.WrapFit,
              editable: false
            },
            new go.Binding('text').makeTwoWay()
          )
        ),
        // four small named ports, one on each side:
        makePort('T', go.Spot.Top, false, true),
        makePort('L', go.Spot.Left, true, true),
        makePort('R', go.Spot.Right, true, true),
        makePort('B', go.Spot.Bottom, true, false),
        {
          // handle mouse enter/leave events to show/hide the ports
          mouseEnter: function (e, node) {
            showSmallPorts(node, true)
          },
          mouseLeave: function (e, node) {
            showSmallPorts(node, false)
          }
        }
      )
      //其他类型节点信息配置包括开始与结束
      //fromLinkable 控制不同不接是否可作为起点,toLinkable 是否可被链接
      var nodeShap = (fromLinkable = true, toLinkable = true) => {
        return $(
          go.Node,
          'Spot',
          { desiredSize: new go.Size(50, 50), locationSpot: go.Spot.Center },
          new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(
            go.Point.stringify
          ),
          {
            selectable: true,
            selectionAdornmentTemplate: nodeSelectionAdornmentTemplate
          },
          {
            click: doClick//节点点击事件
          },
          {
            resizable: true,
            resizeObjectName: 'PANEL',
            resizeAdornmentTemplate: nodeResizeAdornmentTemplate
          },
          {
            rotatable: true,
            rotateAdornmentTemplate: nodeRotateAdornmentTemplate
          },
          new go.Binding('angle').makeTwoWay(),
          $(
            go.Panel,
            'Auto',
            { name: 'PANEL' },
            new go.Binding('desiredSize', 'size', go.Size.parse).makeTwoWay(
              go.Size.stringify
            ),
            $(
              go.Picture, // the icon showing the logo
              {
                width: 50,
                height: 50,
                portId: '', // the default port: if no spot on link data, use closest side
                fromLinkable,
                toLinkable,
                cursor: 'pointer'
              },
              new go.Binding('source', 'type', type => {
                console.log(type, 'type')
                return require(`../../../common/flow/img/16/${type}.png`)
              })
            ),
            $(
              go.TextBlock,
              {
                font: 'bold 11pt Helvetica, Arial, sans-serif',
                margin: 2,
                maxSize: new go.Size(160, NaN),
                wrap: go.TextBlock.WrapFit,
                editable: false
              },
              new go.Binding('textBlock').makeTwoWay()
            )

          ),
          makePort('T', go.Spot.Top, false, true),
          makePort('L', go.Spot.Left, true, true),
          makePort('R', go.Spot.Right, true, true),
          makePort('B', go.Spot.Bottom, true, false)
        )
      }
      //添加其他类型节点信息
      this.myDiagram.nodeTemplateMap.add('Pictrue', nodeShap())
      this.myDiagram.nodeTemplateMap.add('Start', nodeShap(true, false))
      this.myDiagram.nodeTemplateMap.add('End', nodeShap(true, false))
      function showSmallPorts (node, show) {
        node.ports.each(function (port) {
          if (port.portId !== '') {
            // don't change the default port, which is the big shape
            port.fill = show ? 'rgba(0,0,0,.3)' : null
          }
        })
      }
      var linkSelectionAdornmentTemplate = $(
        go.Adornment,
        'Link',
        $(
          go.Shape,
          // isPanelMain declares that this Shape shares the Link.geometry
          {
            isPanelMain: true,
            fill: null,
            stroke: 'deepskyblue',
            strokeWidth: 0
          }
        ) // use selection object's strokeWidth
      )

      this.myDiagram.linkTemplate = $(
        go.Link, // the whole link panel
        {
          selectable: true,
          selectionAdornmentTemplate: linkSelectionAdornmentTemplate
        },
        { relinkableFrom: true, relinkableTo: true, reshapable: true },
        {
          routing: go.Link.AvoidsNodes,
          curve: go.Link.JumpOver,
          corner: 5,
          toShortLength: 4
        },
        new go.Binding('points').makeTwoWay(),
        $(
          go.Shape, // the link path shape
          { isPanelMain: true, strokeWidth: 2 }
        ),
        $(
          go.Shape, // the arrowhead
          { toArrow: 'Standard', stroke: null }
        ),
        $(
          go.Panel,
          'Auto',
          new go.Binding('visible', 'isSelected').ofObject(),
          $(
            go.Shape,
            'RoundedRectangle', // the link shape
            { fill: '#F8F8F8', stroke: null }
          ),
          $(
            go.TextBlock,
            {
              textAlign: 'center',
              font: '10pt helvetica, arial, sans-serif',
              stroke: '#919191',
              margin: 2,
              minSize: new go.Size(10, NaN),
              editable: true
            },
            new go.Binding('text').makeTwoWay()
          )
        )
      )
      //   load() // load an initial diagram from some JSON text

      // initialize the Palette that is on the left side of the page
      this.myPalette = $(
        go.Palette,
        'myPaletteDiv', // must name or refer to the DIV HTML element
        {
          maxSelectionCount: 1,
          nodeTemplateMap: this.myDiagram.nodeTemplateMap, // share the templates used by myDiagram
          // simplify the link template, just in this Palette
          linkTemplate: $(
            go.Link,
            {
              // because the GridLayout.alignment is Location and the nodes have locationSpot == Spot.Center,
              // to line up the Link in the same manner we have to pretend the Link has the same location spot
              locationSpot: go.Spot.Center,
              selectionAdornmentTemplate: $(
                go.Adornment,
                'Link',
                { locationSpot: go.Spot.Center },
                $(go.Shape, {
                  isPanelMain: true,
                  fill: null,
                  stroke: 'deepskyblue',
                  strokeWidth: 0
                }),
                $(
                  go.Shape, // the arrowhead
                  { toArrow: 'Standard', stroke: null }
                )
              )
            },
            {
              routing: go.Link.AvoidsNodes,
              curve: go.Link.JumpOver,
              corner: 5,
              toShortLength: 4
            },
            new go.Binding('points'),
            $(
              go.Shape, // the link path shape
              { isPanelMain: true, strokeWidth: 2 }
            ),
            $(
              go.Shape, // the arrowhead
              { toArrow: 'Standard', stroke: null }
            )
          ),
          model: new go.GraphLinksModel(
            [
              // specify the contents of the Palette
              {
                text: '开始',
                figure: 'ELLIPSE',
                type: 'start',
                category: 'Start',
                textBlock: '   ',
                size: '50 50',
                en_us_stepname: 'start'
              },
              { text: '处理', itype: '处理', en_us_stepname: 'deal', size: '100 50', imode: '默认', type: 'deal', fill: '#FDF5E6' },
              { text: '审批', itype: '审批', en_us_stepname: 'task', size: '100 50', imode: '默认', type: 'task', fill: '#FDF5E6' },
              {
                text: '结束',
                figure: 'Ellipse',
                category: 'End',
                type: 'end',
                size: '50 50',
                textBlock: '   '
              },
              {
                text: '分支',
                figure: 'Ellipse',
                category: 'Pictrue',
                type: 'fork',
                size: '50 50',
                textBlock: '   '
              },
              {
                text: '合并',
                figure: 'Ellipse',
                category: 'Pictrue',
                type: 'join',
                size: '50 50',
                textBlock: '   '
              }
            ],
            [
              // the Palette also has a disconnected Link, which the user can drag-and-drop
              {
                points: new go.List(/* go.Point */).addAll([
                  new go.Point(0, 0),
                  new go.Point(30, 0),
                  new go.Point(30, 40),
                  new go.Point(60, 40)
                ])
              }
            ]
          )
        }
      )
      var show = ({ part }, propName) => {
        var data = part.data
        return data.type === 'deal' || data.type === 'task'
      }
      //节点的详情编辑及显示
      this.inspector = new Inspector('myInspectorDiv', this.myDiagram, {
        // uncomment this line to only inspect the named properties below instead of all properties on each object:
        // includesOwnProperties: false,
        properties: {
          // string|number|boolean|color|arrayofnumber|point|rect|size|spot|margin|select
          text: {
            label: '名称'
          },
          // 名称: {},
          en_us_stepname: {
            label: '英文名称',
            show ({ part }, propName) {
              var type = part.data.type
              return type !== 'fork' && type !== 'join'
            }
            // type: 'button',
            // icon: 'zyrf-chaxun',
            // callback (e) {
            //   console.log(e, 'dddd')
            //   e.value += 1
            //   var event = new Event('change')
            //   e.dispatchEvent(event)
            // }
          },
          stepcode: {
            label: '编号',
            show
          },
          itype: {
            label: '类型',
            show,
            defaultValue: this.isTask ? '审批' : '处理',
            readOnly: true
          },
          imode: {
            label: '模式',
            type: 'select',
            show,
            choices: () => ['默认', '抢占']
          },
          grant: {
            label: '转批',
            type: 'select',
            show,
            defaultValue: '不可转批',
            choices: () => ['不可转批', '可转批']
          },
          ihandler: {
            label: '范围',
            type: 'select',
            show,
            defaultValue: '所有用户',
            choices: () => ['所有用户', '固定用户', '用户组', '角色', '发起者']
          },
          beginset: {
            label: '发起指定',
            type: 'select',
            show,
            defaultValue: '否',
            choices: () => ['是', '否']
          },
          formid: {
            label: '表单',
            type: 'button',
            icon: 'zyrf-chaxun',
            show,
            callback (e) {
              console.log(e, 'dddd')
              e.value += 1
              var event = new Event('change')
              e.dispatchEvent(event)
            }
          },
          // key would be automatically added for nodes, but we want to declare it read-only also:
          key: { readOnly: true, show: false },
          // color would be automatically added for nodes, but we want to declare it a color also:
          category: { show: false },
          figure: { show: false },
          type: { show: false },
          size: { show: false },
          fill: { show: false },
          loc: { show: false }
        }
      })
    }
//被引用的 构造函数Inspector的js文件
//与官网源文件相比添加了以button类型 就是input 框后面有一个button按钮。主要用来做弹出页面进行选择信息的功能
/* eslint-disable no-redeclare */
'use strict'
import go from './go'
/*
*  Copyright (C) 1998-2021 by Northwoods Software Corporation. All Rights Reserved.
*/

/**
  This class implements an inspector for GoJS model data objects.
  The constructor takes three arguments:
    {string} divid a string referencing the HTML ID of the to-be inspector's div.
    {Diagram} diagram a reference to a GoJS Diagram.
    {Object} options An optional JS Object describing options for the inspector.

  Options:
    inspectSelection {boolean} Default true, whether to automatically show and populate the Inspector
                               with the currently selected Diagram Part. If set to false, the inspector won't show anything
                               until you call Inspector.inspectObject(object) with a Part or JavaScript object as the argument.
    includesOwnProperties {boolean} Default true, whether to list all properties currently on the inspected data object.
    properties {Object} An object of string:Object pairs representing propertyName:propertyOptions.
                        Can be used to include or exclude additional properties.
    propertyModified function(propertyName, newValue) a callback
    multipleSelection {boolean} Default false, whether to allow multiple selection and change the properties of all the selected instead of
                                the single first object
    showAllProperties {boolean} Default false, whether properties that are shown with multipleSelection use the intersect of the properties when false or the union when true
                                only affects if multipleSelection is true
    showSize {number} Defaults 0, shows how many nodes are showed when selecting multiple nodes
                      when its lower than 1, it shows all nodes

  Options for properties:
    show: {boolean|function} a boolean value to show or hide the property from the inspector, or a predicate function to show conditionally.
    readOnly: {boolean|function} whether or not the property is read-only
    type: {string} a string describing the data type. Supported values: "string|number|boolean|color|arrayofnumber|point|rect|size|spot|margin|select"
    defaultValue: {*} a default value for the property. Defaults to the empty string.
    choices: {Array|function} when type == "select", the Array of choices to use or a function that returns the Array of choices.

  Example usage of Inspector:

  var inspector = new Inspector("myInspector", myDiagram,
    {
      includesOwnProperties: false,
      properties: {
        "key": { show: Inspector.showIfPresent, readOnly: true },
        "comments": { show: Inspector.showIfNode  },
        "LinkComments": { show: Inspector.showIfLink },
        "chosen": { show: Inspector.showIfNode, type: "checkbox" },
        "state": { show: Inspector.showIfNode, type: "select", choices: ["Stopped", "Parked", "Moving"] }
      }
    });

  This is the basic HTML Structure that the Inspector creates within the given DIV element:

  <div id="divid" class="inspector">
    <tr>
      <td>propertyName</td>
      <td><input value=propertyValue /></td>
    </tr>
    ...
  </div>

*/
export function Inspector (divid, diagram, options) {
  var mainDiv = document.getElementById(divid)
  mainDiv.className = 'inspector'
  mainDiv.innerHTML = ''
  this._div = mainDiv
  this._diagram = diagram
  this._inspectedProperties = {}
  this._multipleProperties = {}

  // Either a GoJS Part or a simple data object, such as Model.modelData
  this.inspectedObject = null

  // Inspector options defaults:
  this.includesOwnProperties = true
  this.declaredProperties = {}
  this.inspectsSelection = true
  this.propertyModified = null
  this.multipleSelection = false
  this.showAllProperties = false
  this.showSize = 0

  if (options !== undefined) {
    if (options.includesOwnProperties !== undefined) this.includesOwnProperties = options.includesOwnProperties
    if (options.properties !== undefined) this.declaredProperties = options.properties
    if (options.inspectSelection !== undefined) this.inspectsSelection = options.inspectSelection
    if (options.propertyModified !== undefined) this.propertyModified = options.propertyModified
    if (options.multipleSelection !== undefined) this.multipleSelection = options.multipleSelection
    if (options.showAllProperties !== undefined) this.showAllProperties = options.showAllProperties
    if (options.showSize !== undefined) this.showSize = options.showSize
  }

  var self = this
  diagram.addModelChangedListener(function (e) {
    if (e.isTransactionFinished) self.inspectObject()
  })
  if (this.inspectsSelection) {
    diagram.addDiagramListener('ChangedSelection', function (e) { self.inspectObject() })
  }
}

// Some static predicates to use with the "show" property.
Inspector.showIfNode = function (part) { return part instanceof go.Node }
Inspector.showIfLink = function (part) { return part instanceof go.Link }
Inspector.showIfGroup = function (part) { return part instanceof go.Group }

// Only show the property if its present. Useful for "key" which will be shown on Nodes and Groups, but normally not on Links
Inspector.showIfPresent = function (data, propname) {
  console.log()
  if (data instanceof go.Part) data = data.data
  return typeof data === 'object' && data[propname] !== undefined
}

/**
* Update the HTML state of this Inspector given the properties of the {@link #inspectedObject}.
* @param {Object} object is an optional argument, used when {@link #inspectSelection} is false to
*                        set {@link #inspectedObject} and show and edit that object's properties.
*/
Inspector.prototype.inspectObject = function (object) {
  var inspectedObject = null
  var inspectedObjects = null
  if (object === null) return
  if (object === undefined) {
    if (this.inspectsSelection) {
      if (this.multipleSelection) { // gets the selection if multiple selection is true
        inspectedObjects = this._diagram.selection
      } else { // otherwise grab the first object
        inspectedObject = this._diagram.selection.first()
      }
    } else { // if there is a single inspected object
      inspectedObject = this.inspectedObject
    }
  } else { // if object was passed in as a parameter
    inspectedObject = object
  }
  if (inspectedObjects && inspectedObjects.count === 1) {
    inspectedObject = inspectedObjects.first()
  }
  if (inspectedObjects && inspectedObjects.count <= 1) {
    inspectedObjects = null
  }

  // single object or no objects
  if (!inspectedObjects || !this.multipleSelection) {
    if (inspectedObject === null) {
      this.inspectedObject = inspectedObject
      this.updateAllHTML()
      return
    }

    this.inspectedObject = inspectedObject
    if (this.inspectObject === null) return
    var mainDiv = this._div
    mainDiv.innerHTML = ''

    // use either the Part.data or the object itself (for model.modelData)
    var data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject
    if (!data) return
    // Build table:
    var table = document.createElement('table')
    var tbody = document.createElement('tbody')
    this._inspectedProperties = {}
    this.tabIndex = 0
    var declaredProperties = this.declaredProperties

    // Go through all the properties passed in to the inspector and show them, if appropriate:
    for (var name in declaredProperties) {
      var desc = declaredProperties[name]
      if (!this.canShowProperty(name, desc, inspectedObject)) continue
      var val = this.findValue(name, desc, data)
      console.log(name, data, desc, 'dd')
      tbody.appendChild(this.buildPropertyRow(name, val, desc))
    }
    // Go through all the properties on the model data and show them, if appropriate:
    if (this.includesOwnProperties) {
      for (var k in data) {
        if (k === '__gohashid') continue // skip internal GoJS hash property
        if (this._inspectedProperties[k]) continue // already exists
        if (declaredProperties[k] && !this.canShowProperty(k, declaredProperties[k], inspectedObject)) continue
        console.log(k, data, 'dd')
        tbody.appendChild(this.buildPropertyRow(k, data[k]))
      }
    }

    table.appendChild(tbody)
    mainDiv.appendChild(table)
  } else { // multiple objects selected
    var mainDiv = this._div
    mainDiv.innerHTML = ''
    var shared = new go.Map() // for properties that the nodes have in common
    var properties = new go.Map() // for adding properties
    var all = new go.Map() // used later to prevent changing properties when unneeded
    var it = inspectedObjects.iterator
    // Build table:
    var table = document.createElement('table')
    var tbody = document.createElement('tbody')
    this._inspectedProperties = {}
    this.tabIndex = 0
    var declaredProperties = this.declaredProperties
    it.next()
    inspectedObject = it.value
    this.inspectedObject = inspectedObject
    var data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject
    if (data) { // initial pass to set shared and all
      // Go through all the properties passed in to the inspector and add them to the map, if appropriate:
      for (var name in declaredProperties) {
        var desc = declaredProperties[name]
        if (!this.canShowProperty(name, desc, inspectedObject)) continue
        var val = this.findValue(name, desc, data)
        if (val === '' && desc && desc.type === 'checkbox') {
          shared.add(name, false)
          all.add(name, false)
        } else {
          shared.add(name, val)
          all.add(name, val)
        }
      }
      // Go through all the properties on the model data and add them to the map, if appropriate:
      if (this.includesOwnProperties) {
        for (var k in data) {
          if (k === '__gohashid') continue // skip internal GoJS hash property
          if (this._inspectedProperties[k]) continue // already exists
          if (declaredProperties[k] && !this.canShowProperty(k, declaredProperties[k], inspectedObject)) continue
          shared.add(k, data[k])
          all.add(k, data[k])
        }
      }
    }
    var nodecount = 2
    while (it.next() && (this.showSize < 1 || nodecount <= this.showSize)) { // grabs all the properties from the other selected objects
      properties.clear()
      inspectedObject = it.value
      if (inspectedObject) {
        // use either the Part.data or the object itself (for model.modelData)
        data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject
        if (data) {
          // Go through all the properties passed in to the inspector and add them to properties to add, if appropriate:
          for (var name in declaredProperties) {
            var desc = declaredProperties[name]
            if (!this.canShowProperty(name, desc, inspectedObject)) continue
            var val = this.findValue(name, desc, data)
            if (val === '' && desc && desc.type === 'checkbox') {
              properties.add(name, false)
            } else {
              properties.add(name, val)
            }
          }
          // Go through all the properties on the model data and add them to properties to add, if appropriate:
          if (this.includesOwnProperties) {
            for (var k in data) {
              if (k === '__gohashid') continue // skip internal GoJS hash property
              if (this._inspectedProperties[k]) continue // already exists
              if (declaredProperties[k] && !this.canShowProperty(k, declaredProperties[k], inspectedObject)) continue
              properties.add(k, data[k])
            }
          }
        }
      }
      if (!this.showAllProperties) {
        // Cleans up shared map with properties that aren't shared between the selected objects
        // Also adds properties to the add and shared maps if applicable
        var addIt = shared.iterator
        var toRemove = []
        while (addIt.next()) {
          if (properties.has(addIt.key)) {
            var newVal = all.get(addIt.key) + '|' + properties.get(addIt.key)
            all.set(addIt.key, newVal)
            if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color' &&
              declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select') ||
              !declaredProperties[addIt.key]) { // for non-string properties i.e color
              newVal = shared.get(addIt.key) + '|' + properties.get(addIt.key)
              shared.set(addIt.key, newVal)
            }
          } else { // toRemove array since addIt is still iterating
            toRemove.push(addIt.key)
          }
        }
        for (var i = 0; i < toRemove.length; i++) { // removes anything that doesn't showAllPropertiess
          shared.remove(toRemove[i])
          all.remove(toRemove[i])
        }
      } else {
        // Adds missing properties to all with the correct amount of seperators
        var addIt = properties.iterator
        console.log(addIt, 'addIt')
        while (addIt.next()) {
          if (all.has(addIt.key)) {
            if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color' &&
              declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select') ||
              !declaredProperties[addIt.key]) { // for non-string properties i.e color
              var newVal = all.get(addIt.key) + '|' + properties.get(addIt.key)
              all.set(addIt.key, newVal)
            }
          } else {
            var newVal = ''
            for (var i = 0; i < nodecount - 1; i++) newVal += '|'
            newVal += properties.get(addIt.key)
            all.set(addIt.key, newVal)
          }
        }
        // Adds bars in case properties is not in all
        addIt = all.iterator
        while (addIt.next()) {
          if (!properties.has(addIt.key)) {
            if ((declaredProperties[addIt.key] && declaredProperties[addIt.key].type !== 'color' &&
              declaredProperties[addIt.key].type !== 'checkbox' && declaredProperties[addIt.key].type !== 'select') ||
              !declaredProperties[addIt.key]) { // for non-string properties i.e color
              var newVal = all.get(addIt.key) + '|'
              all.set(addIt.key, newVal)
            }
          }
        }
      }
      nodecount++
    }
    // builds the table property rows and sets multipleProperties to help with updateall
    var mapIt
    if (!this.showAllProperties) mapIt = shared.iterator
    else mapIt = all.iterator
    console.log(mapIt, 'mapIt')
    while (mapIt.next()) {
      tbody.appendChild(this.buildPropertyRow(mapIt.key, mapIt.value)) // shows the properties that are allowed
    }
    table.appendChild(tbody)
    mainDiv.appendChild(table)
    var allIt = all.iterator
    while (allIt.next()) {
      this._multipleProperties[allIt.key] = allIt.value // used for updateall to know which properties to change
    }
  }
}

/**
* @ignore
* This predicate should be false if the given property should not be shown.
* Normally it only checks the value of "show" on the property descriptor.
* The default value is true.
* @param {string} propertyName the property name
* @param {Object} propertyDesc the property descriptor
* @param {Object} inspectedObject the data object
* @return {boolean} whether a particular property should be shown in this Inspector
*/
Inspector.prototype.canShowProperty = function (propertyName, propertyDesc, inspectedObject) {
  if (propertyDesc.show === false) return false
  // if "show" is a predicate, make sure it passes or do not show this property
  if (typeof propertyDesc.show === 'function') return propertyDesc.show(inspectedObject, propertyName)
  return true
}

/**
* @ignore
* This predicate should be false if the given property should not be editable by the user.
* Normally it only checks the value of "readOnly" on the property descriptor.
* The default value is true.
* @param {string} propertyName the property name
* @param {Object} propertyDesc the property descriptor
* @param {Object} inspectedObject the data object
* @return {boolean} whether a particular property should be shown in this Inspector
*/
Inspector.prototype.canEditProperty = function (propertyName, propertyDesc, inspectedObject) {
  if (this._diagram.isReadOnly || this._diagram.isModelReadOnly) return false
  // assume property values that are functions of Objects cannot be edited
  var data = (inspectedObject instanceof go.Part) ? inspectedObject.data : inspectedObject
  var valtype = typeof data[propertyName]
  if (valtype === 'function') return false
  if (propertyDesc) {
    if (propertyDesc.readOnly === true) return false
    // if "readOnly" is a predicate, make sure it passes or do not show this property
    if (typeof propertyDesc.readOnly === 'function') return !propertyDesc.readOnly(inspectedObject, propertyName)
  }
  return true
}

/**
 * @ignore
 * @param {any} propName
 * @param {any} propDesc
 * @param {any} data
 * @return {any}
 */
Inspector.prototype.findValue = function (propName, propDesc, data) {
  var val = ''
  if (propDesc && propDesc.defaultValue !== undefined) val = propDesc.defaultValue
  if (data[propName] !== undefined) val = data[propName]
  if (val === undefined) return ''
  return val
}

/**
* @ignore
* This sets this._inspectedProperties[propertyName] and creates the HTML table row:
*    <tr>
*      <td>propertyName</td>
*      <td><input value=propertyValue /></td>
*    </tr>
* @param {string} propertyName the property name
* @param {*} propertyValue the property value
* @return the table row
*/
Inspector.prototype.buildPropertyRow = function (propertyName, propertyValue, desc = {}) {
  var mainDiv = this._div
  console.log(propertyName, propertyValue)
  var tr = document.createElement('tr')
  var td1 = document.createElement('td')
  td1.textContent = desc.label || propertyName
  tr.appendChild(td1)

  var td2 = document.createElement('td')
  var decProp = this.declaredProperties[propertyName]
  var input = null
  var div = null
  var self = this
  function updateall () {
    console.log(1222)
    self.updateAllProperties()
  }

  if (decProp && decProp.type === 'select') {
    input = document.createElement('select')
    this.updateSelect(decProp, input, propertyName, propertyValue)
    input.addEventListener('change', updateall)
  } else {
    input = document.createElement('input')
    input.value = this.convertToString(propertyValue)
    if (decProp && decProp.type === 'button') {
      var div = document.createElement('div')
      div.classList.add('box-input')
      div.appendChild(input)
      input.disabled = true
      input.classList.add('buttonInput')
      var buttonBox = document.createElement('div')
      buttonBox.style = 'display: table-cell'
      buttonBox.innerHTML = `<button style="font: bold 12px helvetica, sans-serif; display: inline-block" type="button">
                                   <i class='icon iconfont ${decProp.icon}'>${decProp.text || ''}</i>
                              </button>`
      div.appendChild(buttonBox)
      buttonBox.querySelector('button').onclick = decProp.callback.bind(null, input)
    }
    if (decProp) {
      var t = decProp.type
      if (t !== 'string' && t !== 'number' && t !== 'boolean' &&
          t !== 'arrayofnumber' && t !== 'point' && t !== 'size' &&
          t !== 'rect' && t !== 'spot' && t !== 'margin' && t !== 'button') {
        input.setAttribute('type', decProp.type)
      }
      if (decProp.type === 'color') {
        if (input.type === 'color') {
          input.value = this.convertToColor(propertyValue)
          // input.addEventListener("input", updateall);
          input.addEventListener('change', updateall)
        }
      } if (decProp.type === 'checkbox') {
        input.checked = !!propertyValue
        input.addEventListener('change', updateall)
      }
      if (decProp.type === 'button') {
        input.addEventListener('change', updateall)
      }
    }

    if (input.type !== 'color' && input.type !== 'button') input.addEventListener('blur', updateall)
  }

  if (input) {
    input.tabIndex = this.tabIndex++
    input.disabled = (!this.canEditProperty(propertyName, decProp, this.inspectedObject)) || (decProp && decProp.type === 'button')
    td2.appendChild(decProp && decProp.type === 'button' ? div : input)
  }
  tr.appendChild(td2)

  this._inspectedProperties[propertyName] = input
  return tr
}

/**
* @ignore
* HTML5 color input will only take hex,
* so var HTML5 canvas convert the color into hex format.
* This converts "rgb(255, 0, 0)" into "#FF0000", etc.
* @param {string} propertyValue
* @return {string}
*/
Inspector.prototype.convertToColor = function (propertyValue) {
  var ctx = document.createElement('canvas').getContext('2d')
  ctx.fillStyle = propertyValue
  return ctx.fillStyle
}

/**
* @ignore
* @param {string}
* @return {Array.<number>}
*/
Inspector.prototype.convertToArrayOfNumber = function (propertyValue) {
  if (propertyValue === 'null') return null
  var split = propertyValue.split(' ')
  var arr = []
  for (var i = 0; i < split.length; i++) {
    var str = split[i]
    if (!str) continue
    arr.push(parseFloat(str))
  }
  return arr
}

/**
* @ignore
* @param {*}
* @return {string}
*/
Inspector.prototype.convertToString = function (x) {
  if (x === undefined) return 'undefined'
  if (x === null) return 'null'
  if (x instanceof go.Point) return go.Point.stringify(x)
  if (x instanceof go.Size) return go.Size.stringify(x)
  if (x instanceof go.Rect) return go.Rect.stringify(x)
  if (x instanceof go.Spot) return go.Spot.stringify(x)
  if (x instanceof go.Margin) return go.Margin.stringify(x)
  if (x instanceof go.List) return this.convertToString(x.toArray())
  if (Array.isArray(x)) {
    var str = ''
    for (var i = 0; i < x.length; i++) {
      if (i > 0) str += ' '
      var v = x[i]
      str += this.convertToString(v)
    }
    return str
  }
  return x.toString()
}

/**
* @ignore
* Update all of the HTML in this Inspector.
*/
Inspector.prototype.updateAllHTML = function () {
  var inspectedProps = this._inspectedProperties
  var diagram = this._diagram
  var isPart = this.inspectedObject instanceof go.Part
  var data = isPart ? this.inspectedObject.data : this.inspectedObject
  if (!data) { // clear out all of the fields
    for (var name in inspectedProps) {
      var input = inspectedProps[name]
      if (input instanceof HTMLSelectElement) {
        input.innerHTML = ''
      } else if (input.type === 'color') {
        input.value = '#000000'
      } else if (input.type === 'checkbox') {
        input.checked = false
      } else {
        input.value = ''
      }
    }
  } else {
    for (var name in inspectedProps) {
      var input = inspectedProps[name]
      var propertyValue = data[name]
      if (input instanceof HTMLSelectElement) {
        var decProp = this.declaredProperties[name]
        this.updateSelect(decProp, input, name, propertyValue)
      } else if (input.type === 'color') {
        input.value = this.convertToColor(propertyValue)
      } else if (input.type === 'checkbox') {
        input.checked = !!propertyValue
      } else {
        input.value = this.convertToString(propertyValue)
      }
    }
  }
}

/**
* @ignore
* Update an HTMLSelectElement with an appropriate list of choices, given the propertyName
*/
Inspector.prototype.updateSelect = function (decProp, select, propertyName, propertyValue) {
  select.innerHTML = '' // clear out anything that was there
  var choices = decProp.choices
  if (typeof choices === 'function') choices = choices(this.inspectedObject, propertyName)
  if (!Array.isArray(choices)) choices = []
  decProp.choicesArray = choices // remember list of actual choice values (not strings)
  for (var i = 0; i < choices.length; i++) {
    var choice = choices[i]
    var opt = document.createElement('option')
    opt.text = this.convertToString(choice)
    select.add(opt, null)
  }
  select.value = this.convertToString(propertyValue)
}

/**
* @ignore
* Update all of the data properties of {@link #inspectedObject} according to the
* current values held in the HTML input elements.
*/
Inspector.prototype.updateAllProperties = function () {
  var inspectedProps = this._inspectedProperties
  var diagram = this._diagram
  if (diagram.selection.count === 1 || !this.multipleSelection) { // single object update
    var isPart = this.inspectedObject instanceof go.Part
    var data = isPart ? this.inspectedObject.data : this.inspectedObject
    if (!data) return // must not try to update data when there's no data!
    diagram.startTransaction('set all properties')
    for (var name in inspectedProps) {
      var input = inspectedProps[name]
      var value = input.value

      // don't update "readOnly" data properties
      var decProp = this.declaredProperties[name]
      if (!this.canEditProperty(name, decProp, this.inspectedObject)) continue

      // If it's a boolean, or if its previous value was boolean,
      // parse the value to be a boolean and then update the input.value to match
      var type = ''
      if (decProp !== undefined && decProp.type !== undefined && decProp.type !== 'button') {
        type = decProp.type
      }
      if (type === '') {
        var oldval = data[name]
        if (typeof oldval === 'boolean') type = 'boolean' // infer boolean
        else if (typeof oldval === 'number') type = 'number'
        else if (oldval instanceof go.Point) type = 'point'
        else if (oldval instanceof go.Size) type = 'size'
        else if (oldval instanceof go.Rect) type = 'rect'
        else if (oldval instanceof go.Spot) type = 'spot'
        else if (oldval instanceof go.Margin) type = 'margin'
      }

      // convert to specific type, if needed
      switch (type) {
        case 'boolean': value = !(value === false || value === 'false' || value === '0'); break
        case 'number': value = parseFloat(value); break
        case 'arrayofnumber': value = this.convertToArrayOfNumber(value); break
        case 'point': value = go.Point.parse(value); break
        case 'size': value = go.Size.parse(value); break
        case 'rect': value = go.Rect.parse(value); break
        case 'spot': value = go.Spot.parse(value); break
        case 'margin': value = go.Margin.parse(value); break
        case 'checkbox': value = input.checked; break
        case 'select': value = decProp.choicesArray[input.selectedIndex]; break
      }

      // in case parsed to be different, such as in the case of boolean values,
      // the value shown should match the actual value
      input.value = value

      // modify the data object in an undo-able fashion
      diagram.model.setDataProperty(data, name, value)

      // notify any listener
      if (this.propertyModified !== null) this.propertyModified(name, value, this)
    }
    diagram.commitTransaction('set all properties')
  } else { // selection object update
    diagram.startTransaction('set all properties')
    for (var name in inspectedProps) {
      var input = inspectedProps[name]
      var value = input.value
      var arr1 = value.split('|')
      var arr2 = []
      if (this._multipleProperties[name]) {
        // don't split if it is union and its checkbox type
        if (this.declaredProperties[name] && this.declaredProperties[name].type === 'checkbox' && this.showAllProperties) {
          arr2.push(this._multipleProperties[name])
        } else {
          arr2 = this._multipleProperties[name].toString().split('|')
        }
      }
      var it = diagram.selection.iterator
      var change = false
      if (this.declaredProperties[name] && this.declaredProperties[name].type === 'checkbox') change = true // always change checkbox
      if (arr1.length < arr2.length && // i.e Alpha|Beta -> Alpha procs the change
        (!this.declaredProperties[name] || // from and to links
          !(this.declaredProperties[name] && // do not change color checkbox and choices due to them always having less
            (this.declaredProperties[name].type === 'color' || this.declaredProperties[name].type === 'checkbox' || this.declaredProperties[name].type === 'choices')))) {
        change = true
      } else { // standard detection in change in properties
        for (var j = 0; j < arr1.length && j < arr2.length; j++) {
          if (!(arr1[j] === arr2[j]) &&
            !(this.declaredProperties[name] && this.declaredProperties[name].type === 'color' && arr1[j].toLowerCase() === arr2[j].toLowerCase())) {
            change = true
          }
        }
      }
      if (change) { // only change properties it needs to change instead all of them
        for (var i = 0; i < diagram.selection.count; i++) {
          it.next()
          var isPart = it.value instanceof go.Part
          var data = isPart ? it.value.data : it.value

          if (data) { // ignores the selected node if there is no data
            if (i < arr1.length) value = arr1[i]
            else value = arr1[0]

            // don't update "readOnly" data properties
            var decProp = this.declaredProperties[name]
            if (!this.canEditProperty(name, decProp, it.value)) continue

            // If it's a boolean, or if its previous value was boolean,
            // parse the value to be a boolean and then update the input.value to match
            var type = ''
            if (decProp !== undefined && decProp.type !== undefined && decProp.type !== 'button') {
              type = decProp.type
            }
            if (type === '') {
              var oldval = data[name]
              if (typeof oldval === 'boolean') type = 'boolean' // infer boolean
              else if (typeof oldval === 'number') type = 'number'
              else if (oldval instanceof go.Point) type = 'point'
              else if (oldval instanceof go.Size) type = 'size'
              else if (oldval instanceof go.Rect) type = 'rect'
              else if (oldval instanceof go.Spot) type = 'spot'
              else if (oldval instanceof go.Margin) type = 'margin'
            }

            // convert to specific type, if needed
            switch (type) {
              case 'boolean': value = !(value === false || value === 'false' || value === '0'); break
              case 'number': value = parseFloat(value); break
              case 'arrayofnumber': value = this.convertToArrayOfNumber(value); break
              case 'point': value = go.Point.parse(value); break
              case 'size': value = go.Size.parse(value); break
              case 'rect': value = go.Rect.parse(value); break
              case 'spot': value = go.Spot.parse(value); break
              case 'margin': value = go.Margin.parse(value); break
              case 'checkbox': value = input.checked; break
              case 'select': value = decProp.choicesArray[input.selectedIndex]; break
            }

            // in case parsed to be different, such as in the case of boolean values,
            // the value shown should match the actual value
            input.value = value

            // modify the data object in an undo-able fashion
            diagram.model.setDataProperty(data, name, value)

            // notify any listener
            if (this.propertyModified !== null) this.propertyModified(name, value, this)
          }
        }
      }
    }
    diagram.commitTransaction('set all properties')
  }
}

Inspector构造器 生成表单的样式设置
// An highlighted block
/*
Default CSS for the Data inspector
see also: DataInspector.js, DataInspector.html
*/

/*
  Grey color palette
  https://www.google.com/design/spec/style/color.html
/*   #FAFAFA; /* Grey 50  */
/*   #F5F5F5; /* Grey 100 */
/*   #EEEEEE; /* Grey 200 */
/*   #E0E0E0; /* Grey 300 */
/*   #BDBDBD; /* Grey 400 */
/*   #9E9E9E; /* Grey 500 */
/*   #757575; /* Grey 600 */
/*   #616161; /* Grey 700 */
/*   #424242; /* Grey 800 */
/*   #212121; /* Grey 900 */

.inspector {
    display: inline-block;
    font: bold 14px helvetica, sans-serif;
    background-color: #212121; /* Grey 900 */
    color: #F5F5F5; /* Grey 100 */
    cursor: default;
  }
  
  .inspector table {
    border-collapse: separate;
    border-spacing: 2px;
  }
  
  .inspector td, th {
    padding: 2px;
  }
  
  .inspector input {
    background-color: #424242; /* Grey 800 */
    color: #F5F5F5; /* Grey 100 */
    font: bold 12px helvetica, sans-serif;
    border: 0px;
    padding: 2px;
  }
  
  .inspector input:disabled {
    background-color: #BDBDBD; /* Grey 400 */
    color: #616161; /* Grey 700 */
  }
  
  .inspector select {
    background-color: #424242;
  }
  .inspector .box-input{
    display: inline-table;
    height: 30px;
}
.inspector .buttonInput{
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
    display:table-cell ;
    vertical-align: middle;
    line-height: 18px;
    height: 18px;
}
.inspector button{
  font: bold 12px helvetica, sans-serif;
  display: inline-block;
  vertical-align: middle;
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  background-color: #f5f7fa;
  border:1px solid #dcdfe6;
  height: 22px;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Vue中使用GoJS绘制流程图是很简单的。首先,你需要将GoJS库引入你的项目中。你可以通过npm安装GoJS,然后在你的Vue组件中引入它。 在你的组件的script标签中,首先你应该引入GoJS库: import * as go from 'gojs'; 然后,在Vue的生命周期钩子函数中,比如mounted函数中,使用GoJS创建一个图表: mounted() { const myDiagram = go.GraphObject.make(go.Diagram, 'myDiagramDiv'); // 创建一个布局 const layout = go.GraphObject.make(go.TreeLayout); // 将布局设置到图表上 myDiagram.layout = layout; ... } 上面的代码中,我们使用GoJS的make方法创建一个图表对象,并将它挂载到id为myDiagramDiv的DOM元素上。然后,我们创建一个布局对象并将其设置到图表上。你还可以根据需要自定义图表的样式和行为。 接下来,你可以使用GoJS的其他方法和属性来添加节点和链接,设置样式,添加事件等来绘制你的流程图。比如: const nodeDataArray = [ { key: 'Alpha', color: 'lightblue' }, { key: 'Gamma', color: 'lightgreen' }, { key: 'Beta', color: 'lightyellow' }, ]; // 添加节点 nodeDataArray.forEach(nodeData => { myDiagram.addNodeData(nodeData); }); // 添加链接 myDiagram.model.addLinkData({ from: 'Alpha', to: 'Beta' }); 在上面的代码中,我们使用GoJS的addNodeData方法来添加节点,并使用addLinkData方法来添加链接。你可以根据你的实际需求自定义节点和链接的数据和样式。 最后,在你的模板中,你可以使用一个DOM元素来放置你的图表: <template> <div id="myDiagramDiv" style="width:800px; height:600px;"></div> </template> 最后,通过一些Vue的工具方法,你可以在Vue组件中动态地操作图表,并将其与其他Vue组件进行交互。 总之,Vue和GoJS结合使用能够轻松地绘制流程图,并提供了丰富的功能和可定制性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值