js插件---在线mindmap实现方案(gojs)


js插件---在线mindmap实现方案(gojs)

一、总结

一句话总结:稍微花点时间看看文档,超级简单的

文档地址:https://gojs.net/latest/intro/index.html

 

 

1、mind map js插件如何搜索?

mind map js

这些都是很好的关键词

多使用google,google搜索比百度搜索好用多了,不仅中文,而且英文

 

 

 

2、第二步,把官网参考文档扫一遍?

翻译 功能 接口

如果英文看不了,就把网页翻译成中文就好啰

稍微看下,有点印象就好,看看提供了哪些功能接口

因为插件的使用是非常简单的

https://gojs.net/latest/intro/index.html

 

 

3、gojs插件的移动端支持?

捏合缩放 长按

您可以通过多种方式与此图表进行交互:

  • 您可以通过单击选择零件。选定的节点用Adornment突出显示,Adornment是围绕节点的蓝色矩形。所选链接在链接路径后面以蓝线突出显示。
  • 可以一次选择多个部件。单击以添加到选择时按住Shift键。单击以切换是否选中该部件时按住Control键。
  • 多选的另一种方法是在背景中的某个点(而不是在某个部分上)进行鼠标按下,稍等片刻,然后拖动一个框。选择鼠标向上时框中的部件。Shift和Control修饰符也适用。
  • Ctrl-A选择图表中的所有部分。
  • 通过选择并拖动来移动一个或多个节点。
  • 复制选定的部件可以使用复制/粘贴(Ctrl-C / Ctrl-V)或Ctrl-鼠标拖动。
  • 使用Delete键删除所选部件。
  • 如果滚动条可见或者整个零件集合小于图表的可视区域(“视口”),则可以在背景中使用鼠标按下平移图表(而不是在零件上)等候。
  • 使用鼠标滚轮向上和向下滚动,使用Shift鼠标滚轮向左和向右滚动。Ctrl-mouse-wheel放大和缩小。

您还可以用手指在触摸设备上平移,捏合缩放,选择,复制,移动,删除,撤消和重做。大多数可以从键盘调用的命令都可以从默认的上下文菜单中调用,您可以通过按下手指并保持静止一会儿来获得该命令。

 

4、go-debug.js和go.js的区别?

错误 检查 调试 开发 生产

在您可以执行任何JavaScript代码来构建Diagram之前,您需要加载GoJS库。当您包含库时,“ go”JavaScript对象将包含所有GoJS类型。在开发过程中,我们建议您加载“go-debug.js”而不是“go.js”,以获得额外的运行时错误检查和调试功能。

当出现问题时,GoJS会输出错误或警告信息。使用GoJS进行开发时,请务必查看浏览器的开发者控制台以获取信息。库的“go-debug.js”版本包含额外的类型检查和错误检查代码,应该在开发期间使用。“go.js”版本的错误检查较少,但结果更快,应该在生产中使用

 

5、go.js中的$符号一般是什么意思?

函数 go.GraphObject.make
var $ = go.GraphObject.make;

其它js库也是把$符号看成一个库,比如jquery

GoJS定义了一个静态函数GraphObject.make,它在构造GraphObjects时非常有用,而不必考虑和跟踪临时变量名。此静态函数还支持以嵌套方式构建对象,其中缩进为您提供了有关可视树中深度的线索,这与上面显示的简单线性代码不同。

GraphObject.make是一个函数,其第一个参数必须是类类型,通常是GraphObject的子类

GraphObject.make的 其他参数可能有以下几种类型:

  • 具有属性/值对的纯JavaScript对象 - 在要构造的对象上设置这些属性值
  • 一个GraphObject,作为元素添加到正在构造Panel
  • 一个GoJS枚举值常量,用作可以接受这样一个值的正在构造的对象的唯一属性的值
  • 一个字符串,用于设置正在构造的对象TextBlock.textShape.figurePicture.sourcePanel.type属性
  • 一个RowColumnDefinition,用于描述在表的行或列面板小号
  • 一个JavaScript数组,持有GraphObject.make的参数,在从函数返回多个参数时很有用
  • 以适当方式用于构造对象的其他专用对象

