//JS代码片段 方法functioninit(){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:newgo.Size(8,8),
fill:'tomato',
stroke:'darkred'}),'relinkingTool.toHandleArchetype':$(go.Shape,'Diamond',{
segmentIndex:-1,
cursor:'pointer',
desiredSize:newgo.Size(8,8),
fill:'darkred',
stroke:'tomato'}),'linkReshapingTool.handleArchetype':$(go.Shape,'Diamond',{
desiredSize:newgo.Size(7,7),
fill:'lightblue',
stroke:'deepskyblue'}),'rotatingTool.handleAngle':270,'rotatingTool.handleDistance':30,'rotatingTool.snapAngleMultiple':15,'rotatingTool.snapAngleEpsilon':15,'undoManager.isEnabled':true})vardoClick=(e)=>{this.isShow =true}// when the document is modified, add a "*" to the title and enable the "Save" buttonthis.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”参数// 控制用户是否可以从端口绘制链接或到端口。functionmakePort(name, spot, output, input){// the port is basically just a small transparent circlereturn$(go.Shape,'Circle',{
fill:null,// 默认情况下不可见; 集由showSmallPorts半透明灰色,下面定义
stroke:null,
desiredSize:newgo.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:newgo.Size(6,6),
fill:'lightblue',
stroke:'deepskyblue'}),$(go.Shape,{
alignment: go.Spot.Top,
cursor:'n-resize',
desiredSize:newgo.Size(6,6),
fill:'lightblue',
stroke:'deepskyblue'}),$(go.Shape,{
alignment: go.Spot.TopRight,
cursor:'ne-resize',
desiredSize:newgo.Size(6,6),
fill:'lightblue',
stroke:'deepskyblue'}),$(go.Shape,{
alignment: go.Spot.Left,
cursor:'w-resize',
desiredSize:newgo.Size(6,6),
fill:'lightblue',
stroke:'deepskyblue'}),$(go.Shape,{
alignment: go.Spot.Right,
cursor:'e-resize',
desiredSize:newgo.Size(6,6),
fill:'lightblue',
stroke:'deepskyblue'}),$(go.Shape,{
alignment: go.Spot.BottomLeft,
cursor:'se-resize',
desiredSize:newgo.Size(6,6),
fill:'lightblue',
stroke:'deepskyblue'}),$(go.Shape,{
alignment: go.Spot.Bottom,
cursor:'s-resize',
desiredSize:newgo.Size(6,6),
fill:'lightblue',
stroke:'deepskyblue'}),$(go.Shape,{
alignment: go.Spot.BottomRight,
cursor:'sw-resize',
desiredSize:newgo.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:newgo.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 },newgo.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
},newgo.Binding('angle').makeTwoWay(),// the main object is a Panel that surrounds a TextBlock with a Shape$(
go.Panel,'Auto',{ name:'PANEL'},newgo.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},newgo.Binding('figure'),newgo.Binding('fill')),$(
go.TextBlock,{
font:'bold 11pt Helvetica, Arial, sans-serif',
margin:2,
maxSize:newgo.Size(160,NaN),
wrap: go.TextBlock.WrapFit,
editable:false},newgo.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 是否可被链接varnodeShap=(fromLinkable =true, toLinkable =true)=>{return$(
go.Node,'Spot',{ desiredSize:newgo.Size(50,50), locationSpot: go.Spot.Center },newgo.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
},newgo.Binding('angle').makeTwoWay(),$(
go.Panel,'Auto',{ name:'PANEL'},newgo.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'},newgo.Binding('source','type', type =>{
console.log(type,'type')returnrequire(`../../../common/flow/img/16/${type}.png`)})),$(
go.TextBlock,{
font:'bold 11pt Helvetica, Arial, sans-serif',
margin:2,
maxSize:newgo.Size(160,NaN),
wrap: go.TextBlock.WrapFit,
editable:false},newgo.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))functionshowSmallPorts(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},newgo.Binding('points').makeTwoWay(),$(
go.Shape,// the link path shape{ isPanelMain:true, strokeWidth:2}),$(
go.Shape,// the arrowhead{ toArrow:'Standard', stroke:null}),$(
go.Panel,'Auto',newgo.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:newgo.Size(10,NaN),
editable:true},newgo.Binding('text').makeTwoWay())))// load() // load an initial diagram from some JSON text// initialize the Palette that is on the left side of the pagethis.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},newgo.Binding('points'),$(
go.Shape,// the link path shape{ isPanelMain:true, strokeWidth:2}),$(
go.Shape,// the arrowhead{ toArrow:'Standard', stroke:null})),
model:newgo.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:newgo.List(/* go.Point */).addAll([newgo.Point(0,0),newgo.Point(30,0),newgo.Point(30,40),newgo.Point(60,40)])}])})varshow=({ part }, propName)=>{var data = part.data
return data.type ==='deal'|| data.type ==='task'}//节点的详情编辑及显示this.inspector =newInspector('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 +=1var event =newEvent('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>
*/exportfunctionInspector(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.modelDatathis.inspectedObject =null// Inspector options defaults:this.includesOwnProperties =truethis.declaredProperties ={}this.inspectsSelection =truethis.propertyModified =nullthis.multipleSelection =falsethis.showAllProperties =falsethis.showSize =0if(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 instanceofgo.Node}
Inspector.showIfLink=function(part){return part instanceofgo.Link}
Inspector.showIfGroup=function(part){return part instanceofgo.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 instanceofgo.Part) data = data.data
returntypeof 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 =nullvar inspectedObjects =nullif(object ===null)returnif(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 objectsif(!inspectedObjects ||!this.multipleSelection){if(inspectedObject ===null){this.inspectedObject = inspectedObject
this.updateAllHTML()return}this.inspectedObject = inspectedObject
if(this.inspectObject ===null)returnvar mainDiv =this._div
mainDiv.innerHTML =''// use either the Part.data or the object itself (for model.modelData)var data =(inspectedObject instanceofgo.Part)? inspectedObject.data : inspectedObject
if(!data)return// Build table:var table = document.createElement('table')var tbody = document.createElement('tbody')this._inspectedProperties ={}this.tabIndex =0var 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))continuevar 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 propertyif(this._inspectedProperties[k])continue// already existsif(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 selectedvar mainDiv =this._div
mainDiv.innerHTML =''var shared =newgo.Map()// for properties that the nodes have in commonvar properties =newgo.Map()// for adding propertiesvar all =newgo.Map()// used later to prevent changing properties when unneededvar it = inspectedObjects.iterator
// Build table:var table = document.createElement('table')var tbody = document.createElement('tbody')this._inspectedProperties ={}this.tabIndex =0var declaredProperties =this.declaredProperties
it.next()
inspectedObject = it.value
this.inspectedObject = inspectedObject
var data =(inspectedObject instanceofgo.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))continuevar 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 propertyif(this._inspectedProperties[k])continue// already existsif(declaredProperties[k]&&!this.canShowProperty(k, declaredProperties[k], inspectedObject))continue
shared.add(k, data[k])
all.add(k, data[k])}}}var nodecount =2while(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 instanceofgo.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))continuevar 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 propertyif(this._inspectedProperties[k])continue// already existsif(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 applicablevar 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 seperatorsvar 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 colorvar 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 colorvar newVal = all.get(addIt.key)+'|'
all.set(addIt.key, newVal)}}}}
nodecount++}// builds the table property rows and sets multipleProperties to help with updateallvar 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)returnfalse// if "show" is a predicate, make sure it passes or do not show this propertyif(typeof propertyDesc.show ==='function')return propertyDesc.show(inspectedObject, propertyName)returntrue}/**
* @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)returnfalse// assume property values that are functions of Objects cannot be editedvar data =(inspectedObject instanceofgo.Part)? inspectedObject.data : inspectedObject
var valtype =typeof data[propertyName]if(valtype ==='function')returnfalseif(propertyDesc){if(propertyDesc.readOnly ===true)returnfalse// if "readOnly" is a predicate, make sure it passes or do not show this propertyif(typeof propertyDesc.readOnly ==='function')return!propertyDesc.readOnly(inspectedObject, propertyName)}returntrue}/**
* @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 =nullvar div =nullvar self =thisfunctionupdateall(){
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')returnnullvar 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 instanceofgo.Point)return go.Point.stringify(x)if(x instanceofgo.Size)return go.Size.stringify(x)if(x instanceofgo.Rect)return go.Rect.stringify(x)if(x instanceofgo.Spot)return go.Spot.stringify(x)if(x instanceofgo.Margin)return go.Margin.stringify(x)if(x instanceofgo.List)returnthis.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 instanceofgo.Partvar data = isPart ?this.inspectedObject.data :this.inspectedObject
if(!data){// clear out all of the fieldsfor(var name in inspectedProps){var input = inspectedProps[name]if(input instanceofHTMLSelectElement){
input.innerHTML =''}elseif(input.type ==='color'){
input.value ='#000000'}elseif(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 instanceofHTMLSelectElement){var decProp =this.declaredProperties[name]this.updateSelect(decProp, input, name, propertyValue)}elseif(input.type ==='color'){
input.value =this.convertToColor(propertyValue)}elseif(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 therevar 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 updatevar isPart =this.inspectedObject instanceofgo.Partvar 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 propertiesvar 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 matchvar 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 booleanelseif(typeof oldval ==='number') type ='number'elseif(oldval instanceofgo.Point) type ='point'elseif(oldval instanceofgo.Size) type ='size'elseif(oldval instanceofgo.Rect) type ='rect'elseif(oldval instanceofgo.Spot) type ='spot'elseif(oldval instanceofgo.Margin) type ='margin'}// convert to specific type, if neededswitch(type){case'boolean': value =!(value ===false|| value ==='false'|| value ==='0');breakcase'number': value =parseFloat(value);breakcase'arrayofnumber': value =this.convertToArrayOfNumber(value);breakcase'point': value = go.Point.parse(value);breakcase'size': value = go.Size.parse(value);breakcase'rect': value = go.Rect.parse(value);breakcase'spot': value = go.Spot.parse(value);breakcase'margin': value = go.Margin.parse(value);breakcase'checkbox': value = input.checked;breakcase'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 listenerif(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 typeif(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 =falseif(this.declaredProperties[name]&&this.declaredProperties[name].type ==='checkbox') change =true// always change checkboxif(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 propertiesfor(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 themfor(var i =0; i < diagram.selection.count; i++){
it.next()var isPart = it.value instanceofgo.Partvar data = isPart ? it.value.data : it.value
if(data){// ignores the selected node if there is no dataif(i < arr1.length) value = arr1[i]else value = arr1[0]// don't update "readOnly" data propertiesvar 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 matchvar 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 booleanelseif(typeof oldval ==='number') type ='number'elseif(oldval instanceofgo.Point) type ='point'elseif(oldval instanceofgo.Size) type ='size'elseif(oldval instanceofgo.Rect) type ='rect'elseif(oldval instanceofgo.Spot) type ='spot'elseif(oldval instanceofgo.Margin) type ='margin'}// convert to specific type, if neededswitch(type){case'boolean': value =!(value ===false|| value ==='false'|| value ==='0');breakcase'number': value =parseFloat(value);breakcase'arrayofnumber': value =this.convertToArrayOfNumber(value);breakcase'point': value = go.Point.parse(value);breakcase'size': value = go.Size.parse(value);breakcase'rect': value = go.Rect.parse(value);breakcase'spot': value = go.Spot.parse(value);breakcase'margin': value = go.Margin.parse(value);breakcase'checkbox': value = input.checked;breakcase'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 listenerif(this.propertyModified !==null)this.propertyModified(name, value,this)}}}}
diagram.commitTransaction('set all properties')}}