JSFiddle - React, Tailwind, and code Playground

by Shashank Srivastava

HTML

<div id="holder"></div>

JavaScript

var edge_set = [
        ['start','new'],
        ['new', 'qualified'],
        ['new', 'closed'],
        ['qualified', 'engaged'],
        ['qualified', 'closed'],
        ['engaged', 'cold'],
        ['engaged', 'closed'],
        ['cold', 'engaged'],
        ['cold', 'closed'],
    ],    
    nodes = [],
    r = Raphael("holder", 500, 300),
    initX = 50,
    initY = 150,
    node_radius = 30,
    nodes_info = {},
    
    get_nodes = function() {
        for(var i = 0; i < edge_set.length; i++) {
            var pair = edge_set[i];
            for(var j = 0; j < 2; j++) {
                var find = 0;
                for(var k = 0; k < nodes.length; k++) {
                    if(nodes[k] === pair[j]) {
                        find++;
                        break;
                    }
                }
                if(find === 0) nodes[nodes.length] = pair[j];
            }
        }
    },
    
    connect = function (node1, node2) {
        nodes_info[node2].connectedToX += 1;
        var swapped = false;
        if ( nodes.indexOf(node1) > nodes.indexOf(node2)) {
            var temp = node1;
            node1 = node2;
            node2 = temp;
            swapped = true;
        }
    
        var x1 = nodes_info[node1].x,
            y1 = nodes_info[node1].y,
            x2 = nodes_info[node2].x,
            y2 = nodes_info[node2].y,
            path;
        
        if(swapped) {
            path = r.path([
                'M', x1, y1 + node_radius,
                'q', (x2 - x1) / 2, (((x2 - x1) / 80) * 50), (x2 - x1), 0
            ]).attr({
                'stroke-width': 3,
                'arrow-start': 'open-midium-midium'
            });
        }
        else {
            path = r.path([
                'M', x1, y1 - node_radius,
                'q', (x2 - x1) / 2, -(((x2 - x1) / 80) * 50), (x2 - x1), 0
            ]).attr({
                'stroke-width': 3,
                'arrow-end': 'open-midium-midium'
            });
        }

	 ...