How To Develop a Flowchart Maker with Org Chart JS - BALKAN Blog

How To Develop a Flowchart Maker with Org Chart JS

This is step by step tutorial on how to develop Flowchart Maker using Org Chart JS.

Step 1 - Installation

If you are already familiar with BALKAN OrgChartJS you can skip this step. There are two installation options: standalone or using npm

standalone installation See our getting started page

npm installation

npm i @balkangraph/orgchart.js

Step 2 - Create BALKAN OrgChartJS instance

var chart = new OrgChart(document.getElementById("tree"), {
    align: OrgChart.align.orientation, // use this option to start from the top
    nodeBinding: {
        field_0: "name" // bind the node text
    },
});

chart.load([{"id":1,"name":"start","tags":["start"]}]) // load the start of the chart

Step 3 - Add your templates for the flowchart elements

OrgChart.templates.start = Object.assign({}, OrgChart.templates.ana);
OrgChart.templates.start.defs = '<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="8" markerHeight="8" orient="auto-start-reverse"><path fill="#7e7e7e" d="M 0 0 L 10 5 L 0 10 z" /></marker>';
OrgChart.templates.start.size = [200, 70];
OrgChart.templates.start.node = '<rect x="0" y="0" height="{h}" width="{w}" fill="#415a5f" rx="40" ry="40"></rect>';
OrgChart.templates.start.field_0 = '<text data-width="200" style="font-size: 20px;" fill="#ffffff" x="100" y="40" text-anchor="middle">{val}</text>';
OrgChart.templates.start.link = '<path marker-start="url(#dotBlue)" marker-end="url(#arrow)"   stroke-linejoin="round" stroke="#7e7e7e" stroke-width="3px" fill="none" d="M{xa},{ya} {xb},{yb} {xc},{yc} L{xd},{yd}" />';
OrgChart.templates.start.link_field_0 = '<text text-anchor="middle" fill="#7e7e7e" data-width="290" x="0" y="-20" style="font-size:24px;">{val}</text>';
OrgChart.templates.start.plus = "";
OrgChart.templates.start.minus = "";
OrgChart.templates.end = Object.assign({}, OrgChart.templates.start);

OrgChart.templates.process = Object.assign({}, OrgChart.templates.start);
OrgChart.templates.process.size = [200, 80];
OrgChart.templates.process.node = '<rect x="0" y="0" height="{h}" width="{w}" fill="#ce6664"></rect>';
OrgChart.templates.process.field_0 = '<text data-width="200" style="font-size: 20px;" fill="#ffffff" x="100" y="45" text-anchor="middle">{val}</text>';

OrgChart.templates.input = Object.assign({}, OrgChart.templates.process);
OrgChart.templates.input.size = [200, 80];
OrgChart.templates.input.node = '<svg width="200" height="80"><rect  width="165" height="80" x="35" y="0" fill="#f1b57a" transform="skewX(-25)" /></svg>'

OrgChart.templates.decision = Object.assign({}, OrgChart.templates.process);
OrgChart.templates.decision.size = [200, 100];
OrgChart.templates.decision.node = '<path d="M 100,0 L 0,50 L 100,100 L 200,50 L 100,0 Z" fill="#96d1ab" stroke="#96d1ab" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="0 0"/>'
OrgChart.templates.decision.field_0 = '<text data-width="200" style="font-size: 20px;" fill="#ffffff" x="100" y="55" text-anchor="middle">{val}</text>';

Step 4 - Add the tags in the configuration for these templates

var chart = new OrgChart(document.getElementById("tree"), {
...
    tags: {
        start: {
            template: "start"
        },
        end: {
            template: "end"
        },
        process: {
            template: "process"
        },
        input: {
            template: "input"
        },
        decision: {
            template: "decision"
        }
    }
...

Step 5 - Add link field for yes/no after a desicion

    linkBinding: {
        link_field_0: "bool"
    },

Step 6 - Add in the HTML the sidebar elements that you will drag and drop to the chart

<div id="items">
    <div data-name="end" class="item" width="50" height="50">
        <svg width="120" height="60">
            <rect class="element" width="110" x="5" y="5" height="50" rx="30" ry="30" />
        </svg>
    </div>
    <div data-name="input/output" class="item" width="50" height="50">
        <svg width="120" height="70">
            <rect class="element" width="80" height="60" x="40" y="5" transform="skewX(-30)" />
        </svg>
    </div>
    <div data-name="process" class="item" width="50" height="50">
        <svg width="120" height="70">
            <rect class="element" width="100" height="60" x="5" y="5" />
        </svg>
    </div>
    <div data-name="decision" class="item" width="50" height="50">
        <svg width="120" height="70">
            <path class="element" d="M 50,0 L 0,25 L 50,50 L 100,25 L 50,0 Z" stroke-linecap="round"
                stroke-linejoin="round" stroke-dasharray="0 0" />
        </svg>
    </div>
</div>

Step 7 - Add the CSS for these elements

#items {
    width: 20%;
    height: 100%;
    padding-top: 100px;
}

.item {
    margin: auto;
    margin-bottom: 20px;
    text-align: center;
    width: 150px;
    user-select: none;
}
.element {
    fill: #f2f2f2;
    stroke: #F57C00;
    stroke-width: 2;
}

Step 8 - Make these elements draggable

var items = document.querySelectorAll('.item');
for (var i = 0; i < items.length; i++) {
    var item = items[i];
    item.draggable = true;
    item.ondragstart = function (ev) {
        ev.dataTransfer.setData("name", ev.target.getAttribute('data-name'));
    }
};

Step 9 - Use "redraw" event to create the logic for adding the elements to the flowchart

// add these variables that you will use in the "redraw" event:
var currentNode = '';
var clientXY = [0, 0];
var initialized = false;
var chart = new OrgChart(document.getElementById("tree"), {
...
chart.on('redraw', function () {

    var nodeElements = document.querySelectorAll('[data-n-id]');

    for (var i = 0; i < nodeElements.length; i++) {
        var nodeElement = nodeElements[i];
        nodeElement.ondrop = function (ev) {

            ev.preventDefault();
            clientXY = [ev.clientX, ev.clientY];
            var name = ev.dataTransfer.getData("name");
            var item = document.querySelector('[data-name="' + name + '"]');
            var id = OrgChart.randomId();
            var nodeElement = ev.target;
            var tags = [];
            switch (name) {
                case "end": tags = ["end"];
                    break;
                case "input/output": tags = ["input"];
                    break;
                case "process": tags = ["process"];
                    break;
                case "decision": tags = ["decision"]
            }
            while (!nodeElement.hasAttribute('data-n-id')) {
                nodeElement = nodeElement.parentNode;

            }
            var pid = nodeElement.getAttribute('data-n-id');

            var bool = null;

            if (chart.get(pid).name == "decision") bool = "yes";

            chart.addNode({
                id: id,
                pid: pid,
                name: name,
                tags: tags,
                bool: bool
            }, null, true);
        }

        nodeElement.ondragover = function (ev) {
            ev.preventDefault();
        }
    }
});

That's it. Now you can use your flowchart creator. Feel free to comment or ask questions.

Edit in Code

Error

BALKAN Blog

The Latest BALKAN App News and Releases. Latest information on Org Chart JS and Family Tree JS.