I have been trying to use the grafcet example but using angularJS.
In the html I have:
<go-diagram4 id="myDiagramDiv4" go-model4="model4" style="border: solid 1px black; height: 600px"></go-diagram4>
I have a directive in angular:
app.directive('goDiagram4', function($rootScope) {
return {
restrict: 'E',
template: '<div></div>', // just an empty DIV element
replace: true,
scope: { model: '=goModel4' },
link: function(scope, element, attrs) {
var $ = go.GraphObject.make;
var commandsAdornment =
$(go.Adornment, "Vertical",
$(go.Panel, "Auto",
$(go.Shape, { fill: null, stroke: "deepskyblue", strokeWidth: 2 }),
$(go.Placeholder)
),
$(go.Panel, "Horizontal",
{ defaultStretch: go.GraphObject.Vertical },
$("Button",
$(go.Shape,
{ geometryString: "M0 0 L10 0",
fill: null, stroke: "red", margin: 3 }),
{ click: addExclusive, toolTip: makeTooltip("Add Exclusive") },
new go.Binding("visible", "", canAddSplit).ofObject()),
$("Button",
$(go.Shape,
{ geometryString: "M0 0 L10 0 M0 3 10 3",
fill: null, stroke: "red", margin: 3 }),
{ click: addParallel, toolTip: makeTooltip("Add Parallel") },
new go.Binding("visible", "", canAddSplit).ofObject()),
$("Button",
$(go.Shape,
{ geometryString: "M0 0 L10 0 10 6 0 6z",
fill: "lightyellow", margin: 3 }),
{ click: addStep, toolTip: makeTooltip("Add Step") },
new go.Binding("visible", "", canAddStep).ofObject()),
$("Button",
$(go.Shape,
{ geometryString: "M0 0 M5 0 L5 10 M3 8 5 10 7 8 M10 0",
fill: null, margin: 3 }),
{ click: startLinkDown, toolTip: makeTooltip("Draw Link Down") },
new go.Binding("visible", "", canStartLink).ofObject()),
$("Button",
$(go.Shape,
{ geometryString: "M0 0 M3 0 L3 2 7 2 7 6 3 6 3 10 M1 8 3 10 5 8 M10 0",
fill: null, margin: 3 }),
{ click: startLinkAround, toolTip: makeTooltip("Draw Link Skip") },
new go.Binding("visible", "", canStartLink).ofObject()),
$("Button",
$(go.Shape,
{ geometryString: "M0 0 M3 2 L3 0 7 0 7 10 3 10 3 8 M5 6 7 4 9 6 M10 0",
fill: null, margin: 3 }),
{ click: startLinkUp, toolTip: makeTooltip("Draw Link Repeat") },
new go.Binding("visible", "", canStartLink).ofObject())
)
);
var resizeAdornment =
$(go.Adornment, go.Panel.Spot,
$(go.Placeholder),
$(go.Shape, // left resize handle
{ alignment: go.Spot.Left, cursor: "col-resize",
desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "dodgerblue" }),
$(go.Shape, // right resize handle
{ alignment: go.Spot.Right, cursor: "col-resize",
desiredSize: new go.Size(6, 6), fill: "lightblue", stroke: "dodgerblue" })
);
var myDiagram =
$(go.Diagram, "myDiagramDiv4",
{
allowLink: false, // linking is only started via buttons, not modelessly;
// see the "startLink..." functions and CustomLinkingTool defined below
initialContentAlignment: go.Spot.Center,
// double-click in the background creates a new "Start" node
"clickCreatingTool.archetypeNodeData": { category: "Start", step: 1, text: "Action" },
linkingTool: new CustomLinkingTool(), // defined below to automatically turn on allowLink
"undoManager.isEnabled": true
});
// when the document is modified, add a "*" to the title and enable the "Save" button
myDiagram.addDiagramListener("Modified", function(e) {
var button = document.getElementById("saveModel");
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);
}
});
// This implements a selection Adornment that is a horizontal bar of command buttons
// that appear when the user selects a node.
// Each button has a click function to execute the command, a tooltip for a textual description,
// and a Binding of "visible" to hide the button if it cannot be executed for that particular node.
function makeTooltip(str) { // a helper function for defining tooltips for buttons
return $(go.Adornment, go.Panel.Auto,
$(go.Shape, { fill: "#FFFFCC" }),
$(go.TextBlock, str, { margin: 4 }));
}
// Commands for adding new Nodes
function addStep(e, obj) {
var node = obj.part.adornedPart;
var model = myDiagram.model;
model.startTransaction("add Step");
var loc = node.location.copy();
loc.y += 50;
var nodedata = { location: go.Point.stringify(loc) };
model.addNodeData(nodedata);
var nodekey = model.getKeyForNodeData(nodedata);
var linkdata = { from: model.getKeyForNodeData(node.data), to: nodekey, text: "c" };
model.addLinkData(linkdata);
var newnode = myDiagram.findNodeForData(nodedata);
myDiagram.select(newnode);
model.commitTransaction("add Step");
}
function canAddStep(adorn) {
var node = adorn.adornedPart;
if (node.category === "" || node.category === "Start") {
return node.findLinksOutOf().count === 0;
} else if (node.category === "Parallel" || node.category === "Exclusive") {
return true;
}
return false;
}
function addParallel(e, obj) { addSplit(obj.part.adornedPart, "Parallel"); }
function addExclusive(e, obj) { addSplit(obj.part.adornedPart, "Exclusive"); }
function addSplit(node, type) {
var model = myDiagram.model;
model.startTransaction("add " + type);
var loc = node.location.copy();
loc.y += 50;
var nodedata = { category: type, location: go.Point.stringify(loc) };
model.addNodeData(nodedata);
var nodekey = model.getKeyForNodeData(nodedata);
var linkdata = { from: model.getKeyForNodeData(node.data), to: nodekey };
model.addLinkData(linkdata);
var newnode = myDiagram.findNodeForData(nodedata);
myDiagram.select(newnode);
model.commitTransaction("add " + type);
}
function canAddSplit(adorn) {
var node = adorn.adornedPart;
if (node.category === "" || node.category === "Start") {
return node.findLinksOutOf().count === 0;
} else if (node.category === "Parallel" || node.category === "Exclusive") {
return false;
}
return false;
}
// Commands for starting drawing new Links
function startLinkDown(e, obj) { startLink(obj.part.adornedPart, "", "c"); }
function startLinkAround(e, obj) { startLink(obj.part.adornedPart, "Skip", "s"); }
function startLinkUp(e, obj) { startLink(obj.part.adornedPart, "Repeat", "r"); }
function startLink(node, category, condition) {
var tool = myDiagram.toolManager.linkingTool;
// to control what kind of Link is created,
// change the LinkingTool.archetypeLinkData's category
myDiagram.model.setCategoryForLinkData(tool.archetypeLinkData, category);
// also change the text indicating the condition, which the user can edit
tool.archetypeLinkData.text = condition;
tool.startObject = node.port;
myDiagram.currentTool = tool;
tool.doActivate();
}
function canStartLink(adorn) {
var node = adorn.adornedPart;
return true; // this could be smarter
}
// The various kinds of Nodes
// a helper function that declares common properties for all kinds of nodes
function commonNodeStyle() {
return [
{
locationSpot: go.Spot.Center,
selectionAdornmentTemplate: commandsAdornment // shared selection Adornment
},
new go.Binding("location", "location", go.Point.parse).makeTwoWay(go.Point.stringify),
];
}
myDiagram.nodeTemplateMap.add("Start",
$(go.Node, "Horizontal", commonNodeStyle(),
{ locationObjectName: "STEPPANEL", selectionObjectName: "STEPPANEL" },
$(go.Panel, "Auto",
{ // this is the port element, not the whole Node
name: "STEPPANEL", portId: "",
fromSpot: go.Spot.Bottom, fromLinkable: true
},
$(go.Shape, { fill: "lightgreen" }),
$(go.Panel, "Auto",
{ margin: 3 },
$(go.Shape, { fill: null, minSize: new go.Size(20, 20) }),
$(go.TextBlock, "Start",
{ margin: 3, editable: true },
new go.Binding("text", "step").makeTwoWay())
)
)/*,
// a connector line between the texts
$(go.Shape, "LineH", { width: 10, height: 1 }),
// the boxed, editable text on the side
$(go.Panel, "Auto",
$(go.Shape, { fill: "white" }),
$(go.TextBlock, "Action",
{ margin: 3, editable: true },
new go.Binding("text", "text").makeTwoWay())
)*/
));
myDiagram.nodeTemplateMap.add("",
$(go.Node, "Horizontal", commonNodeStyle(),
{ locationObjectName: "STEPPANEL", selectionObjectName: "STEPPANEL" },
$(go.Panel, "Auto",
{ // this is the port element, not the whole Node
name: "STEPPANEL", portId: "",
fromSpot: go.Spot.Bottom, fromLinkable: true,
toSpot: go.Spot.Top, toLinkable: true
},
$(go.Shape, { name: "mikel", fill: $rootScope.selected.color, minSize: new go.Size(20, 20) }),
$(go.TextBlock, "Step",
{ margin: 3, editable: true },
new go.Binding("text", "step").makeTwoWay())
)/*,
$(go.Shape, "LineH", { width: 10, height: 1 }),
$(go.Panel, "Auto",
$(go.Shape, { fill: "white" }),
$(go.TextBlock, "Action",
{ margin: 3, editable: true },
new go.Binding("text", "text").makeTwoWay())
)*/
));
myDiagram.nodeTemplateMap.add("Parallel",
$(go.Node, commonNodeStyle(),
{ // special resizing: just at the ends
resizable: true, resizeObjectName: "SHAPE", resizeAdornmentTemplate: resizeAdornment,
fromLinkable: true, toLinkable: true
},
$(go.Shape,
{ // horizontal pair of lines stretched to an initial width of 200
name: "SHAPE", geometryString: "M0 0 L100 0 M0 4 L100 4",
fill: "transparent", stroke: "red", width: 200
},
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify))
));
myDiagram.nodeTemplateMap.add("Exclusive",
$(go.Node, commonNodeStyle(),
{ // special resizing: just at the ends
resizable: true, resizeObjectName: "SHAPE", resizeAdornmentTemplate: resizeAdornment,
fromLinkable: true, toLinkable: true
},
$(go.Shape,
{ // horizontal line stretched to an initial width of 200
name: "SHAPE", geometryString: "M0 0 L100 0",
fill: "transparent", stroke: "red", width: 200
},
new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify))
));
// the various kinds of Links
console.log(angular.toJson(BarLink));
myDiagram.linkTemplateMap.add("",
$(BarLink, // subclass defined below
{ routing: go.Link.Orthogonal },
$(go.Shape,
{ strokeWidth: 1.5 }),
$(go.Shape, "LineH", // only visible when there is text
{ width: 20, height: 1, visible: false },
new go.Binding("visible", "text", function(t) { return t !== ""; })),
$(go.TextBlock, // only visible when there is text
{ alignmentFocus: new go.Spot(0, 0.5, -12, 0), editable: true },
new go.Binding("text", "text").makeTwoWay(),
new go.Binding("visible", "text", function(t) { return t !== ""; }))
));
myDiagram.linkTemplateMap.add("Skip",
$(go.Link,
{
routing: go.Link.AvoidsNodes,
fromSpot: go.Spot.Bottom, toSpot: go.Spot.Top,
fromEndSegmentLength: 4, toEndSegmentLength: 4
},
$(go.Shape,
{ strokeWidth: 1.5 }),
$(go.Shape, "LineH", // only visible when there is text
{ width: 20, height: 1, visible: false },
new go.Binding("visible", "text", function(t) { return t !== ""; })),
$(go.TextBlock, // only visible when there is text
{ alignmentFocus: new go.Spot(1, 0.5, 12, 0), editable: true },
new go.Binding("text", "text").makeTwoWay(),
new go.Binding("visible", "text", function(t) { return t !== ""; }))
));
myDiagram.linkTemplateMap.add("Repeat",
$(go.Link,
{
routing: go.Link.AvoidsNodes,
fromSpot: go.Spot.Bottom, toSpot: go.Spot.Top,
fromEndSegmentLength: 4, toEndSegmentLength: 4
},
$(go.Shape,
{ strokeWidth: 1.5 }),
$(go.Shape,
{ toArrow: "OpenTriangle", segmentIndex: 3, segmentFraction: 0.75 }),
$(go.Shape,
{ toArrow: "OpenTriangle", segmentIndex: 3, segmentFraction: 0.25 }),
$(go.Shape, "LineH", // only visible when there is text
{ width: 20, height: 1, visible: false },
new go.Binding("visible", "text", function(t) { return t !== ""; })),
$(go.TextBlock, // only visible when there is text
{ alignmentFocus: new go.Spot(1, 0.5, 12, 0), editable: true },
new go.Binding("text", "text").makeTwoWay(),
new go.Binding("visible", "text", function(t) { return t !== ""; }))
));
// notice when the value of "model" changes: update the Diagram.model
scope.$watch("model", function(newmodel) {
var oldmodel = myDiagram.model;
if (oldmodel !== newmodel) {
myDiagram.removeDiagramListener("ChangedSelection", updateSelection);
myDiagram.model = newmodel;
myDiagram.addDiagramListener("ChangedSelection", updateSelection);
}
});
scope.$watch("model.selectedNodeData.name", function(newname) {
if (!myDiagram.model.selectedNodeData) return;
// disable recursive updates
myDiagram.removeModelChangedListener(updateAngular);
// change the name
myDiagram.startTransaction("change name");
// the data property has already been modified, so setDataProperty would have no effect
var node = myDiagram.findNodeForData(myDiagram.model.selectedNodeData);
if (node !== null) node.updateTargetBindings("name");
myDiagram.commitTransaction("change name");
// re-enable normal updates
myDiagram.addModelChangedListener(updateAngular);
});
var node = {};
myDiagram.addDiagramListener("ObjectSingleClicked",
function(e) {
var part = e.subject.part;
if (!(part instanceof go.Link))
{
var key = part.data.key;
var name = part.data.text;
var category = part.data.category;
console.log("Clicked on " + angular.toJson(part.data));
node = part.data;
$rootScope.recipe_node=node;
$rootScope.$emit('changed_recipe_node', node);
}
});
// update the model when the selection changes
function updateSelection(e) {
var selnode = myDiagram.selection.first();
myDiagram.model.selectedNodeData = (selnode instanceof go.Node ? selnode.data : null);
scope.$apply();
}
myDiagram.addDiagramListener("ChangedSelection", updateSelection);
// initialize Overview
/*var myOverview =
$(go.Overview, "myOverviewDiv",
{
observed: myDiagram,
contentAlignment: go.Spot.Center
});*/
//myDiagram.model = go.Model.fromJson(document.getElementById("mySavedModel").value);
// This custom LinkingTool just turns on Diagram.allowLink when it starts,
// and turns it off again when it stops so that users cannot draw new links modelessly.
function CustomLinkingTool() {
go.LinkingTool.call(this);
}
go.Diagram.inherit(CustomLinkingTool, go.LinkingTool);
// user-drawn linking is normally disabled,
// but needs to be turned on when using this tool
/** @override */
CustomLinkingTool.prototype.doStart = function() {
this.diagram.allowLink = true;
go.LinkingTool.prototype.doStart.call(this);
};
/** @override */
CustomLinkingTool.prototype.doStop = function() {
go.LinkingTool.prototype.doStop.call(this);
this.diagram.allowLink = false;
};
// end CustomLinkingTool
// This custom Link class is smart about computing the link point and direction
// at "Parallel" and "Exclusive" nodes.
function BarLink() {
go.Link.call(this);
}
go.Diagram.inherit(BarLink, go.Link);
/** @override */
BarLink.prototype.getLinkPoint = function(node, port, spot, from, ortho, othernode, otherport) {
var r = new go.Rect(port.getDocumentPoint(go.Spot.TopLeft),
port.getDocumentPoint(go.Spot.BottomRight));
var op = otherport.getDocumentPoint(go.Spot.Center);
var below = op.y > r.centerY;
var y = below ? r.bottom : r.top;
if (node.category === "Parallel" || node.category === "Exclusive") {
if (op.x < r.left) return new go.Point(r.left, y);
if (op.x > r.right) return new go.Point(r.right, y);
return new go.Point(op.x, y);
} else {
return new go.Point(r.centerX, y);
}
};
/** @override */
BarLink.prototype.getLinkDirection = function(node, port, linkpoint, spot, from, ortho, othernode, otherport) {
var p = port.getDocumentPoint(go.Spot.Center);
var op = otherport.getDocumentPoint(go.Spot.Center);
var below = op.y > p.y;
return below ? 90 : 270;
};
}
};
})
Then I inject the model like this:
$scope.diagram={nodeDataArray:[
{"key":1, "category":"Start", "location":"300 50", "step":"", "text":"Action 1"},
{"key":2, "category":"Parallel", "location":"300 100"},
{"key":3, "location":"225 125", "step":"Action 3", "text":"Action 2", fill: "red", figure: "Rectangle"},
{"key":4, "location":"325 150", "step":"Action 4", "text":"Action 3"},
{"key":5, "location":"225 175", "step":"Action 5", "text":"Action 4"},
{"key":6, "category":"Parallel", "location":"300 200"},
{"key":7, "location":"300 250", "step":"Action 7", "text":"Action 6"}
],linkDataArray:[
{"from":1, "to":2, "text":"condition 1"},
{"from":2, "to":3},
{"from":2, "to":4},
{"from":3, "to":5, "text":"condition 2"},
{"from":4, "to":6},
{"from":5, "to":6},
{"from":6, "to":7, "text":"condition 5"}
]
};
$scope.model4 = new go.GraphLinksModel($scope.diagram.nodeDataArray,$scope.diagram.linkDataArray);
I am having to errors in my code:
- Error: Trying to set undefined property “routing” on object: [object Object]
- BarLink is undefined
What could I do to solve these errors?