我们可以使用go.GraphObject.make重写上面的代码,以产生完全相同的结果:

 1   var $ = go.GraphObject.make;
 2   diagram.add(
 3     $(go.Node,go.Panel.Auto,
 4       $(go.Shape,
 5         {图:“RoundedRectangle”,
 6           填充:“lightblue” }),
 7       $(go.TextBlock,
 8         {text:“你好!” ,
 9           保证金:5 })
10     ));

 

 

 

6、go.js改变控件样式代码?

go.Brush
1   diagram.add(
2     $(go.Node, "Auto",
3       $(go.Shape, "RoundedRectangle",
4         { fill: $(go.Brush, "Linear",
5                   { 0.0: "Violet", 1.0: "Lavender" }) }),
6       $(go.TextBlock, "Hello!",
7         { margin: 5 })
8     ));

 

 

7、go.js的模板模型的使用方式?

数据 模板 分离 template data link

采用的是数据模型和节点模板分离的模式

模板(也就是节点样式)由Diagram.nodeTemplate来设置

节点的数据和节点之间的链接关系由GraphLinksModel.nodeDataArrayGraphLinksModel.linkDataArray来设置

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

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

要自动使用模板,请提供一个模型,其中包含每个节点的数据和每个链接的数据。GraphLinksModel保持节点的数据和链接数据作为值的集合(实际上阵列) GraphLinksModel.nodeDataArrayGraphLinksModel.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); 
 

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

 diagram.nodeTemplate = //提供自定义节点外观 $(go.Node,“Auto” $(go.Shape, {图:“RoundedRectangle” 填充:“白色” }), $(go.TextBlock, {text:“你好!”  保证金:5 }) ); var nodeDataArray = [ {key:“Alpha” }, {key:“Beta” } ]。 var linkDataArray = [ {from:“Alpha”,to:“Beta” } ]。diagram.model  = new go.GraphLinksModel(nodeDataArray,linkDataArray); 
 

 

 

 

8、为什么go.js采用模板(节点样式)和模型(节点数据,节点间的逻辑)分离的方式,为什么不采用用一个函数来创建一个节点的方式?

低效 扩展性

a、更新时刷新低效

b、扩展性不好

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

  var node1 = $(go.Node,“Auto” $(go.Shape, {图:“RoundedRectangle” 填充:“lightblue” }), $(go.TextBlock, {text:“Alpha” 保证金:5 }) diagram.add(节点1); var node2 = $(go.Node,“Auto” $(go.Shape, {图:“RoundedRectangle” 填充:“粉红色” }), $(go.TextBlock, {text:“Beta” 保证金:5 }) ); diagram.add(节点2);  diagram.add( $(go.Link, {fromNode:node1,toNode:node2}, $(go.Shape) )); 
 

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

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

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

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

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

 

9、go.js中的TreeModel和GraphlinksModel的区别是什么?

简单 没有 链接数据

一种更简单的模型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”,颜色:“lightblue” }, {key:“Beta”,父级:“Alpha”,颜色:“黄色” }, //注意“父级”属性 {key:“Gamma”,父级:“Alpha”,颜色:“orange” }, {key:“Delta”,父母:“Alpha”,颜色:“lightgreen” } ]。diagram.model  = new go.TreeModel(nodeDataArray);

 

 

10、go.js改变节点让节点闪烁?

事务 数据绑定 setDataProperty

改变节点,改变节点之间的链接关系,比如节点的选中事件等,都是属于数据绑定的操作

