GoJS是Northwoods Software的产品。
Northwoods Software创立于1995年,专一于交互图控件和类库。旗下四款产品:javascript
GoJS是一个实现交互类可视化图表(好比流程图,树图,关系图,力导图,思惟导图等等)的JS库。GoJS为用户交互提供了许多高级功能,如拖放,删除,复制和粘贴,撤销与重作,文本编辑,工具提示,上下文菜单,自动布局,数据绑定和模型,事务状态和撤销管理,事件处理程序,命令以及用于自定义操做的可扩展工具系统等等。php
// gojs能够绘制的图形有css
柱状图 barCharts 线形图 canvases.html 比赛场次图 beatPaths.html 蜡烛图 candlestickCharts.html
类层次结构 classHierarchy.html 诠释comments.html 概念图conceptMap.html 动效图 constantSize.html
决策树 decisionTree.html 距离图 distances.html 双圆 doubleCircle.html 双树doubleTree.html doubleTreeJSON.html
流程图 draggableLink.html 家族图谱 familyTree.html 进度图gantt.html 家族图谱genogram.html 顺序功能图grafcet.html
温度计 thermometer.html 时间轴 tabs.html 纵向面板 swimLanesVertical.html
横向面板swimLanes.html 状态图stateChartIncremental.html 平面表格spreadsheet.html 线形图 sparklineGraphs.html
监控图 shopFloorMonitor.html 序列化函数sequentialFunction.html 序列化图表sequenceDiagram.html
座位图 seatingChart.html
桑基图 sankey.html (桑基图定义:它主要用来表示原材料、能量等如何从初始形式通过中间过程的加工、转化到达最终形式,以下所示为最基本的事物状态随时间推移的变化)
圆形组roundedGroups.html 重组缩放regroupingScaled.html 雷达图radialPartition.html 生成流程图productionProcess.html
货架图planogram.html 管道图pipes.html tab标签页 timeline.htmlhtml
更多实例参考java
https://gojs.net/latest/samples/index.htmlnode
用对象数据表达数据之间的逻辑关系,远不如用图像展现形象直观 ,一图胜千言,为了更直观地表达信息,咱们经常须要用图形来展现数据以及逻辑关系。goJS图表种类,交互行为丰富,自定义模板灵活,已经有很是多的图表例子,支持复杂的模板定义和数据绑定,足够解决实际业务中的常见图表需求。
web
step1 下载gojs 源码 http://gojs.net/latest/site.zip 并在页面中引用算法
step2 在页面中建立goJS图表容器,必定要设置宽高,不然图形绘制不出来编程
step3 建立GraphObject图表实例,(定义样式,交互,布局,属性)json
step4 定义图表属性及事件 节点样式事件 链路样式及事件
step5 绑定图表节点和链路数据, 渲染图表
综合节点模板、连接模板、TreeModel和Treelayout,就生成了一张家族图谱。
全部GoJS的属性和方法都在go这个命名空间下。全部GoJS的类名,例如Diagram、Node、Panel、 Shape、TextBlock也都使用go做为前缀,go.GraphObject.make来建立一个GoJS对象
GoJS图表即最后看到的可视化视图,它是由这些部分构成的:一个或多个可能有链接关系的、可能成组的节点。全部这些节点和链路汇集在相同或不一样的层中,并呈现出必定的布局(开发者预约好的或GoJS自动布局)。
画布初始位置(定义以后就不能拖动了) | initialContentAlignment: go.Spot.Center |
初始坐标 | initialPosition: new go.Point(0, 0) |
禁止移动节点 | allowMove:false |
禁止复制 | allowCopy: false |
禁止删除 | allowDelete:false |
禁止选中 | allowSelect:false |
禁止缩放 | allowZoom: false |
禁止撤销和重作 | "undoManager.isEnabled": false |
禁止水平拖动画布 禁止水平滚动条
|
allowHorizontalScroll: false |
禁止垂直拖动画布 禁止垂直滚动条 |
allowVerticalScroll: false |
只读 | isReadOnly: true |
画布初始化动画时间 | "animationManager.duration": 600 |
禁止画布初始化动画 | "animationManager.isEnabled": false |
画布比例 | scale:1.5 |
画布最小比例 | minScale:1.2, |
画布最大比例 | maxScale:2.0, |
显示网格 | "grid.visible":true, |
禁止鼠标拖动区域选中 | "dragSelectingTool.isEnabled" : false, |
画布边距padding Margin | padding:80或者new go.Margin(2, 0)或new go.Margin(1, 0, 0, 1) |
更多设置参见 https://gojs.net/latest/api/symbols/Diagram.html
GoJs使用model-view(MV架构)的模式,Models做为数据层来管理那些描述性的数据(JS数组对象),Diagrams则负责视图层,将Nodes和Links的数据以可视化的方式渲染出来。Diagrams中的Nodes(节点)和Links(连线)呈现是由Model进行管理的。model和Diagrams实现了数据绑定,经过监听Model数据,自动改变Nodes上的GraphObjects外观和行为。Model数据对象是一个普通的JavaScript对象。咱们编程操做只针对Model的数据层,而不是Diagrams的视图层。能够按照业务需求在Models数据对象上面添加任意属性,通常不须要修改Diagram的prototype(原型)和GraphObject(绘图单元)的classes(类).
数据绑定是指从源对象中提取值并在目标对象上设置属性。目标对象就是图形对象(GraphObject),源对象是模型中保存的js数据对象。
使用模板和数据绑定简化了存储在模型数据中的信息,灵活性很是强。固然并非全部的数据属性都须要绑定使用
go.Binding绑定只将属性的值从源数据转移到目标对象。但有时咱们但愿可以将GraphObject中的值传输回模型数据,使得模型数据与ui界面的图标中的数据保持一致。这能够经过使用TwoWay 绑定,它能够完成从源数据到目标对象,以及从目标对象到源数据的值传递。
每一个图表都有一个数据模型,用于保存开发者程序的数据。
模型描述了节点之间的链接关系和组成员关系。用模型 Model.nodeDataArray 为每一个数据项建立一个节点或组, 用模型 GraphLinksModel.linkDataArray 为每一个数据项建立一个连接。并且,咱们能够为每一个数据对象添加所需的任何属性。
自定义的node模板让咱们的图表看起来更美观,若是要建立一个完整的关系图,经过添加一些连线来表示这些独立的节点之间的对应关系,同时这些节点可以进行自动定位和排版。在咱们的图表里为了获得这些连线,基本的Model已经知足不了需求。咱们必须从GOJS中的支持连线的另外两个Models里选择,GraphLinksModel和TreeModel
GraphLinksModel中,除了model.nodeDataArray还有model.linkDataArray。它包含一个数组对象,经过”to”和”from”来描述没一个连线。
GraphLinksModel容许两个节点之间存在任何数量和任意方向的连线。好比A到B能够连10条线,B到A能够连3条以上反方向的线
TreeModel比GraphLinksModel更简单,可是不能随意的建利链接关系,就像2个节点之间有多条线,又或者有多个父级节点。
模板声明了每一个节点或链路的外观、位置和行为。
* Shape 预约义的或者自定义的几何图形
"Rectangle"--矩形, "RoundedRectangle"--圆角矩形, "Square"--正方形 "Ellipse"--椭圆 "Diamond"--菱形, "Circle"--圆形 各类三角形 "TriangleRight", "TriangleDown", "TriangleLeft", "TriangleUp", "Triangle",
"LineH", "LineV", "BarH", "BarV", "MinusLine", "PlusLine", "XLine"
* TextBlock 拥有各类各样字体的文本(可编辑)
* Picture 图片
* Panel 根据不一样面板的类型,它能够包含其余位置或是尺寸不一样的对象。(列如表格、 竖形列表和拉伸容器等)
TextBlocks不能包含图片;Shapes不能包含文字。若是你想让你的Node显示文字,你必须使用TextBlocks。若是你想绘制一些几何图形,你就必须使用Shape。
myDiagram.nodeTemplate = $(
go.Node,
"Horizontal",
{ background: "#44CCFF" },
$(
go.Shape,
"Rectangle",
{
portId: "",
fromLinkable: true,
toLinkable: true,
cursor: "pointer",
fill: "white",
strokeWidth: 1
},
new go.Binding("figure"),
new go.Binding("fill")
),
$(go.Picture, { margin: 10, width: 50, height: 50, background: "red" }, new go.Binding("source"), new go.Binding("figure")),
$(go.TextBlock, "Default Text", { margin: 12, stroke: "white", font: "bold 16px sans-serif" }, new go.Binding("text", "name"))
);
全部的这些building block类都是由GraphObjects抽象对象衍生出来。由于GraphObject不是DOM元素,因此建立和修改它们对性能开销不大。
多个不一样样式的Node节点模板能够经过myDiagram.nodeTemplateMap.add(go.Node)添加
myDiagram.nodeTemplateMap.add("Center",
$(go.Node, "Spot", { selectable: false, isLayoutPositioned: false, // the Diagram.layout will not position this node locationSpot: go.Spot.Center }, $(go.Shape, "Circle", { fill: radBrush, strokeWidth: 0, stroke: null, desiredSize: new go.Size(200, 200) }), // no outline $(go.TextBlock, "Arrowheads", { margin: 1, stroke: "white", font: "bold 14px sans-serif" }) ));
myDiagram.model =
$(go.GraphLinksModel,
{ // this gets copied automatically when there's a link data reference to a new node key
// and is then added to the nodeDataArray
archetypeNodeData: {}, // the node array starts with just the special Center node nodeDataArray: [{ category: "Center", key: "Center" }], // the link array was created above linkDataArray: linkdata }); }
接下来咱们构造一个新的连线模板,在没有为连线指定样式类型的条件下,默认的连线样式。
myDiagram.linkTemplate =
$(go.Link, // the whole link panel
{ routing: go.Link.Normal }, $(go.Shape, // the link shape // the first element is assumed to be main element: as if isPanelMain were true { stroke: "gray", strokeWidth: 2 }), $(go.Shape, // the "from" arrowhead new go.Binding("fromArrow", "fromArrow"), { scale: 2, fill: "#D4B52C" }), $(go.Shape, // the "to" arrowhead new go.Binding("toArrow", "toArrow"), { scale: 2, fill: "#D4B52C" }), { click: showArrowInfo, toolTip: // define a tooltip for each link that displays its information $("ToolTip", $(go.TextBlock, { margin: 4 }, new go.Binding("text", "", infoString).ofObject()) ) } );
每一个模板由GoJS中的面板Panel构成,面板自己做为一个图形对象GraphObject,保存其余图形对象做为它的元素,同时,面板须要负责图形对象的尺寸、位置。
每一个面板创建本身的坐标系,面板中的元素按顺序绘制,从而肯定了内部这些元素的z坐标。
面板有不少种类,好比 Panel.Position,Panel.Auto,Panel.Vertical,Panel.Horizontal ,Panel.Spot ,Panel.Table,Panel.Viewbox, Panel.Link,Panel.Grid等等。
最简单的面板是“Position”(Panel.Position)。每一个元素得到其正常大小
每一个元素的位置是由GraphObject.position属性指定。若是没有指定位置时,元件被定位在(0,0)。全部位置都是面板本身的坐标系中,而不是在图表范围的坐标系。位置可能包括负坐标。
面板的大小恰好足以容纳全部元素。
Panel.Vertical 面板的全部面板元件的排列垂直从上到下
构成面板的图形对象有Shapes、Pictures、TextBlocks Placeholder,它们都有默认模板。
图表(Diagram)在节点没有指定坐标的时候,图表会显示一个用网格形式排列的默认布局。咱们能够显式的给每一个节点分配一个位置来给组织排序来解决这个混乱的组织结构,更容易的解决方案是,咱们会使用布局来自动排列位置。
设置了布局以后,会影响节点位置和链路属性
常见的布局有:
网格布局 go.GridLayout
力导向布局 go.ForceDirectedLayout fdLayout.html
树形布局 go.TreeLayout
径向布局(须要引RadialLayout.js) RadialLayout
布局算法能够重写
myDiagram = $(go.Diagram, "myDiagramDiv", // 画布定义 {layout:$(go.GridLayout, //自动布局定义,设置为网格布局 { comparer: go.GridLayout.smartComparer,//设置从小到大排序 spacing: go.Size.parse("20 20"),//设置节点间隔 comparer: function(a, b){ //重写布局算法,根据其余属性值从新增设置顺序 var ay = a.data.type; var by = b.data.type; if(!!ay&&!!by){ if(ay > by) return -1; if(ay < by) return 1; }else if(!!ay){ return -1; }else if(!!by){ return 1; } } }); });
更多布局方式
https://gojs.net/latest/intro/layouts.html
利用绘图过程当中的一些DiagramListener能够完成更多的数据交互体验和业务逻辑
节点生成事件 | ExternalObjectsDropped |
线生成事件 | LinkDrawn |
线从新链接事件 | LinkRelinked |
删除后事件 | SelectionDeleted |
删除前事件 | SelectionDeleting |
节点移动事件 | SelectionMoved |
节点修改 | Modified |
选择节点更改完成 | ChangedSelection |
添加图表事件的两种方式
第一种在建立Diagram时注册对应的事件的监听
myDiagram = goObj(go.Diagram, "myDiagramDiv", { initialContentAlignment: go.Spot.Center, allowDrop: true, "LinkDrawn": showLinkLabel, "LinkRelinked": showLinkLabel, "animationManager.duration": 800, "undoManager.isEnabled": true }); function showLinkLabel(e) { var label = e.subject.findObject("LABEL"); if (label !== null) label.visible = (e.subject.fromNode.data.figure === "RoundedRectangle"); }
第二种在建立Diagram时完成后监听对应的事件
myDiagram.addDiagramListener("Modified", function(e) { var button = document.getElementById("SaveButton"); if (button) button.disabled = !myDiagram.isModified; var idx = document.title.indexOf("*"); if (myDiagram.isModified) { if (idx < 0) document.title += "*"; } else { if (idx >= 0) document.title = document.title.substr(0, idx); } });
事件应用举例: 约束编程--若是是孤立节点则删除
myDiagram.addDiagramListener("ExternalObjectsDropped", function(e) {
var newnode = e.diagram.selection.first(); if (newnode.linksConnected.count === 0) { // when the selection is dropped but not hooked up to the rest of the graph, delete it e.diagram.commandHandler.deleteSelection(); } });
更多事件参见 https://gojs.net/latest/api/symbols/DiagramEvent.html
结合undoManager建立撤销重作删除的工具栏
$('#deletePart').click(function(){ if("undefined" == typeof myDiagram){ result_prompt(0, "浏览器不兼容此功能,请使用高版本谷歌浏览器!"); return false; } myDiagram.remove(Select_Port); }); $('#undo-buttun').click(function(){ if("undefined" == typeof myDiagram){ result_prompt(0, "浏览器不兼容此功能,请使用高版本谷歌浏览器!"); return false; } myDiagram.undoManager.undo(); }); $('#redo-buttun').click(function(){ if("undefined" == typeof myDiagram){ result_prompt(0, "浏览器不兼容此功能,请使用高版本谷歌浏览器!"); return false; } myDiagram.undoManager.redo(); });
{ contextMenu: $(go.Adornment, "Vertical", new go.Binding("itemArray", "commands"), { itemTemplate: $( "ContextMenuButton", $(go.Shape, { figure: "RoundedRectangle", fill: "transparent", width: 40, height: 24, stroke: "gray", strokeWidth: 1, scale: 1.0, areaBackground: "transparent" }), $(go.TextBlock, { stroke: "deepskyblue", height: 24, width: 40, margin: 0, font: "bold 12px serif", textAlign: "center", verticalAlignment: go.Spot.Center }, new go.Binding("text")), { click: function(e, button) { if (myDiagram.isReadOnly) return; var cmd = button.data; var nodedata = button.part.adornedPart.data; // console.log(nodedata); let curNode = myDiagram.findNodeForKey(nodedata.key); options.contextMenu(curNode, cmd.text); // console.log("On " + nodedata.text + " " + cmd.text + ": " + cmd.action); } } ) }) }
{ text: "开始策略", figure: "Ellipse", fill: "#FEF7E7", stroke: '#FDCF90', info: "", type: "start", commands: [{ text: "查看", action: "view" }, { text: "删除", action: "view" }], },
{fromPort: "B", toPort: "T", from: -1, to: -3,category: "auditedDottedLine"}
// 自定义虚线样式 myDiagram.linkTemplateMap.add( "auditedDottedLine", $( go.Link, { selectable: true, selectionAdornmentTemplate: linkSelectionAdornmentTemplate }, { relinkableFrom: true, relinkableTo: true, reshapable: true }, { routing: go.Link.AvoidsNodes, curve: go.Link.JumpOver, corner: 5, toShortLength: 4 }, $(go.Shape, { isPanelMain: true, strokeWidth: 2, strokeDashArray: [3, 3] }), $(go.Shape, { toArrow: "Standard", stroke: null }), $( go.Panel, "Auto", $( go.Shape, "RoundedRectangle", new go.Binding("fill", "text", function(v) { return v ? "#F8F8F8" : null; }), { stroke: null, fill: null } ), $( go.TextBlock, { segmentIndex: 1, segmentFraction: 0.5, textAlign: "center", font: "10pt helvetica, arial, sans-serif", stroke: "blue", margin: 2, minSize: new go.Size(10, NaN) // editable: true }, new go.Binding("text").makeTwoWay() ) ) ) );
$(go.Shape, "Rectangle", { width: 40, height: 60, margin: 4, fill: null, strokeWidth: 2, strokeDashArray: [6, 6, 2, 2] }),
myDiagram.nodeTemplate = $(
go.Node,
"Spot", $( go.Panel, "Auto", { name: "PANEL" }, new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify), $( go.Shape, "Rectangle", { portId: "", fromLinkable: true, toLinkable: true, cursor: "pointer", fill: "white", stroke: "black", strokeWidth: 1 }, new go.Binding("figure"), new go.Binding("strokeDashArray"), new go.Binding("fill") ), )
selectionChanged: function(eventPart) { var dom = $$(".my-diagram-div canvas"); dom.unbind("click", myFunction).bind("click", myFunction); function myFunction(e) { let position = { x: e.clientX, y: e.clientY }; options.changeNodeSelection(eventPart.data, position); dom.unbind("click", myFunction); } }
let canvas = $(".my-diagram-div"); let selectHandlerDom = $('.select-handler'); canvas.on('input propertychange','textarea',e => { selectHandlerDom.css({ top:position.y + 20 +'px', left:position.x - 20 +'px', 'z-index':10000 }); this.filterHandlerOptions(e.target.value); }) selectHandlerDom.unbind('click').on('click','li',e => { let val = $(e.target).text() this.myDiagram.model.setDataProperty(data, 'text',val); canvas.find('textarea').val(val); }) canvas.click(e => { selectHandlerDom.css({ 'z-index':-1 }) })
1) 在文件中搜索7eba17a4ca3b1a8346
,找到相似a.Jv=d[w.Jg("7eba17a4ca3b1a8346")][w.Jg("78a118b7")](d,w.um,4,4);
这样结构的代码
2) 将其注释,替换成a.Jv=function(){return true;};
layout: $(go.TreeLayout, { angle: 90 }),
设置了布局,连线的起点和重点就会受布局的影响,能够即便不保存节点的位置信息,绘制出来的图形也按照必定规律排列
layout: $(go.LayeredDigraphLayout, { isInitial: false, direction: 90, columnSpacing: 50, isOngoing: false, layerSpacing: 50 }),
取消了布局设置,须要保存节点的位置信息,才能还原出节点的连线位置信息
$( go.TextBlock, { font: "bold 11pt Helvetica, Arial, sans-serif", margin: 8, maxSize: new go.Size(300, NaN), wrap: go.TextBlock.WrapFit, editable: true, textEdited: function(textBlock, previousText, currentText) { console.log(textBlock,textBlock.part.data); options.changeNodeSelection(textBlock.part.data); } }, new go.Binding("text").makeTwoWay() )
makeImageData方法经过HTMLCanvasElement.toDataURL()方法实现的
downLoadImage(name) { // 不设置,下载的图片残缺不全 // this.myDiagram.autoScale = go.Diagram.Uniform; var a = document.createElement("a"); a.href = this.myDiagram.makeImageData({ scale: 1, type: "image/png", maxSize: new go.Size(Infinity, Infinity) }); a.download = name; a.click(); },
Invalid div id; div already has a Diagram associated with it.
解决方法:myDiagram.div=null;
10.设置了树形折叠菜单以后,当树形菜单有超过一级以上的叶子节点时,本该隐藏的叶子节点显示出来,解决的要点,要向下面这样设置显示和隐藏
myDiagram.nodeTemplate = $(go.Node, "Horizontal", { deletable: false, selectable: false, isTreeExpanded: false,//折叠所有子节点 // toolTip: tooltiptemplate, }, myDiagram.addDiagramListener("InitialLayoutCompleted", function (e) { if (EditType != 'export') { // 只展现一级菜单 e.diagram.findTreeRoots().each(function (r) { r.expandTree(2) }); } });
myDiagram.add( $(go.Part, "Table", { position: new go.Point(300, 10), selectable: false }, $(go.TextBlock, "Key", { row: 0, font: "700 14px Droid Serif, sans-serif" }), // end row 0 $(go.Panel, "Horizontal", { row: 1, alignment: go.Spot.Left }, $(go.Shape, "Rectangle", { desiredSize: new go.Size(30, 30), fill: bluegrad, margin: 5 }), $(go.TextBlock, "Males", { font: "700 13px Droid Serif, sans-serif" }) ), // end row 1 $(go.Panel, "Horizontal", { row: 2, alignment: go.Spot.Left }, $(go.Shape, "Rectangle", { desiredSize: new go.Size(30, 30), fill: pinkgrad, margin: 5 }), $(go.TextBlock, "Females", { font: "700 13px Droid Serif, sans-serif" }) ) // end row 2 ));
myDiagram.nodeTemplate = $(go.Node, "Auto", { deletable: false, toolTip: tooltiptemplate }, new go.Binding("text", "name"), $(go.Shape, "Rectangle", { fill: "orange", stroke: "black", stretch: go.GraphObject.Fill, alignment: go.Spot.Center }, new go.Binding("fill", "gender", genderBrushConverter)), $(go.Panel, "Vertical", $(go.TextBlock, { font: "bold 8pt Helvetica, bold Arial, sans-serif", alignment: go.Spot.Center, margin: 6 }, new go.Binding("text", "name")), $(go.TextBlock, new go.Binding("text", "kanjiName")) ) );
myDiagram.nodeTemplate = $( ... $("TreeExpanderButton", { alignment: go.Spot.Right, alignmentFocus: go.Spot.Left, "ButtonBorder.figure": "Rectangle" })
...
// define the Node template, representing an entity myDiagram.nodeTemplate = $(go.Node, "Auto", // the whole node panel { selectionAdorned: true, resizable: true, layoutConditions: go.Part.LayoutStandard & ~go.Part.LayoutNodeSized, fromSpot: go.Spot.AllSides, toSpot: go.Spot.AllSides, isShadowed: true, shadowColor: "#C5C1AA" }, new go.Binding("location", "location").makeTwoWay(), // whenever the PanelExpanderButton changes the visible property of the "LIST" panel, // clear out any desiredSize set by the ResizingTool. new go.Binding("desiredSize", "visible", function(v) { return new go.Size(NaN, NaN); }).ofObject("LIST"), // define the node's outer shape, which will surround the Table $(go.Shape, "Rectangle", { fill: lightgrad, stroke: "#756875", strokeWidth: 3 }), $(go.Panel, "Table", { margin: 8, stretch: go.GraphObject.Fill }, $(go.RowColumnDefinition, { row: 0, sizing: go.RowColumnDefinition.None }), // the table header $(go.TextBlock, { row: 0, alignment: go.Spot.Center, margin: new go.Margin(0, 14, 0, 2), // leave room for Button font: "bold 16px sans-serif" }, new go.Binding("text", "key")), // the collapse/expand button $("PanelExpanderButton", "LIST", // the name of the element whose visibility this button toggles { row: 0, alignment: go.Spot.TopRight }), // the list of Panels, each showing an attribute $(go.Panel, "Vertical", { name: "LIST", row: 1, padding: 3, alignment: go.Spot.TopLeft, defaultAlignment: go.Spot.Left, stretch: go.GraphObject.Horizontal, itemTemplate: itemTempl }, new go.Binding("itemArray", "items")) ) // end Table Panel ); // end Node
myDiagram.nodeTemplateMap.add("Recycle", $(go.Node, "Auto", { portId: "to", toLinkable: true, deletable: false, layerName: "Background", locationSpot: go.Spot.Center }, new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify), { dragComputation: function(node, pt, gridpt) { return pt; } }, { mouseDrop: function(e, obj) { myDiagram.commandHandler.deleteSelection(); } }, $(go.Shape, { fill: "lightgray", stroke: "gray" }), $(go.TextBlock, "Drop Here\nTo Delete", { margin: 5, textAlign: "center" }) ));
function makeTooltip(str) { // a helper function for defining tooltips for buttons return $("ToolTip", $(go.TextBlock, str)); }
myDiagram.groupTemplate = $(go.Group, "Auto", { // define the group's internal layout layout: $(go.TreeLayout, { angle: 90, arrangement: go.TreeLayout.ArrangementHorizontal, isRealtime: false }), // the group begins unexpanded; // upon expansion, a Diagram Listener will generate contents for the group isSubGraphExpanded: false, // when a group is expanded, if it contains no parts, generate a subGraph inside of it subGraphExpandedChanged: function(group) { if (group.memberParts.count === 0) { randomGroup(group.data.key); } } }, $(go.Shape, "Rectangle", { fill: null, stroke: "gray", strokeWidth: 2 }), $(go.Panel, "Vertical", { defaultAlignment: go.Spot.Left, margin: 4 }, $(go.Panel, "Horizontal", { defaultAlignment: go.Spot.Top }, // the SubGraphExpanderButton is a panel that functions as a button to expand or collapse the subGraph $("SubGraphExpanderButton"), $(go.TextBlock, { font: "Bold 18px Sans-Serif", margin: 4 }, new go.Binding("text", "key")) ), // 设置 对象的目的是, 让组自适应内部节点的大小; $(go.Placeholder, { padding: new go.Margin(0, 10) }) ) // end Vertical Panel ); // end Groupgo.Placeholder
myDiagram.model.addNodeData({ key: name, isGroup: true, group: group });
var inspector = new Inspector("myInfo", myDiagram, { properties: { // key would be automatically added for nodes, but we want to declare it read-only also: "key": { readOnly: true, show: Inspector.showIfPresent }, // fill and stroke would be automatically added for nodes, but we want to declare it a color also: "fill": { show: Inspector.showIfPresent, type: 'color' }, "stroke": { show: Inspector.showIfPresent, type: 'color' } } });
// get tooltip text from the object's data function tooltipTextConverter(person) { var str = ""; str += "Born: " + person.birthYear; if (person.deathYear !== undefined) str += "\nDied: " + person.deathYear; if (person.reign !== undefined) str += "\nReign: " + person.reign; return str; } // define tooltips for nodes var tooltiptemplate = $("ToolTip", { "Border.fill": "whitesmoke", "Border.stroke": "black" }, $(go.TextBlock, { font: "bold 8pt Helvetica, bold Arial, sans-serif", wrap: go.TextBlock.WrapFit, margin: 5 }, new go.Binding("text", "", tooltipTextConverter)) ); myDiagram.nodeTemplate = $(go.Node, "Horizontal", { deletable: false, selectable: false, toolTip: tooltiptemplate, })
其它效果参见goJS的示例
1.各类箭头样式 arrowheads.html
2.全部的形状shapes.html
3.自定义节点上下文 customContextMenu.html
4.自定义卷起折叠 customExpandCollapse.html
5.自定义选择输入框 customTextEditingTool.html
6.定义多个连线的入口和出口 dataFlow.html draggablePorts.html
鼠标右键动态增删端口 dynamicPorts.html
7.实体关系 连线会动态连接 避免交错在一块儿 entityRelationship.html
8.鼠标通过时显示多行节点信息 dataVisualization.html
9.拖动排序 dragDropFields.html
10.限制节点在特定范围内移动 且不能触碰到边缘 dragUnoccupied.html
11.手势缩放功能 gestureBehavior.html
12.鼠标通过时显示按钮 hoverButtons.html
var removeLinks=[]; //首先拿到这个节点的对象 var node = myDiagram.findNodeForKey('key'); //获取节点全部线 node.findLinksConnected().each(function(link) { removeLinks.push(link.data); } ); myDiagram.model.removeLinkDataCollection(removeLinks);
myDiagram.addDiagramListener("LinkDrawn",function(e){ (e.subject.data ) //这是这个线条的数据 }) ;
diagram.addModelChangedListener(function(evt) { // ignore unimportant Transaction events if (!evt.isTransactionFinished) return; var txn = evt.object; // a Transaction if (txn === null) return; // iterate over all of the actual ChangedEvents of the Transaction txn.changes.each(function(e) { // ignore any kind of change other than adding/removing a node if (e.modelChange !== "nodeDataArray") return; // record node insertions and removals if (e.change === go.ChangedEvent.Insert) { console.log(evt.propertyName + " added node with key: " + e.newValue.key); } else if (e.change === go.ChangedEvent.Remove) { console.log(evt.propertyName + " removed node with key: " + e.oldValue.key); } }); });
myDiagram.findNodeForKey(key).data //key值是节点的key
let nodeData={ text: "Start", figure: "Ellipse", fill: "#00AD5F", info: "", type: "start" };
myDiagram.model.addNodeData(nodeData); // 须有位置信息
myDiagram.remove(part)
let linkData ={ from: newnode.data.key, to: oldnode.data.key, text: "true", side: "Left", isHighlighted:false};
myDiagram.model.addLinkData(linkData); // linkData是连线数据
key.findNodesOutOf()
myDiagram.model.toJson(); // 获得结果为json字符串
myDiagram.model = go.Model.fromJson(model); // 传入参数model为json字符串
var node=myDiagram.findNodeForKey('key');
var nodeData=myDiagram.model.findNodeDataForKey('key');
var nodes=myDiagram.nodes; //遍历输出节点对象 nodes.each(function (node) { console.log(node.data.text); });
node.findTreeChildrenNodes().each(function(cNode) { console.log(cNode.data) });
var node=myDiagram.findNodeForKey('key'); node.findLinksConnected().each(function(link) {console.log(link.data)});
var node=myDiagram.findNodeForKey('key'); node.findLinksOutOf().each(function(link) {console.log(link.data)});
// 修改单个节点属性 myDiagram.model.updateTargetBindings(node.data) // 批量修改节点属性 myDiagram.model.nodeDataArray myDiagram.model.linkDataArray //修改完成调用如下方法完成重建 myDiagram.rebuildParts()
更新节点API
// 更新方式一
let curDataNode = myDiagram.model.findNodeDataForKey(this.clickNodeKey); curDataNode.nodeItem = this[obj.type + "Info"]; myDiagram.model.updateTargetBindings(curDataNode);
// 更新方式二 myDiagram.model.setDataProperty(curNode, "data", curNode.data); console.log("curNode.data", curNode.data);
goJS资料
2.https://www.cnblogs.com/helloluckworld/articles/9592238.html 去除水印(实用)
3.goJS 绘制web流程图 https://blog.csdn.net/kenhins/article/details/79043198 (收获很大)
4.关于 Gojs 你可能用到的方法 / gojs自定义 / gojs
5.https://blog.csdn.net/sinat_20522337/article/details/79158122
6.https://juejin.im/post/5b875d85e51d4538c0220603
7.https://gojs.net/latest/intro/nodes.html 官方教程
8.https://blog.csdn.net/qq_29287561/article/details/81066004 画布比例自适应
9. goJS入门教程 https://liuxiaofan.com/2018/03/16/3521.html
10. gojS事件 https://blog.csdn.net/pdw2009/article/details/82993971
11. gojs 初探 https://www.wengbi.com/thread_50581_1.html
12. gojs的一些使用技巧 https://blog.csdn.net/MEdwardM/article/details/52528236