This example is the same as the Browser Basic Application example except run through a node server.
There is a decision shape that calls itself until the value data.a > 10
at which point it terminates and calls the complete function.
App.js contains all the functions that the decision tree will use to manipulate the object
Json.js contains a JSON object for the root shape
To run it download the code, open a console and type node server.js
We create a new object to process. This object is passed to the decision tree and is altered by the functions in the tree.
Any functions processing the object should be aware of it's structure or handle incorrect objects by throwing an error.
//create a data object to process
var data = { "a": 1 };
Every decision tree requires a root shape to start processing at. This example has it stored in the json.js file.
The process and decision functions in the shape are set using processName and decideName and are referencing functions in the TestApp e.g. "processName": "TestApp.add"
and "decideName": "TestApp.checkValue"
var shape = exports.shape = {
"shapeType": "Entry",
"id": 1,
"description": "Start",
"nextShape": {
"shapeType": "Operation",
"id": 2,
"description": "Adding value 2",
"nextShape": {
"shapeType": "Decision",
"id": 3,
"description": "Adding value 2",
"paths": [{
"value": true,
"selected": false,
"nextShape": null,
"nextShapeId": 3
},
{
"value": false,
"selected": false,
"nextShape":
{
"shapeType": "Operation",
"id": 5,
"description": "Adding nothing",
"nextShape": null,
"properties": { "value": 0 },
"processName": "TestApp.add"
},
"nextShapeId": 0
}],
"properties": { "value": 2, "decision": 10 },
"processName": "TestApp.add",
"nextShape": null,
"decideName": "TestApp.checkValue"
},
"properties": { "value": 2 },
"processName": "TestApp.add"
}
};
The TestApp is added to the decisionTree.execute
function along with the standed options of the root shape, the data object to process and sets a callback function to be called on complete.
For more information on sending apps to the execute function check out the documentation
//execute the tree on the root shape
decisionTree.execute(tree.shape, data, TestApp.complete, { "TestApp": TestApp });
var TestApp = require("./app.js");
var tree = require("./json.js");
var decisionTree = require("./decisionTree.min.js");
//create a data object to process
var data = { "a": 1 };
//execute the tree on the root shape
decisionTree.execute(tree.shape, data, TestApp.complete, { "TestApp": TestApp });
var TestApp = exports;
(function (TestApp) {
//logs messages to the console
TestApp.log = function (message) {
console.log(message);
};
//add function
function add(data, shape, callback) {
try {
TestApp.log("*************");
TestApp.log("add function called");
TestApp.log("data.a=" + data.a);
var v = Number(shape.properties.value);
if(isNaN(v)) {
throw new Error("'" + v + "' is not a number");
}
TestApp.log("adding: " + v);
data.a += v;
TestApp.log("data.a=" + data.a);
callback(null, shape);
} catch (e) {
callback(e, shape);
}
}
TestApp.add = add;
//check value function
function checkValue(data, shape, callback) {
try {
TestApp.log("*************");
TestApp.log("checkValue function called");
TestApp.log("checking data.a (" + data.a + ") is less than shape.properties.decision (" + shape.properties.decision + ")");
if(data.a < shape.properties.decision) {
TestApp.log("data.a < shape.properties.decision selecting path[0]");
shape.paths[0].selected = true;
shape.paths[1].selected = false;
} else {
TestApp.log("data.a >= shape.properties.decision selecting path[1]");
shape.paths[0].selected = false;
shape.paths[1].selected = true;
}
callback(null, shape);
} catch (e) {
callback(e, shape);
}
}
TestApp.checkValue = checkValue;
//complete function
function complete(err, result, processedShapes) {
TestApp.log("*************");
TestApp.log("complete function called");
TestApp.log("error: " + err);
TestApp.log("result: " + result.a);
for(var x = 0; x < processedShapes.length; x++) {
TestApp.log("processed Shape: " + processedShapes[x].description + " id:" + processedShapes[x].id);
}
TestApp.log("Processed shapes JSON");
//TestApp.log(JSON.stringify(processedShapes));
}
TestApp.complete = complete;
})(TestApp || (TestApp = {}));
var shape = exports.shape = {
"shapeType": "Entry",
"id": 1,
"description": "Start",
"nextShape": {
"shapeType": "Operation",
"id": 2,
"description": "Adding value 2",
"nextShape": {
"shapeType": "Decision",
"id": 3,
"description": "Adding value 2",
"paths": [{
"value": true,
"selected": false,
"nextShape": null,
"nextShapeId": 3
},
{
"value": false,
"selected": false,
"nextShape":
{
"shapeType": "Operation",
"id": 5,
"description": "Adding nothing",
"nextShape": null,
"properties": { "value": 0 },
"processName": "TestApp.add"
},
"nextShapeId": 0
}],
"properties": { "value": 2, "decision": 10 },
"processName": "TestApp.add",
"nextShape": null,
"decideName": "TestApp.checkValue"
},
"properties": { "value": 2 },
"processName": "TestApp.add"
}
};