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. Filter过滤器的写法

    http://pengenjing.iteye.com/blog/1607248 这里写的过滤器用的是适配器模式,思路为: 先写一个类实现Filter,然后在让你写的过滤器来继承自这个类: 步骤:1. ...

  2. 基于日志数据分析以防御CC攻击的想法

    1. What - 什么是CC攻击 CC攻击,即针对应用层HTTP协议的DDos攻击,攻击者在短时间内向目标服务器发送大量的HTTP请求,使得服务器会非常繁忙,资源消耗会增加:同时,如果请求中包含基于 ...

  3. visual studio 查找/替换对话框

    工具--选项--环境--查找和替换 如下设置: 则会在查找.替换到最后时会弹出提示,比如“查找到达了搜索的起点”,如下图: 原文:http://keleyi.com/a/bjac/27iswh0p.h ...

  4. 【HTML5】Server-Sent服务器发送事件

    Server-Sent 事件 - 单向消息传递 Server-Sent 事件指的是网页自动获取来自服务器的更新. 以前也可能做到这一点,前提是网页不得不询问是否有可用的更新.通过服务器发送事件,更新能 ...

  5. [Silverlight] Visual Studio2010不能安装Silverlight4_Tools,提示语言不一致

    今天在装Silverlight4_Tools时出现“必须先安装与 Silverlight Tools 4 语言版本相一致的 Visual Studio 2010.Visual Web Develope ...

  6. makefile中使用变量

    makefile里的变量就像一个变量,变量的作用主要如下: (1)保存文件名列表. (2)保存编译器的参数. makefile中的变量是用一个字符串在makefile中定义的,这个文本串就是变量的值. ...

  7. iOS 之NSJSONReadingOptions说明【转】

    首先用代码来说明NSJSONReadingMutableContainers的作用: NSString *str = @"{\"name\":\"kaixuan ...

  8. 数据分析系统DIY3/3:本地64位WIN7+matlab 2012b訪问VMware CentOS7+MariaDB

    数据分析系统DIY中要完毕的三个任务. 一.用VMware装64位CentOS.数据库服务端用CentOS自带的就好. 二.数据採集与预处理用Dev-C++编程解决. 三.用本地Win7 64上的MA ...

  9. poj2352树状数组

    Astronomers often examine star maps where stars are represented by points on a plane and each star h ...

  10. PGM:贝叶斯网表示之朴素贝叶斯模型naive Bayes

    http://blog.csdn.net/pipisorry/article/details/52469064 独立性质的利用 条件参数化和条件独立性假设被结合在一起,目的是对高维概率分布产生非常紧凑 ...