Basic Application [Browser]

In this example the decision tree processing functions and the root shape have been removed from the page and been placed within separate files.

There is a decision shape that calls itself until the value data.a > 10 at which point it terminates and calls the complete function.

Download »

Setup

This browser example splits the code into separate files.

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

Log Function

We are overwritting the app.js log function within the page so we can write the logs to the results layer in the test page.


        //add a log function to show on screen
        TestApp.log = function (msg) {
            document.getElementById("results").innerHTML += msg + "
"; }

Object to Process

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 };

Root Shape

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 = {
    "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"
    }
};
                    

Run Test

The runTest() function calls the decisionTree.execute function passing in the root shape, the data object to process and sets a callback function to be called on complete.


        function runTest() {
            //execute the tree on the root shape
            decisionTree.execute(shape, data, TestApp.complete);
        }

    <script src="decisiontree.min.js"></script>
    <script src="app.js"></script>
    <script src="json.js"></script>
    <script type="text/javascript">        

        //add a log function to show on screen
        TestApp.log = function (msg) {
            document.getElementById("results").innerHTML += msg + "
"; } //create a data object to process var data = { "a": 1 }; function runTest() { //execute the tree on the root shape decisionTree.execute(shape, data, TestApp.complete); } </script> <input type="button" class="btn btn-primary" onclick="runTest();" value="Run Test" /> <h2>Results</h2> <div id="results"></div>
var TestApp;
(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.complete = complete;
})(TestApp || (TestApp = {}));

                    
                
var 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"
    }
};
                    
                

You haven't run the test yet!