流程图控件GoJS教程:验证方式(下)

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

GoJS最新试用版

常规链接验证

在某些情况下,您的应用程序的语义将导致有效链接目标集以某种方式取决于节点数据(即,链接从其开始的节点和端口以及可能的目标节点/端口)只能使用代码来实现:谓词函数。

您可以通过设置LinkingBaseTool.linkValidation或Node.linkValidation来实现此类特定于域的验证。这些谓词(如果提供)将为链接工具考虑的每对端口调用。如果谓词返回false,则可能无法建立链接。在LinkingTool或RelinkingTool上设置属性会使谓词应用于所有链接操作,而在Node上设置属性仅适用于涉及该节点的链接操作。根据上述属性,只有在所有标准链接检查均通过的情况下,才调用谓词。

在此示例中,存在三种不同颜色的节点。该LinkingTool和RelinkingTool自定义为使用的功能,sameColor以确保链接只有相同颜色的连接节点。鼠标向下拖动并在椭圆上拖动(光标变为“指针”),开始绘制新链接。您将看到,唯一允许的链接目标是相同颜色的节点,这些节点尚未从同一节点进行链接。

  diagram.nodeTemplate =    $(go.Node, "Auto",      $(go.Shape, "Ellipse",        { cursor: "pointer", portId: "",          fromLinkable: true, toLinkable: true },        new go.Binding("fill", "color")),      $(go.TextBlock,        { stroke: "white", margin: 3 },        new go.Binding("text", "key"))    );  diagram.linkTemplate =    $(go.Link,      { curve: go.Link.Bezier, relinkableFrom: true, relinkableTo: true },      $(go.Shape, { strokeWidth: 2 },        new go.Binding("stroke", "fromNode", function(n) { return n.data.color; })            .ofObject()),      $(go.Shape, { toArrow: "Standard", stroke: null},        new go.Binding("fill", "fromNode", function(n) { return n.data.color; })            .ofObject())    );  // this predicate is true if both nodes have the same color  function sameColor(fromnode, fromport, tonode, toport) {    return fromnode.data.color === tonode.data.color;    // this could look at the fromport.fill and toport.fill instead,    // assuming that the ports are Shapes, which they are because portID was set on them,    // and that there is a data Binding on the Shape.fill  }  // only allow new links between ports of the same color  diagram.toolManager.linkingTool.linkValidation = sameColor;  // only allow reconnecting an existing link to a port of the same color  diagram.toolManager.relinkingTool.linkValidation = sameColor;  var nodeDataArray = [    { key: "Red1", color: "red" },    { key: "Blue1", color: "blue" },    { key: "Green1", color: "green" },    { key: "Green2", color: "green" },    { key: "Red2", color: "red" },    { key: "Blue2", color: "blue" },    { key: "Red3", color: "red" },    { key: "Green3", color: "green" },    { key: "Blue3", color: "blue" }  ];  var linkDataArray = [    // initially no links  ];  diagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);

流程图控件GoJS教程:验证方式(下)

为了强调颜色限制,链接的颜色绑定到“ from”节点数据。

限制与节点连接的链接总数

可以通过设置GraphObject.toMaxLinks来限制进入端口的链接数。同样,可以通过设置GraphObject.fromMaxLinks来限制从端口出来的链接数。但是,如果要限制与端口连接的链接总数,而不管它们是进入端口还是离开端口,该怎么办样的约束只能通过链接验证谓词来实现。

当要限制任一方向上与每个端口连接的链路总数时,可以使用此Node.linkValidation谓词:

