var $ = go.GraphObject.make;  // for conciseness in defining templates

function buildAlarm(row,column,columnSpan=1){
var obj=$(go.Shape, "Rectangle", // define the node's outer shape
{fill: "yellow", stroke: "black",alignment: go.Spot.TopRight,row: row, column: column, margin: 2, },
new go.Binding("fill", "color"),
new go.Binding("desiredSize", "", function(){ return new go.Size(40, 20) }));
return obj;
} function buildNodeName(row,column,columnSpan=1){
var obj=$(go.TextBlock,
{
row: row, column: column,columnSpan:columnSpan,
maxSize: new go.Size(160, NaN), margin: 2,
font: '500 16px Roboto, sans-serif',
alignment: go.Spot.Top,
editable: true,
isMultiline: false,
minSize: new go.Size(10, 16)
},
new go.Binding("text", "name")
);
return obj;
} function buildFields(row,column,columnSpan=1){
var obj=$(go.TextBlock,
{
row: row, column: column, columnSpan: columnSpan,
font: "12px Roboto, sans-serif",
editable: true,
isMultiline: true,
name: "LIST",
//minSize: new go.Size(10, 16),
},
new go.Binding("text", "", theInfoTextConverter));
return obj;
} function buildExpandNode(){
var obj=$(go.Panel, // this is underneath the "BODY"
{ height: 15 }, // always this height, even if the TreeExpanderButton is not visible
$("TreeExpanderButton"));
return obj;
} function buildContentTable(){
var obj=$(go.Panel, "Table",
{ margin: 6,
maxSize: new go.Size(250, NaN),
margin: new go.Margin(6, 10, 0, 3),
defaultAlignment: go.Spot.Left
},
// the two TextBlocks in column 0 both stretch in width
// but align on the left side
$(go.RowColumnDefinition,
{
column: 0,
// width: 80 ,
stretch: go.GraphObject.Horizontal,
alignment: go.Spot.Left
}),
// the name
//标题
buildNodeName(0,0),
//报警标识
buildAlarm(0,1),
$("PanelExpanderButton", "LIST", // the name of the element whose visibility this button toggles
{ row: 1, column: 2,columnSpan:1, alignment: go.Spot.Center, margin: 0, }),
//属性字段
buildFields(2,0,2));
return obj;
} function buildBackground(){
var obj=$(go.Shape, "Rectangle",
{ stroke: null, strokeWidth: 0 },
new go.Binding("fill", "isHighlighted", function(h) { return h ? "#F44336" : "#A7E7FC"; }).ofObject());
return obj;
} var nodeTemplateFactory={
buildDefaultNodeTemplate:function(){
var obj=$(go.Node, "Vertical",
{ selectionObjectName: "BODY", deletable: false,
//desiredSize: new go.Size(300, 200),
doubleClick: nodeDoubleClick,
mouseEnter: mouseEnter,
mouseLeave: mouseLeave,
selectionChanged:nodeSelectionChanged,
isShadowed: true,
shadowColor: "#C5C1AA",
//resizable: true,
toolTip:
$(go.Adornment, "Auto",
$(go.Shape, { fill: "lightyellow" }),
$(go.TextBlock, "double-click\nfor documentation",
{ margin: 5 })
),
},
$(go.Panel,"Auto",
{ name: "BODY" },
// the outer shape for the node, surrounding the Table
buildBackground(),
// a table to contain the different parts of the node
buildContentTable()),
buildExpandNode());
return obj;
},
buildEnvNodeTemplate:function(){ }
} var nodeIdCounter = -1; // use a sequence to guarantee key uniqueness as we add/remove/modify nodes var myDiagram =
$(go.Diagram, "myDiagramDiv", // the DIV HTML element
{
// Put the diagram contents at the top center of the viewport
initialDocumentSpot: go.Spot.TopCenter,
initialViewportSpot: go.Spot.TopCenter,
initialAutoScale: go.Diagram.UniformToFill,
maxSelectionCount: 1,
//initialAutoScale: go.Diagram.Uniform,
validCycle: go.Diagram.CycleDestinationTree, // make sure users can only create trees
"clickCreatingTool.archetypeNodeData": {}, // allow double-click in background to create a new node
"clickCreatingTool.insertPart": function(loc) { // customize the data for the new node
this.archetypeNodeData = {
key: getNextKey(), // assign the key based on the number of nodes
name: "(new person)",
title: ""
};
return go.ClickCreatingTool.prototype.insertPart.call(this, loc);
},
// allow double-click in background to create a new node
"clickCreatingTool.archetypeNodeData": { text: "Node", color: "white" },
// allow Ctrl-G to call groupSelection()
"commandHandler.archetypeGroupData": { text: "Group", isGroup: true, color: "blue" }, // OR: Scroll to show a particular node, once the layout has determined where that node is
//"InitialLayoutCompleted": function(e) {
// var node = e.diagram.findNodeForKey(28);
// if (node !== null) e.diagram.commandHandler.scrollToPart(node);
//},
layout:
$(go.TreeLayout, // use a TreeLayout to position all of the nodes
{
//treeStyle: go.TreeLayout.StyleLastParents,
// properties for most of the tree:
angle: 90,
nodeSpacing: 10,
layerSpacing: 60,
arrangement: go.TreeLayout.ArrangementHorizontal, // properties for the "last parents":
alternateAngle: 0,
alternateAlignment: go.TreeLayout.AlignmentStart,
alternateNodeIndent: 20,
alternateNodeIndentPastParent: 1,
alternateNodeSpacing: 20,
alternateLayerSpacing: 40,
alternateLayerSpacingParentOverlap: 1,
alternatePortSpot: new go.Spot(0.001, 1, 20, 0),
alternateChildPortSpot: go.Spot.Left
}),
"undoManager.isEnabled": true // enable undo & redo
}); myDiagram.nodeTemplate =nodeTemplateFactory.buildDefaultNodeTemplate(); myDiagram.linkTemplate =$(go.Link, go.Link.Orthogonal,
{ corner: 5, selectable: false },
$(go.Shape, { strokeWidth: 3, stroke: "#424242" } )); /*
myDiagram.linkTemplate =
$(go.Link,
{
curve: go.Link.Bezier,
toEndSegmentLength: 30, fromEndSegmentLength: 30
},
$(go.Shape, { strokeWidth: 1.5 }) // the link shape, with the default black stroke
);
*/ // Overview
var myOverview =
$(go.Overview, "myOverviewDiv", // the HTML DIV element for the Overview
{ observed: myDiagram, contentAlignment: go.Spot.Center }); // tell it which Diagram to show and pan
// define Converters to be used for Bindings 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("SelectionDeleting", function(e) {
var part = e.subject.first(); // e.subject is the myDiagram.selection collection,
// so we'll get the first since we know we only have one selection
myDiagram.startTransaction("clear boss");
if (part instanceof go.Node) {
var it = part.findTreeChildrenNodes(); // find all child nodes
while(it.next()) { // now iterate through them and clear out the boss information
var child = it.value;
var bossText = child.findObject("boss"); // since the boss TextBlock is named, we can access it by name
if (bossText === null) return;
bossText.text = undefined;
}
} else if (part instanceof go.Link) {
var child = part.toNode;
var bossText = child.findObject("boss"); // since the boss TextBlock is named, we can access it by name
if (bossText === null) return;
bossText.text = undefined;
}
myDiagram.commitTransaction("clear boss");
}); var levelColors = ["#AC193D/#BF1E4B", "#2672EC/#2E8DEF", "#8C0095/#A700AE", "#5133AB/#643EBF",
"#008299/#00A0B1", "#D24726/#DC572E", "#008A00/#00A600", "#094AB2/#0A5BC4"];
// override TreeLayout.commitNodes to also modify the background brush based on the tree depth level
myDiagram.layout.commitNodes = function() {
go.TreeLayout.prototype.commitNodes.call(myDiagram.layout); // do the standard behavior
// then go through all of the vertexes and set their corresponding node's Shape.fill
// to a brush dependent on the TreeVertex.level value
myDiagram.layout.network.vertexes.each(function(v) {
if (v.node) {
var level = v.level % (levelColors.length);
var colors = levelColors[level].split("/");
var shape = v.node.findObject("SHAPE");
if (shape) shape.fill = $(go.Brush, "Linear", { 0: colors[0], 1: colors[1], start: go.Spot.Left, end: go.Spot.Right });
}
});
}; // This function is used to find a suitable ID when modifying/creating nodes.
// We used the counter combined with findNodeDataForKey to ensure uniqueness.
function getNextKey() {
var key = nodeIdCounter;
while (myDiagram.model.findNodeDataForKey(key.toString()) !== null) {
key = nodeIdCounter -= 1;
}
return key.toString();
} function nodeDoubleClick(e, obj) {
var clicked = obj.part;
if (clicked !== null) {
var thisemp = clicked.data;
myDiagram.startTransaction("add employee");
var nextkey = getNextKey();
var newemp = { key: nextkey, name: "(new person)", title: "", parent: thisemp.key };
myDiagram.model.addNodeData(newemp);
myDiagram.commitTransaction("add employee");
}
} function theNationFlagConverter(nation) {
return "https://www.nwoods.com/go/Flags/" + nation.toLowerCase().replace(/\s/g, "-") + "-flag.Png";
} function theInfoTextConverter(info) {
var str = "";
if (info.title) str += "Title: " + info.title;
if (info.headOf) str += "\n\nHead of: " + info.headOf;
if (typeof info.boss === "number") {
var bossinfo = myDiagram.model.findNodeDataForKey(info.boss);
if (bossinfo !== null) {
str += "\n\nReporting to: " + bossinfo.name;
}
}
return str;
} // set up the nodeDataArray, describing each person/position
var nodeDataArray = [
{ key: 0, name: "Ban Ki-moon 반기문", nation: "South Korea", title: "Secretary-General of the United Nations", headOf: "Secretariat" },
{ key: 1, boss: 0, name: "Patricia O'Brien", nation: "Ireland", title: "Under-Secretary-General for Legal Affairs and United Nations Legal Counsel", headOf: "Office of Legal Affairs" },
{ key: 3, boss: 1, name: "Peter Taksøe-Jensen", nation: "Denmark", title: "Assistant Secretary-General for Legal Affairs" },
{ key: 9, boss: 3, name: "Other Employees" },
{ key: 4, boss: 1, name: "Maria R. Vicien - Milburn", nation: "Argentina", title: "General Legal Division Director", headOf: "General Legal Division" },
{ key: 10, boss: 4, name: "Other Employees" },
{ key: 5, boss: 1, name: "Václav Mikulka", nation: "Czech Republic", title: "Codification Division Director", headOf: "Codification Division" },
{ key: 11, boss: 5, name: "Other Employees" },
{ key: 6, boss: 1, name: "Sergei Tarassenko", nation: "Russia", title: "Division for Ocean Affairs and the Law of the Sea Director", headOf: "Division for Ocean Affairs and the Law of the Sea" },
{ key: 12, boss: 6, name: "Alexandre Tagore Medeiros de Albuquerque", nation: "Brazil", title: "Chairman of the Commission on the Limits of the Continental Shelf", headOf: "The Commission on the Limits of the Continental Shelf" },
{ key: 17, boss: 12, name: "Peter F. Croker", nation: "Ireland", title: "Chairman of the Committee on Confidentiality", headOf: "The Committee on Confidentiality" },
{ key: 31, boss: 17, name: "Michael Anselme Marc Rosette", nation: "Seychelles", title: "Vice Chairman of the Committee on Confidentiality" },
{ key: 32, boss: 17, name: "Kensaku Tamaki", nation: "Japan", title: "Vice Chairman of the Committee on Confidentiality" },
{ key: 33, boss: 17, name: "Osvaldo Pedro Astiz", nation: "Argentina", title: "Member of the Committee on Confidentiality" },
{ key: 34, boss: 17, name: "Yuri Borisovitch Kazmin", nation: "Russia", title: "Member of the Committee on Confidentiality" },
{ key: 18, boss: 12, name: "Philip Alexander Symonds", nation: "Australia", title: "Chairman of the Committee on provision of scientific and technical advice to coastal States", headOf: "Committee on provision of scientific and technical advice to coastal States"},
{ key: 35, boss: 18, name: "Emmanuel Kalngui", nation: "Cameroon", title: "Vice Chairman of the Committee on provision of scientific and technical advice to coastal States" },
{ key: 36, boss: 18, name: "Sivaramakrishnan Rajan", nation: "India", title: "Vice Chairman of the Committee on provision of scientific and technical advice to coastal States" },
{ key: 37, boss: 18, name: "Francis L. Charles", nation: "Trinidad and Tobago", title: "Member of the Committee on provision of scientific and technical advice to costal States"},
{ key: 38, boss: 18, name: "Mihai Silviu German", nation: "Romania", title: "Member of the Committee on provision of scientific and technical advice to costal States"},
{ key: 19, boss: 12, name: "Lawrence Folajimi Awosika", nation: "Nigeria", title: "Vice Chairman of the Commission on the Limits of the Continental Shelf" },
{ key: 20, boss: 12, name: "Harald Brekke", nation: "Norway", title: "Vice Chairman of the Commission on the Limits of the Continental Shelf" },
{ key: 21, boss: 12, name: "Yong-Ahn Park", nation: "South Korea", title: "Vice Chairman of the Commission on the Limits of the Continental Shelf" },
{ key: 22, boss: 12, name: "Abu Bakar Jaafar", nation: "Malaysia", title: "Chairman of the Editorial Committee", headOf: "Editorial Committee" },
{ key: 23, boss: 12, name: "Galo Carrera Hurtado", nation: "Mexico", title: "Chairman of the Training Committee", headOf: "Training Committee" },
{ key: 24, boss: 12, name: "Indurlall Fagoonee", nation: "Mauritius", title: "Member of the Commission on the Limits of the Continental Shelf" },
{ key: 25, boss: 12, name: "George Jaoshvili", nation: "Georgia", title: "Member of the Commission on the Limits of the Continental Shelf" },
{ key: 26, boss: 12, name: "Wenzhang Lu", nation: "China", title: "Member of the Commission on the Limits of the Continental Shelf" },
{ key: 27, boss: 12, name: "Isaac Owusu Orudo", nation: "Ghana", title: "Member of the Commission on the Limits of the Continental Shelf" },
{ key: 28, boss: 12, name: "Fernando Manuel Maia Pimentel", nation: "Portugal", title: "Member of the Commission on the Limits of the Continental Shelf" },
{ key: 7, boss: 1, name: "Renaud Sorieul", nation: "France", title: "International Trade Law Division Director", headOf: "International Trade Law Division" },
{ key: 13, boss: 7, name: "Other Employees" },
{ key: 8, boss: 1, name: "Annebeth Rosenboom", nation: "Netherlands", title: "Treaty Section Chief", headOf: "Treaty Section" },
{ key: 14, boss: 8, name: "Bradford Smith", nation: "United States", title: "Substantive Legal Issues Head", headOf: "Substantive Legal Issues" },
{ key: 29, boss: 14, name: "Other Employees" },
{ key: 15, boss: 8, name: "Andrei Kolomoets", nation: "Russia", title: "Technical/Legal Issues Head", headOf: "Technical/Legal Issues" },
{ key: 30, boss: 15, name: "Other Employees" },
{ key: 16, boss: 8, name: "Other Employees" },
{ key: 2, boss: 0, name: "Heads of Other Offices/Departments" }
]; // the Search functionality highlights all of the nodes that have at least one data property match a RegExp
function searchDiagram() { // called by button
var input = document.getElementById("mySearch");
if (!input) return;
input.focus(); // create a case insensitive RegExp from what the user typed
var regex = new RegExp(input.value, "i"); myDiagram.startTransaction("highlight search");
myDiagram.clearHighlighteds(); // search four different data properties for the string, any of which may match for success
if (input.value) { // empty string only clears highlighteds collection
var results = myDiagram.findNodesByExample({ name: regex },
{ nation: regex },
{ title: regex },
{ headOf: regex });
myDiagram.highlightCollection(results);
// try to center the diagram at the first node that was found
if (results.count > 0) myDiagram.centerRect(results.first().actualBounds);
} myDiagram.commitTransaction("highlight search");
} // this event handler is called when the diagram is first ready
myDiagram.addDiagramListener("InitialLayoutCompleted", function(e) {
// pick a random node data
//var data = nodeDataArray[Math.floor(Math.random()*nodeDataArray.length)];
var data=nodeDataArray[0];
// find the corresponding Node
var node = myDiagram.findNodeForData(data);
// and center it and select it
myDiagram.centerRect(node.actualBounds);
myDiagram.select(node);
}); //修改节点时触发
myDiagram.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.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) {
// record node insertions and removals
if (e.change === go.ChangedEvent.Property) {
if (e.modelChange === "linkFromKey") {
console.log(evt.propertyName + " changed From key of link: " +
e.object + " from: " + e.oldValue + " to: " + e.newValue);
} else if (e.modelChange === "linkToKey") {
console.log(evt.propertyName + " changed To key of link: " +
e.object + " from: " + e.oldValue + " to: " + e.newValue);
}
} else if (e.change === go.ChangedEvent.Insert && e.modelChange === "linkDataArray") {
console.log(evt.propertyName + " added link: " + e.newValue);
} else if (e.change === go.ChangedEvent.Remove && e.modelChange === "linkDataArray") {
console.log(evt.propertyName + " removed link: " + e.oldValue);
}
});
}); // To simplify this code we define a function for creating a context menu button:
function makeButton(text, action, visiblePredicate) {
return $("ContextMenuButton",
$(go.TextBlock, text),
{ click: action },
// don't bother with binding GraphObject.visible if there's no predicate
visiblePredicate ? new go.Binding("visible", "", visiblePredicate).ofObject() : {});
} var partContextMenu =
$(go.Adornment, "Vertical",
makeButton("Properties",
function(e, obj) { // OBJ is this Button
var contextmenu = obj.part; // the Button is in the context menu Adornment
var part = contextmenu.adornedPart; // the adornedPart is the Part that the context menu adorns
// now can do something with PART, or with its data, or with the Adornment (the context menu)
if (part instanceof go.Link) alert(linkInfo(part.data));
else if (part instanceof go.Group) alert(groupInfo(contextmenu));
else alert(nodeInfo(part.data));
}),
makeButton("Cut",
function(e, obj) { e.diagram.commandHandler.cutSelection(); },
function(o) { return o.diagram.commandHandler.canCutSelection(); }),
makeButton("Copy",
function(e, obj) { e.diagram.commandHandler.copySelection(); },
function(o) { return o.diagram.commandHandler.canCopySelection(); }),
makeButton("Paste",
function(e, obj) { e.diagram.commandHandler.pasteSelection(e.diagram.lastInput.documentPoint); },
function(o) { return o.diagram.commandHandler.canPasteSelection(); }),
makeButton("Delete",
function(e, obj) { e.diagram.commandHandler.deleteSelection(); },
function(o) { return o.diagram.commandHandler.canDeleteSelection(); }),
makeButton("Undo",
function(e, obj) { e.diagram.commandHandler.undo(); },
function(o) { return o.diagram.commandHandler.canUndo(); }),
makeButton("Redo",
function(e, obj) { e.diagram.commandHandler.redo(); },
function(o) { return o.diagram.commandHandler.canRedo(); }),
makeButton("Group",
function(e, obj) { e.diagram.commandHandler.groupSelection(); },
function(o) { return o.diagram.commandHandler.canGroupSelection(); }),
makeButton("Ungroup",
function(e, obj) { e.diagram.commandHandler.ungroupSelection(); },
function(o) { return o.diagram.commandHandler.canUngroupSelection(); })
); function nodeInfo(d) { // Tooltip info for a node data object
var str = "Node " + d.key + ": " + d.text + "\n";
if (d.group)
str += "member of " + d.group;
else
str += "top-level node";
return str;
} // When a Node is selected, highlight the corresponding HTML element.
function nodeSelectionChanged(node) {
if (node.isSelected) {
//names[node.data.name].style.backgroundColor = "lightblue";
// node.style.backgroundColor = "lightblue";
console.log(node.data.name); } else {
//names[node.data.name].style.backgroundColor = "";
}
} function mouseEnter(e, obj) {
obj.isHighlighted = true;
}; function mouseLeave(e, obj) {
obj.isHighlighted = false;
};
//linkData在父亲节点都不存在的情况下会自动创建Node
//{ from: "Center", to: i++, toArrow: arrowheads[j], fromArrow: arrowheads[j + 1] } // a selected node shows an Adornment that includes both a blue border
// and a row of Buttons above the node
myDiagram.nodeTemplate.selectionAdornmentTemplate =
$(go.Adornment, "Spot",
$(go.Panel, "Auto",
$(go.Shape, { stroke: "dodgerblue", strokeWidth: 2, fill: null }),
$(go.Placeholder)
),
$(go.Panel, "Horizontal",
{ alignment: go.Spot.Top, alignmentFocus: go.Spot.Bottom },
$("Button",
{ click: editText }, // defined below, to support editing the text of the node
$(go.TextBlock, "t",
{ font: "bold 10pt sans-serif", desiredSize: new go.Size(15, 15), textAlign: "center" })
),
$("Button",
{ click: changeColor, "_buttonFillOver": "transparent" }, // defined below, to support changing the color of the node
new go.Binding("ButtonBorder.fill", "color", nextColor),
$(go.Shape,
{ fill: null, stroke: null, desiredSize: new go.Size(14, 14) })
),
$("Button",
{ // drawLink is defined below, to support interactively drawing new links
click: drawLink, // click on Button and then click on target node
actionMove: drawLink // drag from Button to the target node
},
$(go.Shape,
{ geometryString: "M0 0 L8 0 8 12 14 12 M12 10 L14 12 12 14" })
),
$("Button",
{
actionMove: dragNewNode, // defined below, to support dragging from the button
_dragData: { text: "a Node", color: "lightgray" }, // node data to copy
click: clickNewNode // defined below, to support a click on the button
},
$(go.Shape,
{ geometryString: "M0 0 L3 0 3 10 6 10 x F1 M6 6 L14 6 14 14 6 14z", fill: "gray" })
)
)
); function editText(e, button) {
var node = button.part.adornedPart;
e.diagram.commandHandler.editTextBlock(node.findObject("TEXTBLOCK"));
} function editText(e, button) {
var node = button.part.adornedPart;
e.diagram.commandHandler.editTextBlock(node.findObject("TEXTBLOCK"));
} // used by nextColor as the list of colors through which we rotate
var myColors = ["lightgray", "lightblue", "lightgreen", "yellow", "orange", "pink"]; // used by both the Button Binding and by the changeColor click function
function nextColor(c) {
var idx = myColors.indexOf(c);
if (idx < 0) return "lightgray";
if (idx >= myColors.length-1) idx = 0;
return myColors[idx+1];
} function changeColor(e, button) {
var node = button.part.adornedPart;
var shape = node.findObject("SHAPE");
if (shape === null) return;
node.diagram.startTransaction("Change color");
shape.fill = nextColor(shape.fill);
button["_buttonFillNormal"] = nextColor(shape.fill); // update the button too
node.diagram.commitTransaction("Change color");
} function drawLink(e, button) {
var node = button.part.adornedPart;
var tool = e.diagram.toolManager.linkingTool;
tool.startObject = node.port;
e.diagram.currentTool = tool;
tool.doActivate();
} // used by both clickNewNode and dragNewNode to create a node and a link
// from a given node to the new node
function createNodeAndLink(data, fromnode) {
var diagram = fromnode.diagram;
var model = diagram.model;
var nodedata = model.copyNodeData(data);
model.addNodeData(nodedata);
var newnode = diagram.findNodeForData(nodedata);
var linkdata = model.copyLinkData({});
model.setFromKeyForLinkData(linkdata, model.getKeyForNodeData(fromnode.data));
model.setToKeyForLinkData(linkdata, model.getKeyForNodeData(newnode.data));
model.addLinkData(linkdata);
diagram.select(newnode);
return newnode;
} // the Button.click event handler, called when the user clicks the "N" button
function clickNewNode(e, button) {
var data = button._dragData;
if (!data) return;
e.diagram.startTransaction("Create Node and Link");
var fromnode = button.part.adornedPart;
var newnode = createNodeAndLink(button._dragData, fromnode);
newnode.location = new go.Point(fromnode.location.x + 200, fromnode.location.y);
e.diagram.commitTransaction("Create Node and Link");
} // the Button.actionMove event handler, called when the user drags within the "N" button
function dragNewNode(e, button) {
var tool = e.diagram.toolManager.draggingTool;
if (tool.isBeyondDragSize()) {
var data = button._dragData;
if (!data) return;
e.diagram.startTransaction("button drag"); // see doDeactivate, below
var newnode = createNodeAndLink(data, button.part.adornedPart);
newnode.location = e.diagram.lastInput.documentPoint;
// don't commitTransaction here, but in tool.doDeactivate, after drag operation finished
// set tool.currentPart to a selected movable Part and then activate the DraggingTool
tool.currentPart = newnode;
e.diagram.currentTool = tool;
tool.doActivate();
}
} // using dragNewNode also requires modifying the standard DraggingTool so that it
// only calls commitTransaction when dragNewNode started a "button drag" transaction;
// do this by overriding DraggingTool.doDeactivate:
var tool = myDiagram.toolManager.draggingTool;
tool.doDeactivate = function() {
// commit "button drag" transaction, if it is ongoing; see dragNewNode, above
if (tool.diagram.undoManager.nestedTransactionNames.elt(0) === "button drag") {
tool.diagram.commitTransaction();
}
go.DraggingTool.prototype.doDeactivate.call(tool); // call the base method
}; myDiagram.model =
$(go.TreeModel,
{ nodeParentKeyProperty: "boss", // this property refers to the parent node data
//nodeParentKeyProperty: "parentKey",
nodeDataArray: nodeDataArray }); //更新数据
// model.updateTargetBindings(data); //循环更新数据
/*
function loop() {
setTimeout(function() { randomProblems(); loop(); }, 2000);
}
loop(); // start the simulation
*/

