Collapsible Tree

by Pedro Moreira

HTML

<section id="collapsible">
    <header>
        <h1>
            <div>
                <svg height="100" width="190">
                    <text style="font-size:80px;font-family:helvetica neue;font-weight: 100;  " fill="rgb(132,132,132)"
                          y="55" x="1">yaap
                    </text>
                    <text style="font-size:15px;font-family:helvetica neue;font-weight: 100;" y="83" x="4"
                          fill="rgb(190,100,39)">understand.plan.predict
                    </text>
                </svg>
            </div>

            <small>
                Pedro Moreira - Collapsible Tree
            </small>
        </h1>
    </header>

    <div class="changes container">
        <header class="text-center">
            <h2>Changes</h2>
        </header>

        <ul>
            <li>Added comments explaining what each part of the code does in order to facilitate future maintenance</li>
            <li>The code was refactored, so that all the code relative to the code relative to the tree is inside the
                function CollapsibleTree
            </li>
            <li>The parameters are now encapsulated and must now be accessed through its functions, such as <i>nodeSize(value)</i>,
                <i>margin(value)</i>,
                etc. These functions automatically call the update method.
            </li>
            <li>The calc of the tree sized is based on the number of nodes being displayed. The ideia of using the
                number of nodes is brought from <a
                        href="http://stackoverflow.com/questions/13103748/dynamically-resize-the-d3-tree-layout-based-on-number-of-childnodes">http://stackoverflow.com/questions/13103748/dynamically-resize-the-d3-tree-layout-based-on-number-of-childnodes</a>
            </li>
            <li>There are two trees being displayed to show that more than one tree can be displayed on the same
                screen
            </li>
            <li>
        ...

CSS

@import url('http://getbootstrap.com/dist/css/bootstrap.css');

#collapsible > header {
    margin-bottom: 16px;
}

#collapsible > header h1 {
    margin: 0;
    text-align: center;
}

#collapsible .changes {
    color: #333;
    margin: 0 auto;
}

#collapsibleTree {
    background: #eee;
    overflow: auto;
}

#collapsibleTree footer {
    margin: 8px;
    padding: 8px;
    border-top: 1px solid #ddd;
}

#collapsibleTree2 {
    overflow: auto;
    height: 200px;
    width: 400px;
    margin-top: 32px;
}

.tooltip {
    position: absolute;
    padding: 4px 8px;
    font: 12px sans-serif;
    background: white;
    border: 0px;
    border: 1px solid blue;
}

.node {
    cursor: pointer;
}

.node circle {
    fill: #fff;
    stroke-width: 1.5px;
}

.node text {
    font: 14px sans-serif;
}

.link {
    fill: none;
    stroke: #ccc;
    stroke-width: 1.5px;
}

JavaScript

/**
 * Pedro Moreira
 *
 * Creates a "class" for CollapsibleTree
 *
 * @param element
 * @constructor
 */
var CollapsibleTree = function (element) {
    /*
     * Creates a variable "ct" (CollapsibleTree) for this object
     * Store the element in which the table is gonna be generated
     * Create a "i" used as a counter for node id generation
     */
    var ct = this;
    ct.element = d3.select(element);
    ct.i = 0;

    /*
     * Instantiate d3 objects
     */
    ct.tree = d3.layout.tree();

    ct.diagonal = d3.svg.diagonal()
        .projection(function (d) {
            return [d.y, d.x];
        });

    /*
     * Create canvas elements
     */
    ct.svg = ct.element.append("svg");
    ct.svgG = ct.svg.append("g");

    /*
     * Size Parameters
     *
     * Each parameter has its private variable and methods that update the private variable
     * and update the visual component
     */
    ct._nodeSize = 32;
    ct.nodeSize = function (value) {
        if (value) {
            ct._nodeSize = value;
            ct.update();
        }
        return ct._nodeSize;
    };

    ct._width = 0;
    ct._height = 0;

    /*
     * Margin Parameters
     *
     * Each parameter has its private variable and methods that update the private variable
     * and update the visual component
     */
    ct._margin = {top: 20, right: 120, bottom: 20, left: 120};
    ct.margin = function (value) {
        ct._margin.top = value;
        ct._margin.right = value;
        ct._margin.bottom = value;
        ct._margin.left = value;
        ct.update();
    };

    ct.marginTop = function (value) {
        if (value) {
            ct_margin.top = value;
            ct.update();
        }
        return value;
    };

    ct.marginBottom = function (value) {
        if (value) {
            ct_margin.bottom = value;
            ct.update();
        }
        return value;
    };

    ct.marginRight = function (value) {
        if (value) {
            ct_margin.right =...