JSFiddle - React, Tailwind, and code Playground

HTML

<html>
    <head>
        <title>Radial Menus Are Cool</title>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
        <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.1.js"></script>
        
        <style>
            body {
                background-color: green;
            }
        </style>
    </head>
    <body>
        <div id="radialcontainer" />
    
        <script>
            var stage = new Kinetic.Stage({
                container: $("#radialcontainer").attr("id"),
                width: 800,
                height: 800
            });
            var layer = new Kinetic.Layer();

            layer.add(MakeRadialContainer({
                " Primitives" : {
                    "Cube" : undefined,
                    "Cylinder" : undefined,
                    "Sphere" : undefined
                },
                " Operators" : {
                    "Add" : undefined,
                    "Subtract" : undefined,
                    "Overlap" : undefined
                },
                "  Topology": {
                    "Building Plan" : undefined,
                    "Floor Plan" : undefined,
                    "Utilities": {
                        "Water" : undefined,
                        "Gas" : undefined,
                        "Electricity" : undefined,
                        "Computer" : undefined,
                        "Security" : undefined
                    },
                    "AI": {
                        "Nav Mesh" : undefined,
                        "Behaviour" : undefined
                    }
                },
                "      Tools": {
                    "   Guns" : {
                        "Sniper" : undefined,
                        "Laser Rifle" : undefined,
                        "Plasma Caster" : undefined
                    },
                    "   Utilities" : {
                        "Manipulator" : undefined,
       ...

JavaScript

function ObjectLength(obj) {
    var datasize = 0;
    for (var key in obj) {
        if (obj.hasOwnProperty(key))
            datasize++;
    }
    return datasize;
};

function FindRoot(node) {
    if (node.Parent)
        return FindRoot(node.Parent);
    return node;
}

function RecursiveTrueForAny(root, func) {
    if (func(root))
        return true;
    
    if (root.Children) {
        for (var i = 0; i < root.Children.length; i++) {
            if (RecursiveTrueForAny(root.Children[i], func))
                return true;
        }
    }
    
    return false;
}

function RecursiveDoForAll(root, func) {
    func(root);
    
    if (root.Children) {
        for (var i = 0; i < root.Children.length; i++) {
            RecursiveDoForAll(root.Children[i], func);
        }
    }
}

function RecursiveDoUpToRoot(node, func) {
    func(node);
    if (node.Parent)
        return RecursiveDoUpToRoot(node.Parent, func);
}

function ForEachChild(node, func) {
    if (node.Children) {
        jQuery.each(node.Children, function(index, value) {
            func(value);
        });
    }
}

function HideNode(node) {
    if (!node.AlwaysVisible)
    {
        node.transitionTo({
            opacity: 0,
            duration: 0.3,
            easing: 'ease-out'
        });
    }
}

function ShowNode(node) {
    node.transitionTo({
        opacity: 1,
        duration: 0.1,
        easing: 'ease-in-out'
    });
}

var wedgeWidth = 97;

function CreatePolygonPoints(innerRadius, outerRadius, angle, rotation) {
    var points = [];
    var innerPointCount = 10;
    for (var i = 0; i <= innerPointCount; i++) {
        points.push(innerRadius * Math.cos(rotation + angle / innerPointCount * i));
        points.push(innerRadius * Math.sin(rotation + angle / innerPointCount * i));
    };
    
    var outerPointCount = 40;
    for (var i = outerPointCount; i >= 0; i--) {
        points.push(outerRadius * Math.cos(rotation + angle / outerPointCount * i));
       ...