all model changes should happen in a transaction
 1   diagram.nodeTemplate =
 2     $(go.Node, "Auto",
 3       { locationSpot: go.Spot.Center },
 4       $(go.Shape, "RoundedRectangle",
 5         { // default values if the data.highlight is undefined:
 6           fill: "yellow", stroke: "orange", strokeWidth: 2 },
 7         new go.Binding("fill", "highlight", function(v) { return v ? "pink" : "lightblue"; }),
 8         new go.Binding("stroke", "highlight", function(v) { return v ? "red" : "blue"; }),
 9         new go.Binding("strokeWidth", "highlight", function(v) { return v ? 3 : 1; })),
10       $(go.TextBlock,
11         { margin: 5 },
12         new go.Binding("text", "key"))
13     );
14 
15   diagram.model.nodeDataArray = [
16     { key: "Alpha", highlight: false }  // just one node, and no links
17   ];
18 
19   function flash() {
20     var model = diagram.model;
21     // all model changes should happen in a transaction
22     model.startTransaction("flash");
23     var data = model.nodeDataArray[0];  // get the first node data
24     model.setDataProperty(data, "highlight", !data.highlight);
25     model.commitTransaction("flash");
26   }
27   function loop() {
28     setTimeout(function() { flash(); loop(); }, 500);
29   }
30   loop();

 

 

11、添加按钮,并且给按钮添加点击事件?

column item arrays panel

 

 1   diagram.nodeTemplate =
 2     $(go.Node, "Auto",
 3       $(go.Shape, { fill: "white" }),
 4       $(go.Panel, "Table",
 5         new go.Binding("itemArray", "people"),
 6         {
 7           defaultAlignment: go.Spot.Left,
 8           itemTemplate:
 9             $(go.Panel, "TableRow",
10               new go.Binding("background", "row",
11                              function(i) { return i%2 === 0 ? "lightgreen" : "transparent" })
12                   .ofObject(),
13               $(go.TextBlock, new go.Binding("text", "name"),
14                 { column: 0, margin: 2, font: "bold 10pt sans-serif" }),
15               $(go.TextBlock, new go.Binding("text", "phone"),
16                 { column: 1, margin: 2 }),
17               $(go.TextBlock, new go.Binding("text", "loc"),
18                 { column: 2, margin: 2 }),
19               $("Button",
20                 {
21                   column: 3,
22                   margin: new go.Margin(0, 1, 0, 0),
23                   click: function(e, obj) {
24                     // OBJ is this Button Panel;
25                     // find the TableRow Panel containing it
26                     var itempanel = obj.panel;
27                     alert("Clicked on row " + itempanel.row + " for " + itempanel.data.name);
28                   }
29                 },
30                 $(go.Shape, "FivePointedStar",
31                   { desiredSize: new go.Size(8, 8) })
32               )
33             )  // end of itemTemplate
34         })
35     );
36 
37   diagram.model =
38     $(go.GraphLinksModel,
39       {
40         nodeDataArray: [
41           { key: "group1",
42             people: [
43               { name: "Alice", phone: "2345", loc: "C4-E18" },
44               { name: "Bob", phone: "9876", loc: "E1-B34" },
45               { name: "Carol", phone: "1111", loc: "C4-E23" },
46               { name: "Ted", phone: "2222", loc: "C4-E197" },
47               { name: "Robert", phone: "5656", loc: "B1-A27" },
48               { name: "Natalie", phone: "5698", loc: "B1-B6" }
49             ] }
50         ]
51       }
52     );
53 
54   diagram.initialContentAlignment = go.Spot.Center;

 

 

12、如何改变选中节点的画表颜色(未完)?

selection

Users normally select Parts manually by clicking on them and they deselect them by clicking in the background or pressing the Esc key. You can select parts programmatically by setting Part.isSelected.

You can show that a part is selected by either or both of two general techniques: adding Adornments or changing the appearance of some of the elements in the visual tree of the selected Part.

就在文档的Selection里面:

可以试着去查看修改节点文字的那个函数的源码

node有一个isSelected属性(不是所需代码,只是举例)

  function onSelectionChanged(node) {
    var icon = node.findObject("Icon");
    if (icon !== null) {
      if (node.isSelected)
        icon.fill = "cyan";
      else
        icon.fill = "lightgray";
    }
  }

然后配上修改节点属性的事务(不是所需代码,只是举例)

