流程图控件GoJS教程:使用模型和模板

GoJS是一款功能强大,快速且轻量级的流程图控件,可帮助你在JavaScript 和HTML5 Canvas程序中创建流程图。本教程将为您介绍如何使用使用模型和模板。

GoJS是一款功能强大,快速且轻量级的流程图控件,可帮助你在JavaScript 和HTML5 Canvas程序中创建流程图,且极大地简化您的JavaScript / Canvas 程序。

GoJS最新版

您可以以编程方式构建节点和链接图。但GoJS提供了一种以更具说明性的方式构建图表的方法。您只提供图表所需的节点和链接数据(即模型)以及自动复制到图表中的零件实例(即模板)。可以通过节点和链接数据的属性来参数化这些模板。

使用代码构建图表

让我们尝试构建两个节点并用链接连接它们。这是一种方法:

 var node1 =    $(go.Node, "Auto",      $(go.Shape,        { figure: "RoundedRectangle",          fill: "lightblue" }),      $(go.TextBlock,        { text: "Alpha",          margin: 5 })    )  diagram.add(node1);   var node2 =    $(go.Node, "Auto",      $(go.Shape,        { figure: "RoundedRectangle",          fill: "pink" }),      $(go.TextBlock,        { text: "Beta",          margin: 5 })    );  diagram.add(node2);   diagram.add(    $(go.Link,      { fromNode: node1, toNode: node2 },      $(go.Shape)    ));

流程图控件GoJS教程:使用模型和模板

这会产生一个漂亮,简单的图表。如果拖动其中一个节点,您将看到该链接仍然与其连接。

虽然这种构建图表的方式可行,但在创建大图时,它不会很好地扩展。通常,您需要不同数量的节点,每个节点与其他节点非常相似。最好分享节点的结构,但参数化一些值应该变化的东西。

一种可能性是将代码构建到一个函数中,该函数返回一个完全构造的Node,包括其可视树中的所有Panel和其他GraphObject。您可能希望参数化该函数,以便提供所需的字符串和颜色以及图形和图像URL。然而,这种方法非常特别:系统很难知道如何自动调用这些功能以便按需创建新节点或新链接。此外,当您的应用程序数据动态更改时,您将如何使用此类函数更新现有节点和链接中现有对象的属性,而不会无效地重新创建所有内容果您希望在应用程序数据发生变化时自动更新任何内容/所有内容,系统将如何知道该怎么做/p>

这个图表构建代码也比管理节点引用需要更麻烦,以便您可以将它们链接起来。这类似于在代码中构建节点的可视树时必须使用临时命名变量并在需要时引用它们时的早期问题。

我们要寻找的是将所有节点的外观,定义和构造与描述每个特定节点的独特方面所需的应用程序数据分开。

使用模型和模板

实现节点外观与节点数据分离的一种方法是使用数据模型和节点模板。模型基本上只是一个数据集合,它包含每个节点和每个链接的基本信息。模板基本上只是一个可以复制的部分 ; 您将拥有Node和Link的不同模板。

事实上,一个Diagram已经有非常简单的节点和链接默认模板。如果要自定义图中节点的外观,可以通过设置Diagram.nodeTemplate替换默认节点模板。

要自动使用模板,请提供一个模型,其中包含每个节点的数据和每个链接的数据。GraphLinksModel保持节点的数据和链接数据作为值的集合(实际上阵列) GraphLinksModel.nodeDataArray和GraphLinksModel.linkDataArray。然后设置Diagram.model属性,以便该图可以为所有节点数据创建Node,为所有链接数据创建Link。

模型解释和维护数据之间的引用。期望每个节点数据具有唯一的键值,以便可以可靠地解析对节点数据的引用。模型还管理动态添加和删除数据。

模型中的节点数据和链接数据可以是任何JavaScript对象。您可以决定这些对象具有哪些属性 – 添加您的应用程序所需的数量。由于这是JavaScript,您甚至可以动态添加属性。GoJS模型假设存在数个属性,例如“密钥”(在节点数据上)和“类别”和“从”和“到”(后两个在链接数据上)。但是,您可以通过设置名称以“… Property”结尾的模型属性来告诉模型使用不同的属性名称。

节点数据对象通常在“key”属性中具有其节点的唯一键值。目前,节点数据键必须是字符串或数字。您可以通过Node.key属性或通过获取Node的密钥someNode.data.key。

让我们创建一个图表,提供最少量的必要信息。特定节点数据已放入JavaScript对象数组中。我们在链接数据对象的单独数组中声明链接关系。每个链接数据通过使用其键来保存对节点数据的引用。通常,引用是“from”和“to”属性的值。

  var nodeDataArray = [    { key:“Alpha” },    { key:“Beta” }  ]。  var linkDataArray = [    { from:“Alpha”,to:“Beta” }  ]。diagram.model  = new go.GraphLinksModel(nodeDataArray,linkDataArray);