$(go.Node, . . .,    {      linkValidation: function(fromnode, fromport, tonode, toport) {        // total number of links connecting with a port is limited to 1:        return fromnode.findLinksConnected(fromport.portId).count +               tonode.findLinksConnected(toport.portId).count < 1; } }, . . .

当想要限制任一方向的链接总数,并为一个节点的所有端口连接时,可以使用此Node.linkValidation谓词:

  $(go.Node, . . .,    {      linkValidation: function(fromnode, fromport, tonode, toport) {        // total number of links connecting with all ports of a node is limited to 1:        return fromnode.linksConnected.count + tonode.linksConnected.count < 1; } }, . . .

分组验证

当要限制用户可以添加到特定组的节点的类型时,可以将谓词实现为CommandHandler.memberValidation或Group.memberValidation属性。在CommandHandler上设置属性会使谓词应用于所有组,而在Group上设置属性仅适用于该组。

在此示例中,samePrefix谓词用于确定是否可以将节点放入组中。尝试将左侧的简单文本节点拖到右侧的任一组中。仅当将节点放到高亮“绿色”的组上时,该节点才被添加为该组的成员。您可以通过移动组以查看文本节点是否也移动来进行验证。

  // this predicate is true if both node data keys start with the same letter  function samePrefix(group, node) {    if (group === null) return true;  // when maybe dropping a node in the background    if (node instanceof go.Group) return false;  // don't add Groups to Groups    return group.data.key.charAt(0) === node.data.key.charAt(0);  };  diagram.nodeTemplate =    $(go.Node,      new go.Binding("location", "loc", go.Point.parse),      $(go.TextBlock,        new go.Binding("text", "key"))    );  diagram.groupTemplate =    $(go.Group, "Vertical",      {        // only allow those simple nodes that have the same data key prefix:        memberValidation: samePrefix,        // don't need to define handlers on member Nodes and Links        handlesDragDropForMembers: true,        // support highlighting of Groups when allowing a drop to add a member        mouseDragEnter: function(e, grp, prev) {          // this will call samePrefix; it is true if any node has the same key prefix          if (grp.canAddMembers(grp.diagram.selection)) {            var shape = grp.findObject("SHAPE");            if (shape) shape.fill = "green";            grp.diagram.currentCursor = "";          } else {            grp.diagram.currentCursor = "not-allowed";          }        },        mouseDragLeave: function(e, grp, next) {          var shape = grp.findObject("SHAPE");          if (shape) shape.fill = "rgba(128,128,128,0.33)";          grp.diagram.currentCursor = "";        },        // actually add permitted new members when a drop occurs        mouseDrop: function(e, grp) {          if (grp.canAddMembers(grp.diagram.selection)) {            // this will only add nodes with the same key prefix            grp.addMembers(grp.diagram.selection, true);          } else {  // and otherwise cancel the drop            grp.diagram.currentTool.doCancel();          }        }      },      // make sure all Groups are behind all regular Nodes      { layerName: "Background" },      new go.Binding("location", "loc", go.Point.parse),      $(go.TextBlock,        { alignment: go.Spot.Left, font: "Bold 12pt Sans-Serif" },        new go.Binding("text", "key")),      $(go.Shape,        { name: "SHAPE", width: 100, height: 100,          fill: "rgba(128,128,128,0.33)" })    );  diagram.mouseDrop = function(e) {    // dropping in diagram background removes nodes from any group    diagram.commandHandler.addTopLevelParts(diagram.selection, true);  };  var nodeDataArray = [    { key: "A group", isGroup: true, loc: "100 10" },    { key: "B group", isGroup: true, loc: "100 140" },    { key: "A1", loc: "10 30" },  // can be added to "A" group    { key: "A2", loc: "10 60" },    { key: "B1", loc: "10 90" },  // can be added to "B" group    { key: "B2", loc: "10 120" },    { key: "C1", loc: "10 150" }  // cannot be added to either group  ];  diagram.model = new go.GraphLinksModel(nodeDataArray, []);

流程图控件GoJS教程:验证方式(下)

这些组是固定大小的组-它们不使用Placeholder。因此,当将节点放入其中时,该组不会自动调整自身大小以包围其成员节点。但这在将节点拖出组时也是有好处的。

拖动已经是组成员的节点时,也会调用验证谓词。您可以看到将节点放入其现有的包含组是如何可接受的。当将其拖动到组的外部到图的背景中时,谓词将以null作为“组”参数被调用。

在此示例中,将节点放到图的背景中而不是放到一个组中总是可以的。如果要禁止在后台拖放,可以myDiagram.currentTool.doCancel() 在Diagram.mouseDrop事件处理程序中调用。如果要在后台拖动过程中显示反馈,则可以实现一个set 的Diagram.mouseDragOver事件处理程序 myDiagram.currentCursor = “not-allowed”。当在“组”中拖动时,此行为将类似于上面实现的行为。

  // this predicate is true if the new string has at least three characters  // and has a vowel in it  function okName(textblock, oldstr, newstr) {    return newstr.length >= 3 && /[aeiouy]/i.test(newstr);  };  diagram.nodeTemplate =    $(go.Node, "Auto",      $(go.Shape, { fill: "lightyellow" }),      $(go.Panel, "Vertical",        { margin: 3 },        $(go.TextBlock,          { editable: true },  // no validation predicate          new go.Binding("text", "text1")),        $(go.TextBlock,          { editable: true,            isMultiline: false,  // don't allow embedded newlines            textValidation: okName },  // new string must be an OK name          new go.Binding("text", "text2"))      )    );  var nodeDataArray = [    { key: 1, text1: "Hello", text2: "Dolly!" },    { key: 2, text1: "Goodbye", text2: "Mr. Chips" }  ];  diagram.model = new go.GraphLinksModel(nodeDataArray, []);

流程图控件GoJS教程:验证方式(下)

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

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

流程图控件GoJS教程:验证方式(下)
标签:

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年3月1日
下一篇 2020年3月1日

相关推荐

发表回复

登录后才能评论