changeColor = function() {
  var model = diagram.model;
  diagram.startTransaction();
  // alternate between lightblue and lightgreen colors
  var oldcolor = model.modelData.color;
  var newcolor = (oldcolor === "lightblue" ? "lightgreen" : "lightblue");
  model.setDataProperty(model.modelData, "color", newcolor);
  diagram.commitTransaction("changed shared color");
}

 

13、使用重定义了$的插件的时候最容易出现的问题是什么,比如gojs做mindmap的时候?

$ 替换 冲突

如下面这段代码,定义了$的值,还是会习惯性的把$当成jQuery来用,所以难免出错

var $ = go.GraphObject.make;
<script> $(function () { //console.log('1111111111'); gojs_init(); gojs_load(); }); </script>

最好的方式是把这个插件(比如这里是go.js)中的$替换成别的,比如$$、Go、$go

var $go = go.GraphObject.make;

这样就互相不冲突了

 

 

 

 

二、在线mind-map

百度盘下载地址:

 

1、截图

 

2、代码

  1 <!DOCTYPE html>
  2 <html>
  3 <head>
  4     <meta name="viewport" content="width=device-width, initial-scale=1">
  5     <title>Mind Map</title>
  6     <meta name="description" content="A mind map editor, showing how subtrees can be moved, copied, deleted, and laid out." />
  7     <!-- Copyright 1998-2018 by Northwoods Software Corporation. -->
  8     <meta charset="UTF-8">
  9     <script src="go.js"></script>
 10     <!--<script src="go-debug.js"></script>-->
 11 
 12 </head>
 13 <body onload="init()">
 14 <div id="sample">
 15     <div id="myDiagramDiv" style="border: solid 1px black; width:100%; height:300px;"></div>
 16 
 17     <button id="gojs_SaveButton" onclick="gojs_save()">Save</button>
 18     <button onclick="jojs_load()">Load</button>
 19     <button onclick="gojs_layoutAll()">Layout</button>
 20     <button onclick="myDiagram.commandHandler.deleteSelection()">刪除</button>
 21     <button onclick="myDiagram.commandHandler.undo()">Undo</button>
 22     <button onclick="myDiagram.commandHandler.redo()">Redo</button>
 23     <button onclick="myDiagram.commandHandler.editTextBlock()">修改文字</button>
 24     <button onclick="fry_gojs_clear()">清空</button>
 25     <button id="fry_gojs_add_first_btn" onclick="fry_gojs_add_first()" disabled>增加</button>
 26     <input type="color" id="fry_gojs_color">
 27 
 28     <br />
 29     <textarea id="gojs_mySavedModel" style="width:100%;height:400px;display: none;">
 30 { "class": "go.TreeModel",
 31   "nodeDataArray": [
 32 {"key":0, "text":"Mind Map", "loc":"0 0"}
 33  ]
 34 }
 35   </textarea>
 36     <script id="code">
 37         function init() {
 38             if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
 39             var $ = go.GraphObject.make;
 40             myDiagram =
 41                 $(go.Diagram, "myDiagramDiv",
 42                     {
 43                         padding: 20,
 44                         // when the user drags a node, also move/copy/delete the whole subtree starting with that node
 45                         "commandHandler.copiesTree": true,
 46                         "commandHandler.deletesTree": true,
 47                         "draggingTool.dragsTree": true,
 48                         initialContentAlignment: go.Spot.Center,  // center the whole graph
 49                         "undoManager.isEnabled": true
 50                     });
 51             // when the document is modified, add a "*" to the title and enable the "Save" button
 52             myDiagram.addDiagramListener("Modified", function(e) {
 53                 var button = document.getElementById("gojs_SaveButton");
 54                 if (button) button.disabled = !myDiagram.isModified;
 55                 var idx = document.title.indexOf("*");
 56                 if (myDiagram.isModified) {
 57                     if (idx < 0) document.title += "*";
 58                 } else {
 59                     if (idx >= 0) document.title = document.title.substr(0, idx);
 60                 }
 61             });
 62             // a node consists of some text with a line shape underneath
 63             myDiagram.nodeTemplate =
 64                 $(go.Node, "Vertical",
 65                     { selectionObjectName: "TEXT" },
 66                     $(go.TextBlock,
 67                         {
 68                             name: "TEXT",
 69                             minSize: new go.Size(30, 15),
 70                             editable: true
 71                         },
 72                         // remember not only the text string but the scale and the font in the node data
 73                         new go.Binding("text", "text").makeTwoWay(),
 74                         new go.Binding("scale", "scale").makeTwoWay(),
 75                         new go.Binding("font", "font").makeTwoWay()),
 76                     $(go.Shape, "LineH",
 77                         {
 78                             stretch: go.GraphObject.Horizontal,
 79                             strokeWidth: 3, height: 3,
 80                             // this line shape is the port -- what links connect with
 81                             portId: "", fromSpot: go.Spot.LeftRightSides, toSpot: go.Spot.LeftRightSides
 82                         },
 83                         new go.Binding("stroke", "brush"),
 84                         // make sure links come in from the proper direction and go out appropriately
 85                         new go.Binding("fromSpot", "dir", function(d) { return spotConverter(d, true); }),
 86                         new go.Binding("toSpot", "dir", function(d) { return spotConverter(d, false); })),
 87                     // remember the locations of each node in the node data
 88                     new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
 89                     // make sure text "grows" in the desired direction
 90                     new go.Binding("locationSpot", "dir", function(d) { return spotConverter(d, false); })
 91                 );
 92             // selected nodes show a button for adding children
 93             myDiagram.nodeTemplate.selectionAdornmentTemplate =
 94                 $(go.Adornment, "Spot",
 95                     $(go.Panel, "Auto",
 96                         // this Adornment has a rectangular blue Shape around the selected node
 97                         $(go.Shape, { fill: null, stroke: "dodgerblue", strokeWidth: 3 }),
 98                         $(go.Placeholder, { margin: new go.Margin(4, 4, 0, 4) })
 99                     ),
100                     // and this Adornment has a Button to the right of the selected node
101                     $("Button",
102                         {
103                             alignment: go.Spot.Right,
104                             alignmentFocus: go.Spot.Left,
105                             click: addNodeAndLink  // define click behavior for this Button in the Adornment
106                         },
107                         $(go.TextBlock, "+",  // the Button content
108                             { font: "bold 8pt sans-serif" })
109                     )
110                 );
111             // the context menu allows users to change the font size and weight,
112             // and to perform a limited tree layout starting at that node
113             myDiagram.nodeTemplate.contextMenu =
114                 $(go.Adornment, "Vertical",
115                     $("ContextMenuButton",
116                         $(go.TextBlock, "Bigger"),
117                         { click: function(e, obj) { changeTextSize(obj, 1.1); } }),
118                     $("ContextMenuButton",
119                         $(go.TextBlock, "Smaller"),
120                         { click: function(e, obj) { changeTextSize(obj, 1/1.1); } }),
121                     $("ContextMenuButton",
122                         $(go.TextBlock, "Bold/Normal"),
123                         { click: function(e, obj) { toggleTextWeight(obj); } }),
124                     $("ContextMenuButton",
125                         $(go.TextBlock, "Layout"),
126                         {
127                             click: function(e, obj) {
128                                 var adorn = obj.part;
129                                 adorn.diagram.startTransaction("Subtree Layout");
130                                 layoutTree(adorn.adornedPart);
131                                 adorn.diagram.commitTransaction("Subtree Layout");
132                             }
133                         }
134                     )
135                 );
136             // a link is just a Bezier-curved line of the same color as the node to which it is connected
137             myDiagram.linkTemplate =
138                 $(go.Link,
139                     {
140                         curve: go.Link.Bezier,
141                         fromShortLength: -2,
142                         toShortLength: -2,
143                         selectable: false
144                     },
145                     $(go.Shape,
146                         { strokeWidth: 3 },
147                         new go.Binding("stroke", "toNode", function(n) {
148                             if (n.data.brush) return n.data.brush;
149                             return "black";
150                         }).ofObject())
151                 );
152             // the Diagram's context menu just displays commands for general functionality
153             myDiagram.contextMenu =
154                 $(go.Adornment, "Vertical",
155                     $("ContextMenuButton",
156                         $(go.TextBlock, "Undo"),
157                         { click: function(e, obj) { e.diagram.commandHandler.undo(); } },
158                         new go.Binding("visible", "", function(o) { return o.diagram && o.diagram.commandHandler.canUndo(); }).ofObject()),
159                     $("ContextMenuButton",
160                         $(go.TextBlock, "Redo"),
161                         { click: function(e, obj) { e.diagram.commandHandler.redo(); } },
162                         new go.Binding("visible", "", function(o) { return o.diagram && o.diagram.commandHandler.canRedo(); }).ofObject()),
163                     $("ContextMenuButton",
164                         $(go.TextBlock, "Save"),
165                         { click: function(e, obj) { gojs_save(); } }),
166                     $("ContextMenuButton",
167                         $(go.TextBlock, "Load"),
168                         { click: function(e, obj) { jojs_load(); } })
169                 );
170             myDiagram.addDiagramListener("SelectionMoved", function(e) {
171                 var rootX = myDiagram.findNodeForKey(0).location.x;
172                 myDiagram.selection.each(function(node) {
173                     if (node.data.parent !== 0) return; // Only consider nodes connected to the root
174                     var nodeX = node.location.x;
175                     if (rootX < nodeX && node.data.dir !== "right") {
176                         updateNodeDirection(node, "right");
177                     } else if (rootX > nodeX && node.data.dir !== "left") {
178                         updateNodeDirection(node, "left");
179                     }
180                     layoutTree(node);
181                 });
182                 gojs_save();
183                 gojs_layoutAll()
184             });
185             // read in the predefined graph using the JSON format data held in the "gojs_mySavedModel" textarea
186             jojs_load();
187         }
188         function spotConverter(dir, from) {
189             if (dir === "left") {
190                 return (from ? go.Spot.Left : go.Spot.Right);
191             } else {
192                 return (from ? go.Spot.Right : go.Spot.Left);
193             }
194         }
195         function changeTextSize(obj, factor) {
196             var adorn = obj.part;
197             adorn.diagram.startTransaction("Change Text Size");
198             var node = adorn.adornedPart;
199             var tb = node.findObject("TEXT");
200             tb.scale *= factor;
201             adorn.diagram.commitTransaction("Change Text Size");
202         }
203         function toggleTextWeight(obj) {
204             var adorn = obj.part;
205             adorn.diagram.startTransaction("Change Text Weight");
206             var node = adorn.adornedPart;
207             var tb = node.findObject("TEXT");
208             // assume "bold" is at the start of the font specifier
209             var idx = tb.font.indexOf("bold");
210             if (idx < 0) {
211                 tb.font = "bold " + tb.font;
212             } else {
213                 tb.font = tb.font.substr(idx + 5);
214             }
215             adorn.diagram.commitTransaction("Change Text Weight");
216         }
217         function updateNodeDirection(node, dir) {
218             myDiagram.model.setDataProperty(node.data, "dir", dir);
219             // recursively update the direction of the child nodes
220             var chl = node.findTreeChildrenNodes(); // gives us an iterator of the child nodes related to this particular node
221             while(chl.next()) {
222                 updateNodeDirection(chl.value, dir);
223             }
224         }
225         //var fry_brush_group=['skyblue','darkseagreen','palevioletred','coral'];
226         //console.log(fry_brush_group[Math.floor(Math.random()*fry_brush_group.length)]);
227         function addNodeAndLink(e, obj) {
228             //console.log(e);
229             //console.log(obj);
230             var adorn = obj.part;
231             var diagram = adorn.diagram;
232             diagram.startTransaction("Add Node");
233             var oldnode = adorn.adornedPart;
234             var olddata = oldnode.data;
235             //console.log(olddata.brush);
236             //如果沒定義筆刷,就在數組裡面隨機選就好了,多簡單
237             //var fry_brush_group=['skyblue','darkseagreen','palevioletred','coral','palegreen'];
238             //if(typeof olddata.brush == "undefined") olddata.brush=fry_brush_group[Math.floor(Math.random()*fry_brush_group.length)];
239             olddata.brush=document.getElementById("fry_gojs_color").value;
240             //console.log(olddata.brush);
241             // copy the brush and direction to the new node data
242             var newdata = { text: "idea", brush: olddata.brush, dir: olddata.dir, parent: olddata.key };
243             diagram.model.addNodeData(newdata);
244             layoutTree(oldnode);
245             diagram.commitTransaction("Add Node");
246             // if the new node is off-screen, scroll the diagram to show the new node
247             var newnode = diagram.findNodeForData(newdata);
248             if (newnode !== null) diagram.scrollToRect(newnode.actualBounds);
249             gojs_layoutAll();
250         }
251         function layoutTree(node) {
252             if (node.data.key === 0) {  // adding to the root?
253                 gojs_layoutAll();  // lay out everything
254             } else {  // otherwise lay out only the subtree starting at this parent node
255                 var parts = node.findTreeParts();
256                 layoutAngle(parts, node.data.dir === "left" ? 180 : 0);
257             }
258         }
259         function layoutAngle(parts, angle) {
260             var layout = go.GraphObject.make(go.TreeLayout,
261                 { angle: angle,
262                     arrangement: go.TreeLayout.ArrangementFixedRoots,
263                     nodeSpacing: 5,
264                     layerSpacing: 20,
265                     setsPortSpot: false, // don't set port spots since we're managing them with our spotConverter function
266                     setsChildPortSpot: false });
267             layout.doLayout(parts);
268         }
269         function gojs_layoutAll() {
270             var root = myDiagram.findNodeForKey(0);
271             if (root === null) return;
272             myDiagram.startTransaction("Layout");
273             // split the nodes and links into two collections
274             var rightward = new go.Set(go.Part);
275             var leftward = new go.Set(go.Part);
276             root.findLinksConnected().each(function(link) {
277                 var child = link.toNode;
278                 if (child.data.dir === "left") {
279                     leftward.add(root);  // the root node is in both collections
280                     leftward.add(link);
281                     leftward.addAll(child.findTreeParts());
282                 } else {
283                     rightward.add(root);  // the root node is in both collections
284                     rightward.add(link);
285                     rightward.addAll(child.findTreeParts());
286                 }
287             });
288             // do one layout and then the other without moving the shared root node
289             layoutAngle(rightward, 0);
290             layoutAngle(leftward, 180);
291             myDiagram.commitTransaction("Layout");
292         }
293         // Show the diagram's model in JSON format
294         function gojs_save() {
295             document.getElementById("gojs_mySavedModel").value = myDiagram.model.toJson();
296             myDiagram.isModified = false;
297         }
298         function jojs_load() {
299             myDiagram.model = go.Model.fromJson(document.getElementById("gojs_mySavedModel").value);
300             //console.log(myDiagram.model);
301         }
302         //清空
303         function fry_gojs_clear() {
304             document.getElementById("gojs_mySavedModel").value='{ "class": "go.TreeModel","nodeDataArray": []}';
305             document.getElementById("fry_gojs_add_first_btn").disabled="";
306             jojs_load();
307         }
308         //增加最初那個節點
309         function fry_gojs_add_first(){
310             document.getElementById("gojs_mySavedModel").value='{ "class": "go.TreeModel","nodeDataArray": [{"key":0, "text":"Mind Map", "loc":"0 0"}]}';
311             document.getElementById("fry_gojs_add_first_btn").setAttribute('disabled','disabled');
312             jojs_load();
313         }
314         //改變選中的
315     </script>
316 </div>
317 </body>
318 </html>

 

 

 

 

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM