流程图控件GoJS教程:集合类
GoJS是一款功能强大,快速且轻量级的流程图控件,可帮助你在JavaScript 和HTML5 Canvas程序中创建流程图,且极大地简化您的JavaScript / Canvas 程序。
GoJS现已更新至最新版本2.0.17发布,修复了一些bug,增强用户体验,赶快下载试试吧~
GoJS提供了自己的集合类:List,Set和Map。您可以使用Iterator遍历集合。
与将JavaScript数组用作列表或将对象用作地图相比,这些集合类具有多个优点。如果自获取迭代器以来对集合进行了修改,则在尝试获取迭代器的下一项时,它们会引发错误。可以将它们设为只读,以避免意外的修改。它们提供了在简单数组或对象(例如Iterator.any,Iterator.all和Iterator.each)上找不到的方法。如果您使用TypeScript编写,则可以选择对项目类型强制执行编译时类型检查。
在GoJS中,大多数返回描述图结构的集合的属性和方法都返回一个Iterator。那是因为集合的实现是内部的-您只需要知道如何遍历结果集合即可。其他方法或属性将允许您修改图表。一个示例是Diagram.nodes,它以迭代器的形式返回图中的Node和Group的当前集合。当程序员在模型中添加或删除节点数据时,或者通过直接调用Diagram.add或Diagram.remove,将自动修改该集合 。
但是,有一些属性可以返回允许修改的集合。示例包括通常在初始化后冻结的类的集合: Geometry.figures,PathFigure.segments和Brush.colorStops。其他示例包括很少被修改的集合,通常仅在图初始化时才进行修改: ToolManager.mouseDownTools(和其他工具列表)和Diagram.nodeTemplateMap (和其他模板图)。
列表
一个列表是由整数索引的一个从零小于计数值的有序集合。
var l = new go.List(); l.add("A"); l.add("B"); l.add("C"); assert(l.count === 3); assert(l.elt(0) === "A"); assert(l.has("B")); assert(l.indexOf("B") === 1); l.setElt(1, "z"); // replace an item assert(l.elt(1) === "z"); l.removeAt(1); // remove an item assert(l.count === 2); assert(l.elt(1) === "C");
在2.0中,List构造函数的可选参数已删除。但是,如果你在写打字稿,GoJS集合类(List,Map,Set)现在是通用的,并会帮助你执行类型:
// TypeScript: var l = new go.List<string>(); // Create a list of only strings l.add("A"); l.add(23); // throws an error during compilation or in an IDE l.add({}); // throws an error during compilation or in an IDE
要遍历List,请获取其List.iterator,然后对其调用Iterator.next 以提高其在列表中的位置。它的Iterator.value将是一个列表项;它的Iterator.key将是列表中的相应索引。
var l = new go.List(); l.add("A"); l.add("B"); l.add("C"); var it = l.iterator; while (it.next()) { console.log(it.key + ": " + it.value); } // This outputs: // 0: A // 1: B // 2: C
组
一组是值的无序集合,不允许重复的值。此类类似于SetECMAScript 2015(ES6)中定义的对象。
Set构造函数 的可选参数指定可以添加到集合中的项的类型。
var s = new go.Set(); s.add("A"); s.add("B"); s.add("C"); s.add("B"); // duplicate is ignored assert(s.count === 3); assert(s.has("B")); s.remove("B"); // remove an item assert(s.count === 2); assert(!s.has("B"));
与List和一样Map,在2.0中,Set构造函数的可选参数已删除,但现在它是TypeScript中的泛型类,可以强制执行类型:
// TypeScript: var s = new go.Set<string>(); // Create a set of only strings s.add("A"); s.add(23); // throws an error during compilation or in an IDE s.add({}); // throws an error during compilation or in an IDE
遍历Set中 的项目就像遍历List一样,只是项目的顺序可能会有所不同。
var s = new go.Set(); s.add("A"); s.add("B"); s.add("C"); s.add("B"); // duplicate is ignored var it = s.iterator; while (it.next()) { console.log(it.value); } // This might output, perhaps in different order: // A // B // C
地图
一个地图是由密钥索引键-值对的无序集合。此类类似于MapECMAScript 2015(ES6)中定义的对象。
Map构造函数 的两个可选参数指定键的类型以及可以添加到地图的项目值的类型。
var m = new go.Map(); m.add("A", 1); // associate "A" with 1 m.add("B", 2); m.add("C", 3); assert(s.count === 3); assert(s.has("B")); assert(s.get("B") === 2); m.add("B", 222); // replace the value for "B" assert(s.get("B") === 222); s.remove("B"); // remove an item assert(s.count === 2); assert(!s.has("B")); assert(s.get("B") === null);
与List和一样Set,在2.0中,已删除了Map构造函数的可选参数,但现在它是TypeScript中的泛型类,可以强制执行类型:
// TypeScript: var m = new go.Map<string, number>(); // Create a map of strings to numbers m.add("A", 1); m.add(23, 23); // throws an error during compilation or in an IDE m.add({}, 23); // throws an error during compilation or in an IDE
遍历Map中 的项目就像遍历List一样,但是提供对键和值的访问。与Set一样,项目的顺序可能有所不同。
var m = new go.Map(); m.add("A", 1); // associate "A" with 1 m.add("B", 2); m.add("C", 3); m.add("B", 222); // replace the value for "B" // Normal iteration lets you get both the key and its corresponding value: var it = m.iterator; while (it.next()) { console.log(it.key + ": " + it.value); } // This might output, perhaps in different order: // A: 1 // B: 222 // C: 3 // To get a collection of the keys, use Map.iteratorKeys: var kit = m.iteratorKeys; while (kit.next()) { console.log(kit.value); } // This might output, perhaps in different order: // A // B // C // To get a collection of the values, use Map.iteratorValues: var vit = m.iteratorValues; while (vit.next()) { console.log(vit.value); } // This might output, perhaps in different order: // 1 // 222 // 3
当需要将集合传递给采用Iterator的其他方法时, 通常使用Map.iteratorKeys或Map.iteratorValues。
更多迭代示例
这是司空见惯的遍历选定部分一第图:
for (var it = diagram.selection.iterator; it.next(); ) { var part = it.value; // part is now a Node or a Group or a Link or maybe a simple Part if (part instanceof go.Node) { . . . } else if (part instanceof go.Link) { . . . } }
或者
diagram.selection.each(function(part) { // part is now a Node or a Group or a Link or maybe a simple Part if (part instanceof go.Node) { . . . } else if (part instanceof go.Link) { . . . } });
有时一个需要遍历节点 ■在一个图表:
for (var it = diagram.nodes; it.next(); ) { var n = it.value; // n is now a Node or a Group if (n.category === "Special") { . . . } }
您还可以遍历Node中的端口元素或连接到端口元素的Link:
for (var pit = node.ports; pit.next(); ) { var port = pit.value; // port is now a GraphObject within the node for (var lit = node.findLinksConnected(port.portId); lit.next(); ) { var link = lit.value; // link is now a Link connected with the port if (link.data.xyz === 17) { . . . } } }
或者,也许您需要遍历Panel的元素:
for (var it = panel.elements; it.next(); ) { var elt = it.value; // elt is now a GraphObject that is an immediate child of the Panel if (elt instanceof go.TextBlock) { . . . } else if (elt instanceof go.Panel) { . . . recurse . . . } }
如果要查找作为Group直属成员的Node:
for (var mit = group.memberParts; mit.next(); ) { var part = mit.value; // part is now a Part within the Group if (part instanceof go.Node) { . . . maybe work with part.data . . . } }
=====================================================
想要购买GoJS正版授权的朋友可以。
更多精彩内容,欢迎关注下方的微信公众号,及时获取产品最新资讯▼▼▼