节点模板(nodeTemplate)

当我们没有手动指定节点模板的时候,其实 ​​GoJS​​​ 是有默认模板的,也就是我们最开始的例子,一个节点(​​Node​​​)加一个文本(​​TextBlock​​)。

默认的节点模板:

gojs(五)_前端

我们可以自定义节点的样式

// 创建画布
this.diagram = $(go.Diagram, "diagram",{"undoManager.isEnabled": true});
// 定义模板
this.diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape,
{ figure: "RoundedRectangle", fill: "white" },
),
$(go.TextBlock,
{ text: "hello!", margin: 20 })
);
// 定义数据
const nodeDataArray = [
{ key: "Alpha" },
{ key: "Beta" },
{ key: "Gamma" }
];
// 创建模型实例
const myModel = new go.Model(nodeDataArray);
// 最终赋值给 diagram.model 修改模型
this.diagram.model = myModel;

自定义的节点模板:

gojs(五)_数组_02

连线模板(linkTemplate)

如果想让图表中的节点之间有一些有向或者无向的连线,仅仅靠普通的 ​​Model​​​ 是无法做到的。此时应该使用 ​​TreeModel​​​ 或者 ​​GraphLinksModel​​。

TreeModel

​TreeModel​​ 适用于比较简单的场景。

创建一个 ​​nodeDataArray​​​ 数组,用来保存节点数据,每个元素需要增加一个 ​​key​​ 作为唯一标识。

​TreeModel​​​ 只用 ​​nodeDataArray​​ 一个数组就可以,不需要用一个额外的数组定义连线,只需在定义节点的时候指定父节点即可。

在定义节点同时指定当前节点的父节点,用属性 ​​parent​​​ 表示,属性值是节点的 ​​key​​ 值。

特点:只能处理比较简单的连线情况,如果比较复杂就无能为力,比如,一个节点有多个父节点,或者一对节点之间有多条连线的情况。

语法:

const myTreeModel = new go.TreeModel(nodeDataArray);

演示代码:

// 创建画布
this.diagram = $(go.Diagram, "diagram", { "undoManager.isEnabled": true });
// 定义数据
const nodeDataArray = [
{ key: "Head" },
{ key: "Alpha", parent: "Head" },
{ key: "Beta", parent: "Head" },
{ key: "A", parent: "Alpha" },
{ key: "B", parent: "Alpha" },
{ key: "C", parent: "Beta" },
{ key: "D", parent: "Beta" },
{ key: "E", parent: "Beta" },
];
// 创建 TreeModel 模型实例
const myTreeModel = new go.TreeModel(nodeDataArray);
// 最终赋值给 diagram.model 修改模型
this.diagram.model = myTreeModel;

结果如下:

gojs(五)_数组_03

发现连线重合,布局混乱,这时可以使用 ​​TreeLayout​​ 解决。

// 创建画布
this.diagram = $(go.Diagram, "diagram", {
"undoManager.isEnabled": true,
layout: $(go.TreeLayout, { angle: 90, layerSpacing: 35 })
});
// 定义数据
const nodeDataArray = [
{ key: "Head" },
{ key: "Alpha", parent: "Head" },
{ key: "Beta", parent: "Head" },
{ key: "A", parent: "Alpha" },
{ key: "B", parent: "Alpha" },
{ key: "C", parent: "Beta" },
{ key: "D", parent: "Beta" },
{ key: "E", parent: "Beta" },
];
// 创建 TreeModel 模型实例
const myTreeModel = new go.TreeModel(nodeDataArray);
// 最终赋值给 diagram.model 修改模型
this.diagram.model = myTreeModel;

这下就比较正常了。

gojs(五)_连线_04

GraphLinksModel

​GraphLinksModel​​ 适用于比较复杂的情况。

创建一个 ​​nodeDataArray​​​ 数组,用来保存节点数据,每个元素需要增加一个 ​​key​​ 作为唯一标识。

创建一个 ​​linkDataArray​​​ 数组,利用 ​​from​​​ 和 ​​to​​​ 属性表示连线的指向,它俩的属性值就是节点的 ​​key​​ 值。

语法:

const myGraphLinksModel = new go.GraphLinksModel(nodeDataArray, linkDataArray);

演示代码:

// 创建画布
this.diagram = $(go.Diagram, "diagram", { "undoManager.isEnabled": true });
// 定义节点数据
const nodeDataArray = [
{ key: "Head" },
{ key: "Alpha", parent: "Head" },
{ key: "Beta", parent: "Head" },
{ key: "A", parent: "Alpha" },
{ key: "B", parent: "Alpha" },
{ key: "C", parent: "Beta" },
{ key: "D", parent: "Beta" },
{ key: "E", parent: "Beta" },
];
// 定义连线数据
const linkDataArray = [
{ from: "Alpha", to: "Head" },
{ from: "Beta", to: "Alpha" },
{ from: "A", to: "Alpha" },
{ from: "B", to: "Alpha" },
{ from: "C", to: "Alpha" },
{ from: "D", to: "C" },
{ from: "E", to: "D" },
]
// 创建模型实例
const myGraphLinksModel = new go.GraphLinksModel(nodeDataArray, linkDataArray);
// 最终赋值给 diagram.model 修改模型
this.diagram.model = myGraphLinksModel;

结果如下:

gojs(五)_前端_05

linkTemplate

和节点模板相同的是,我们也可以自定义连线模板。

// 定义连线模板
this.diagram.linkTemplate =
$(go.Link,
{ routing: go.Link.Orthogonal, corner: 5 },
$(go.Shape, { strokeWidth: 3, stroke: "#555" })
)

最后变成了这样:

gojs(五)_数组_06

图表事件(DiagramEvent)

​DiagramEvent​​​ 表示一般用户发起的对图表的改变。可以通过调用 ​​Diagram.addDiagramListener​​​ 注册图表事件处理程序,各个图表事件以名字区分,也可以在图表初始化时调用 ​​go.GraphObject.make​​ 注册图事件处理程序。

常用的的图表事件名称包括:

事件名称

事件含义

 InitialAnimationStarting 

初始默认动画即将开始;不要在事件侦听器中修改图或其模型。这对于修改AnimationManager.defaultAnimation以制作自定义初始动画很有用。

 AnimationStarting 

一个默认动画(AnimationManager.defaultAnimation)将要开始;不要在事件侦听器中修改图或其模型。

 AnimationFinished 

刚刚完成的默认动画(AnimationManager.defaultAnimation);不要在事件侦听器中修改图或其模型。

 BackgroundSingleClicked 

当鼠标左键单击发生在图的背景中而不是零件上时;如果进行任何更改,请启动并提交自己的事务。

 BackgroundDoubleClicked 

当鼠标左键双击发生在图表的背景中而不是零件上时;如果进行任何更改,请启动并提交自己的事务。

 BackgroundContextClicked 

当在图的背景中而不是在零件的背景中发生鼠标右键单击时;如果进行任何更改,请启动并提交自己的事务。

 ChangeingSelection 

一个操作即将更改Diagram.selection集合,该集合也是DiagramEvent.subject的值;不要在事件侦听器中对选择或图表或模型进行任何更改;请注意,仅设置Part.isSelected不会引发此事件,但是工具和命令将引发此事件。

 ChangedSelection 

一个操作刚刚更改了Diagram.selection集合,该集合也是DiagramEvent.subject的值;不要在事件侦听器中对选择或图表或模型进行任何更改;请注意,仅设置Part.isSelected不会引发此事件,但是工具和命令将引发此事件。

 ClipboardChanged 

零件已通过CommandHandler.copySelection复制到剪贴板; 所述DiagramEvent.subject是零件的集合; 如果进行任何更改,请启动并提交自己的事务。

 ClipboardPasted 

CommandHandler.pasteSelection已将零件从剪贴板复制到图表中; 该DiagramEvent.subject是Diagram.selection,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 DocumentBoundsChanged 

图的部件的区域Diagram.documentBounds已更改;该DiagramEvent.parameter是旧的矩形。

 ExternalObjectsDropped 

通过从图的外部拖放将零件复制到图中;该DiagramEvent.subject是一套零件被丢弃的(这也是Diagram.selection),该DiagramEvent.parameter是源图,这是一个事务中调用,这样你就不必从头开始,并提交您的自己的交易。

 GainedFocus 

该图已获得键盘焦点,诸如一个呼叫后Diagram.focus。

 InitialLayoutCompleted 

自从对图进行重大更改(例如替换模型)以来,整个图布局首次更新。如果进行任何更改,则无需执行交易。

 LayoutCompleted 

整个图的布局刚刚更新;如果进行任何更改,则无需执行交易。

 LinkDrawn 

