markgojs
Version:
Interactive diagrams, charts, and graphs, such as trees, flowcharts, orgcharts, UML, BPMN, or business diagrams
166 lines (158 loc) • 7.47 kB
HTML
<html ng-app="minimal">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Minimal GoJS Sample with AngularJS</title>
<meta name="description" content="Interactive diagram implemented by GoJS using AngularJS, including a diagram directive and model binding." />
<!-- Copyright 1998-2019 by Northwoods Software Corporation. -->
<meta charset="UTF-8">
<script src="../release/go.js"></script>
<script src="../assets/js/goSamples.js"></script> <!-- this is only for the GoJS Samples framework -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.2/angular.min.js"></script>
<script id="code">
angular.module('minimal', [])
.directive('goDiagram', function() {
return {
restrict: 'E',
template: '<div></div>', // just an empty DIV element
replace: true,
scope: { model: '=goModel' },
link: function(scope, element, attrs) {
if (window.goSamples) goSamples(); // init for these samples -- you don't need to call this
var $ = go.GraphObject.make;
var diagram = // create a Diagram for the given HTML DIV element
$(go.Diagram, element[0],
{
nodeTemplate: $(go.Node, "Auto",
new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
$(go.Shape, "RoundedRectangle", new go.Binding("fill", "color"),
{
portId: "", cursor: "pointer", strokeWidth: 0,
fromLinkable: true, toLinkable: true,
fromLinkableSelfNode: true, toLinkableSelfNode: true,
fromLinkableDuplicates: true, toLinkableDuplicates: true
}),
$(go.TextBlock, { margin: 8, editable: true },
new go.Binding("text", "name").makeTwoWay())
),
linkTemplate: $(go.Link,
{ relinkableFrom: true, relinkableTo: true },
$(go.Shape),
$(go.Shape, { toArrow: "Standard", stroke: null, strokeWidth: 0 })
),
initialContentAlignment: go.Spot.Center,
"ModelChanged": updateAngular,
"ChangedSelection": updateSelection,
"undoManager.isEnabled": true
});
// whenever a GoJS transaction has finished modifying the model, update all Angular bindings
function updateAngular(e) {
if (e.isTransactionFinished) {
scope.$apply();
}
}
// update the Angular model when the Diagram.selection changes
function updateSelection(e) {
diagram.model.selectedNodeData = null;
var it = diagram.selection.iterator;
while (it.next()) {
var selnode = it.value;
// ignore a selected link or a deleted node
if (selnode instanceof go.Node && selnode.data !== null) {
diagram.model.selectedNodeData = selnode.data;
break;
}
}
scope.$apply();
}
// notice when the value of "model" changes: update the Diagram.model
scope.$watch("model", function(newmodel) {
var oldmodel = diagram.model;
if (oldmodel !== newmodel) {
diagram.removeDiagramListener("ChangedSelection", updateSelection);
diagram.model = newmodel;
diagram.addDiagramListener("ChangedSelection", updateSelection);
}
});
scope.$watch("model.selectedNodeData.name", function(newname) {
if (!diagram.model.selectedNodeData) return;
// disable recursive updates
diagram.removeModelChangedListener(updateAngular);
// change the name
diagram.startTransaction("change name");
// the data property has already been modified, so setDataProperty would have no effect
var node = diagram.findNodeForData(diagram.model.selectedNodeData);
if (node !== null) node.updateTargetBindings("name");
diagram.commitTransaction("change name");
// re-enable normal updates
diagram.addModelChangedListener(updateAngular);
});
}
};
})
.controller('MinimalCtrl', function($scope) {
$scope.model = new go.GraphLinksModel(
[
{ key: 1, name: "Alpha", color: "lightblue" },
{ key: 2, name: "Beta", color: "orange" },
{ key: 3, name: "Gamma", color: "lightgreen" },
{ key: 4, name: "Delta", color: "pink" }
],
[
{ from: 1, to: 2 },
{ from: 1, to: 3 },
{ from: 2, to: 2 },
{ from: 3, to: 4 },
{ from: 4, to: 1 }
]);
$scope.model.selectedNodeData = null;
$scope.replaceModel = function() {
$scope.model = new go.GraphLinksModel(
[
{ key: 11, name: "zeta", color: "red" },
{ key: 12, name: "eta", color: "green" }
],
[
{ from: 11, to: 12 }
]
);
}
});
</script>
</head>
<body ng-controller="MinimalCtrl"> <!-- only needed for the goSamples framework -->
<div id="sample">
<!-- a go-diagram element referring to the model, originally written as: -->
<!-- <go-diagram go-model="model" style="border: solid 1px blue; width:100%; height:400px"></go-diagram> -->
<go-diagram go-model="model" style="border: solid 1px black; width:100%; height:400px"></go-diagram>
Number of node data: {{model.nodeDataArray.length}}
<br />
Alpha node location: {{model.findNodeDataForKey(1).loc}}
<br />
Selected node: {{model.selectedNodeData.key}} <input type="text" ng-model="model.selectedNodeData.name"></input>
<br />
Number of link data: {{model.linkDataArray.length}}
<p class="box bg-info">
This is an AngularJS v1 sample. For a minimal Angular v4+ project, see the <code>../projects/angular-basic/</code> subdirectory.
</p>
<p>
This defines an <a href="https://angularjs.org/">AngularJS</a> directive for creating a <b>GoJS</b> <a>Diagram</a> with certain properties.
It also sets up a controller holding a <a>GraphLinksModel</a> that is passed
to the <b>go-diagram</b> element via the <b>go-model</b> attribute.
</p>
<p>
Note that the above bindings are updated automatically as the user moves the "Alpha" node,
copies or deletes Parts in the Diagram, reconnects the Link from "Alpha" to "Beta", or performs an undo or redo.
</p>
<p>
You can also replace the <a>Diagram.model</a> just by setting the "model" property on the $scope,
since the "goDiagram" directive watches that property for changes.
</p>
<button ng-click="replaceModel()">Replace Model</button>
<p>
Please note that the source code shown here for the HTML shows the expanded DIV element produced by AngularJS and other modified elements,
not <code><go-diagram go-model="model" style=...></go-diagram></code> and { { } } bindings as originally written.
</p>
</div>
</body>
</html>