【12-26】go.js的更多相关文章

  1. 【重温基础】15.JS对象介绍

    从这篇文章开始,复习 MDN 中级教程 的内容了,在初级教程中,我和大家分享了一些比较简单基础的知识点,并放在我的 [Cute-JavaScript]系列文章中. 关于[Cute-JavaScript ...

  2. 【开源专访】Sea.js创始人玉伯的前端开发之路

    摘要:玉伯,淘宝前端类库 KISSY.前端模块化开发框架SeaJS.前端基础类库Arale的创始人.本期[开源专访]我们邀请玉伯来为我们分享一些关于前端框架.前端开发的那些事,以及前端大牛是如何炼成的 ...

  3. 【23.26%】【codeforces 747D】Winter Is Coming

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  4. 【干货分享】Node.js 中文学习资料和教程导航

    这篇文章来自 Github 上的一位开发者收集整理的 Node.js 中文学习资料和教程导航.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念,它的目标是帮助程 ...

  5. 【Python + Selenium】之JS定位总结

    感谢:小琰子 Python+Selenium 脚本中的一些js的用法汇总: 1.滚动条 driver.set_window_size(500,500) js = "window.scroll ...

  6. 【干货分享】Node.js 中文资料导航

    这篇文章与大家分享一批高质量的的 Node.js 中文资料.Node.js 是一个基于 Chrome JavaScript 运行时建立的一个平台, 用来方便地搭建快速的, 易于扩展的网络应用 Node ...

  7. 【功能代码】---5 JS通过事件隐藏显示元素

    JS通过事件隐藏显示元素 在开发中,很多时候我们需要点击事件,才显示隐藏元素.那如何做到页面刚开始就把标签隐藏. 有两种方法: (1) display:none    <div id=" ...

  8. 【功能代码】---3 JS判断字符串是否包含某个字符串

    JS判断字符串是否包含某个字符串 var str ="abc"; if(str.indexOf("bc")>-1){ alert('str中包含bc字符串 ...

  9. 【12.78%】【codeforces 677D】Vanya and Treasure

    time limit per test1.5 seconds memory limit per test256 megabytes inputstandard input outputstandard ...

  10. 【特别推荐】Node.js 入门教程和学习资源汇总

    这篇文章与大家分享一批很有用的 Node.js 入门教程和学习资源.Node 是一个服务器端的 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用 ...

随机推荐

  1. Python导入其他文件中的.py文件 即模块

    import sys sys.path.append("路径") import .py文件

  2. Java 数组打印数组的 五种方法

    Arrays.toString(arr) for(int n: arr) System.out.println(n+", "); for (int i = 0; i < ar ...

  3. sqlserver中根据表中的配置概率取到数据

      create proc pr_zhanglei_test1 /*功能描述: 根据t_zhanglei_test1中perc设置的概率,取到相应数据old_id */ as declare @per ...

  4. rsync同步架构

    1.1 rsync服务器端配置 1.1.1 查看服务器端rsync版本 1.1.2 创建配置文件 默认安装好rsync程序后,并不会自动创建rsync的主配置文件,需要手工来创建,其主配置文件为“/e ...

  5. 迭代字典中的key和value

    字典是python中十分重要的一个内容. 今天我们来谈谈,在一个 for 循环中,能否同时迭代 key和value?当然可以咯. dict 对象的 items() 方法返回的值: >>&g ...

  6. Ubuntu在wps-office等qt5程序下不能切换中文fcitx输入法的问题

    经检查,是缺了fcitx-qt的包.比如qt5的程序,需要一个叫fcitx-libs-qt5的包. 如果您在基于qt的程序下不能使用基于fcitx的中文输入法,请检查以下包是否已安装: sudo ap ...

  7. hdu1032 Train Problem II (卡特兰数)

    题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能.    (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...

  8. Lua的协程和协程库详解

    我们首先介绍一下什么是协程.然后详细介绍一下coroutine库,然后介绍一下协程的简单用法,最后介绍一下协程的复杂用法. 一.协程是什么? (1)线程 首先复习一下多线程.我们都知道线程——Thre ...

  9. C# 动态修改Config

    Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); confi ...

  10. 延迟加载外部js文件,延迟加载图片(jquery.lazyload.js和echo,js)

    js里一说到延迟加载,大都离不开两种情形,即外部Js文件的延迟加载,以及网页图片的延迟加载: 1.首先简单说一下js文件的3种延迟加载方式: (1)<script type="text ...