用户刚刚使用LinkingTool创建了一个新的Link ;该DiagramEvent.subject是新的链接,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务..

 LinkRelinked 

用户刚刚重新连接使用现有链路RelinkingTool或DraggingTool ; 该DiagramEvent.subject是修改后的链接,该DiagramEvent.parameter是GraphObject端口的链接从断开连接,这就是所谓的事务中,这样你就不必从头开始,并提交自己的事务..

 LinkReshaped 

用户刚刚使用LinkReshapingTool重新路由了现有的Link ;该DiagramEvent.subject是修改后的链接,该DiagramEvent.parameter是链接的原始路线点的列表,这就是所谓的事务中,这样你就不必从头开始,并提交自己的事务..

 LostFocus 

该图失去了键盘焦点(“模糊”)。

Modified

Diagram.isModified 属性已设置为新值-用于将窗口标记为自上次保存以来已被修改;不要在事件侦听器中修改逻辑示意图或其模型。

 ObjectSingleClicked 

发生在GraphObject上的点击;该DiagramEvent.subject是GraphObject; 如果进行任何更改,请启动并提交自己的事务。

 ObjectDoubleClicked 

发生在GraphObject上的双击;该DiagramEvent.subject是GraphObject; 如果进行任何更改,请启动并提交自己的事务。

 ObjectContextClicked 

发生在GraphObject上的上下文单击;该DiagramEvent.subject是GraphObject; 如果进行任何更改,请启动并提交自己的事务。

 PartCreated 

用户通过ClickCreatingTool插入了一个新的Part ;该DiagramEvent.subject是新的部分,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 PartResized 

用户已通过ResizingTool更改了GraphObject的大小;该DiagramEvent.subject是GraphObject,该DiagramEvent.parameter是原来的大小,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 PartRotated 

用户通过RotatingTool改变了GraphObject的角度; 该DiagramEvent.subject是GraphObject,该DiagramEvent.parameter是度原来的角度,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 SelectionMoved 

用户已通过DraggingTool移动了选定的零件;该DiagramEvent.subject是一套移动零件,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 SelectionCopied 

用户已通过DraggingTool复制了选定的零件;该DiagramEvent.subject是新复制件的设置,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 SelectionDeleting 

用户将通过CommandHandler.deleteSelection删除选定的部件;该DiagramEvent.subject是Diagram.selection零件的集合被删除,这就是所谓的事务中,这样你就不必从头开始,并提交自己的事务。

 SelectionDeleted 

用户已通过CommandHandler.deleteSelection删除了选定的部件;该DiagramEvent.subject是被删除的零件的集合,这就是所谓的事务中,这样你就不必从头开始,并提交自己的事务。

 SelectionGrouped 

用户已通过CommandHandler.groupSelection从选定的零件中创建了一个新的组;该DiagramEvent.subject是新的集团,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 SelectionUngrouped 

用户已删除选定的组,但通过CommandHandler.ungroupSelection保留了其成员;该DiagramEvent.subject是被取消组合组的集合,该DiagramEvent.parameter是被取消组合的前成员零件的集合,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 SubGraphCollapsed 

用户已通过CommandHandler.collapseSubGraph折叠了选定的组;该DiagramEvent.subject是被压塌的是群体的集合,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 SubGraphExpanded 

用户已通过CommandHandler.expandSubGraph扩展了选定的组;该DiagramEvent.subject是被扩展组的集合,这就是所谓的事务中,这样你就不必从头开始,并提交自己的事务。

 TextEdited 

用户已通过TextEditingTool更改了TextBlock的字符串值;该DiagramEvent.subject是编辑的TextBlock时,DiagramEvent.parameter是原始的字符串,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 TreeCollapsed 

用户已通过CommandHandler.collapseTree折叠了带有子树的选定节点;该DiagramEvent.subject是被压塌的是节点的集合,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 TreeExpanded 

用户已通过CommandHandler.expandTree用子树扩展了选定的Nodes 。该DiagramEvent.subject是被扩展节点的集合,这是一个事务中调用,这样你就不必从头开始,并提交自己的事务。

 ViewportBoundsChanged 

图的可见区域Diagram.viewportBounds已更改;所述DiagramEvent.subject是一个对象,其“规模”属性是旧Diagram.scale值,其“位置”属性是旧Diagram.position值,其“范围”属性是旧Diagram.viewportBounds值; 该DiagramEvent.parameter也是老viewportBounds矩形。不要在侦听器中修改图的位置或比例(即视口范围)