流程图控件GoJS教程:使用模型和模板

这导致两个节点和一个链接,但节点不按我们想要的方式显示。因此,我们将节点模板定义为我们在上面执行的特定节点构造的概括。  

diagram.nodeTemplate =  // provide custom Node appearance    $(go.Node, "Auto",      $(go.Shape,        { figure: "RoundedRectangle",          fill: "white" }),      $(go.TextBlock,        { text: "hello!",          margin: 5 })    );   var nodeDataArray = [    { key: "Alpha" },    { key: "Beta" }  ];  var linkDataArray = [    { from: "Alpha", to: "Beta" }  ];  diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);

流程图控件GoJS教程:使用模型和模板

现在图表看起来更好,但节点尚未参数化 – 它们都是相同的!我们可以通过使用数据绑定来实现该参数化。

使用数据绑定参数化节点

数据绑定是一种声明性声明,应该使用一个对象的属性值来设置另一个对象的属性值。

在这种情况下,我们希望确保TextBlock.text属性获取相应节点数据的“键”值。我们希望确保将Shape.fill属性设置为相应节点数据的“color”属性值给出的颜色/画笔。

我们可以通过创建Binding对象并将它们与目标GraphObject相关联来声明这样的数据绑定。通过调用GraphObject.bind以编程方式执行此操作。但是当使用go.GraphObject.make时,这会在传入Binding时自动发生。

 diagram.nodeTemplate =    $(go.Node, "Auto",      $(go.Shape,        { figure: "RoundedRectangle",          fill: "white" },  // default Shape.fill value        new go.Binding("fill", "color")),  // binding to get fill from nodedata.color      $(go.TextBlock,        { margin: 5 },        new go.Binding("text", "key"))  // binding to get TextBlock.text from nodedata.key    );   var nodeDataArray = [    { key: "Alpha", color: "lightblue" },  // note extra property for each node data: color    { key: "Beta", color: "pink" }  ];  var linkDataArray = [    { from: "Alpha", to: "Beta" }  ];  diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);

流程图控件GoJS教程:使用模型和模板

现在我们有与以前相同的图表结果,但它以更一般的方式实现。您可以轻松添加更多节点和链接数据以构建更大的图表。您可以轻松更改所有节点的外观而无需修改数据。

实际上,您可能会注意到链接不同:它有一个箭头。当我们第一次使用代码构建此图时,没有包含箭头。但是默认的Diagram.linkTemplate包含一个箭头,在本例中我们没有用自定义链接模板替换链接模板。

请注意,上面模板中Shape.fill的值获取两次值。首先它被设置为“白色”。然后绑定将它设置为节点数据的“颜色”属性具有的任何值。能够指定在节点数据没有“颜色”属性或者获得该值时出错的情况下保留的初始值可能是有用的。

在这一点上,我们也可以更准确地了解模板是什么。模板是一个部分,可能有一些数据绑定以及本身不是图中,但可能被复制到创建要添加到图的部分。

模板定义

所有预定义模板的实现都在Extensions目录的Templates.js中提供。您可能希望在创建自己的模板时复制和修改这些定义。

这些定义可能不是GoJS中实际标准模板实现的最新描述。

各种模型

模型是一种将数据对象集合解释为抽象图形的方式,其中各种关系由数据属性和模型所做的假设确定。最简单的模型Model只能保存“部件”而它们之间没有任何关系 – 没有链接或组。但该模型类充当其他类型模型的基类。

GraphLinksModel

您在上面看到的模型GraphLinksModel实际上是最常见的一种。它为每个链接使用单独的链接数据对象支持链接关系。链接可以连接的节点没有固有的限制,因此允许自反和重复链接。链接也可能导致图中的循环。但是,您可以通过设置各种属性(例如Diagram.validCycle)来阻止用户绘制此类链接。如果您希望链接看起来与链接而不是节点连接,则可以通过具有属于链接的特殊节点(称为“标签节点”)来实现,这些节点沿着链接的路径排列。与文本标签在链接上排列的方式相同。

此外,GraphLinksModel还支持在节点内识别逻辑上和物理上不同的连接对象(称为“端口”)。因此,单个链路可以与特定端口连接而不是与整个节点连接。“ 链接点和端口”页面更深入地讨论了此主题。

一个GraphLinksModel还支持组成员关系。任何部分最多只能属于一个集团 ; 任何群体都不能直接或间接地包含在内。

TreeModel

一种更简单的模型TreeModel仅支持形成树形结构图的链接关系。没有单独的链接数据,因此没有“linkDataArray”。树中固有的父子关系由子节点数据上的额外属性确定,该属性通过其键引用父节点。如果该属性(其名称默认为“parent”)未定义,则该数据的相应节点是树根。每个链接仍然是数据绑定,但链接的数据是子节点数据。

 diagram.nodeTemplate =    $(go.Node, "Auto",      $(go.Shape,        { figure: "Ellipse" },        new go.Binding("fill", "color")),      $(go.TextBlock,        { margin: 5 },        new go.Binding("text", "key"))    );   var nodeDataArray = [    { key: "Alpha", color: "lightblue" },    { key: "Beta", parent: "Alpha", color: "yellow" },  // note the "parent" property    { key: "Gamma", parent: "Alpha", color: "orange" },    { key: "Delta", parent: "Alpha", color: "lightgreen" }  ];  diagram.model = new go.TreeModel(nodeDataArray);

流程图控件GoJS教程:使用模型和模板

许多面向树的样本使用TreeModel而不是GraphLinksModel。但仅仅因为您的图形是树形结构并不意味着您必须使用TreeModel。您可能会发现您的数据是使用单独的“表”来组织的,该表定义了链接关系,因此使用GraphLinksModel是最自然的。或者您可能想要使用TreeModel不支持的其他功能。

修改模型

如果要以编程方式添加或删除节点,则可能需要调用 Model.addNodeData和Model.removeNodeData方法。如果您只有唯一的键值,请使用Model.findNodeDataForKey方法查找特定的节点数据对象。您还可以调用Model.copyNodeData来创建节点数据对象的副本,然后可以将其修改并传递给Model.addNodeData。

它不能简单地修改Model.nodeDataArray,因为GoJS软件不会被通知有关任何JavaScript数组的任何更改,因此无法根据需要添加或删除Node或其他部分。

同样,它不能简单地修改节点数据对象的属性。任何依赖于属性的Binding都不会被通知任何更改,因此它将无法更新其目标GraphObject属性。例如,设置color属性不会导致Shape更改颜色。

  var data = myDiagram.model.findNodeDataForKey("Delta");    // This will NOT change the color of the "Delta" Node    if (data !== null) data.color = "red";

相反,您需要调用Model.setDataProperty来修改模型中的对象。

 var data = myDiagram.model.findNodeDataForKey("Delta");    // This will update the color of the "Delta" Node    if (data !== null) myDiagram.model.setDataProperty(data, "color", "red");

当JavaScript数组或对象已经是模型的一部分时,需要 调用模型方法,如Model.addNodeData或Model.setDataProperty。首次为Model.nodeDataArray构建对象数组 或将JavaScript对象初始化为新节点数据对象时,不需要此类调用。但是,一旦数据成为模型的一部分,就必须调用模型的方法来实现更改。

保存和加载模型

GoJS不要求您以任何特定介质或格式保存模型。但由于这是JavaScript和JSON是最流行的数据交换格式,我们确实可以轻松地以JSON格式编写和读取模型。

只需调用Model.toJson即可生成表示模型的字符串。调用静态方法Model.fromJson来构造并初始化给定Model.toJson生成的字符串的模型。许多示例都证明了这一点 – 搜索名为“save”和“load”的JavaScript函数。这些函数中的大多数都在页面本身上编写和读取TextArea,以便您可以查看和修改JSON文本,然后加载它以获取新图表。但是在编辑时请小心,因为JSON语法非常严格,任何语法错误都会导致这些“加载”函数失败。

JSON格式的文本对您可以表示的数据类型有严格的限制,无需额外的假设。要保存和加载您在节点数据(或链接数据)上设置的任何数据属性,它们需要满足以下要求:

  • 该属性是可枚举的,其名称不以下划线开头(您可以使用以下划线开头的属性名称,但不会保存它们)

  • 属性值未定义且不是函数(JSON不能忠实地保存函数)

  • 模型知道如何将属性值转换为JSON格式(数字,字符串,JavaScript数组或纯JavaScript对象)

  • 作为对象或数组的属性值形成树结构 – 没有共享或循环引用

Model.toJson和Model.fromJson还将处理Point,Size,Rect,Spot,Margin,Geometry和非模式Brush es的实例 。但是,我们建议您使用这些类parse和stringify静态函数将这些对象存储在其字符串表示中。

因为您使用的是JavaScript,所以向您的节点数据添加数据属性是微不足道的。这允许您将所需的任何信息与每个节点相关联。但是,如果您需要将某些信息与模型相关联,即使根本没有节点数据也会存在,您可以向Model.modelData对象添加属性。该对象的属性将被写入Model.toJson和阅读Model.fromJson,就像节点数据对象被写入和读取。

=====================================================

想要购买GoJS正版授权的朋友可以咨询官方客服

更多精彩内容,欢迎关注下方的微信公众号,及时获取产品最新资讯▼▼▼

图片2.jpg

标签:

来源:慧都

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2019年8月9日
下一篇 2019年8月9日

相关推荐

发表回复

登录后才能评论