<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>Singularity Container: ubuntu:12.04 --> ubuntu:12.04 Tree</title>
    <link rel='stylesheet prefetch' href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
    <link rel='stylesheet prefetch' href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <link href='https://fonts.googleapis.com/css?family=Questrial' rel='stylesheet' type='text/css'>

    <style>
        .container-fluid {
            margin: 5px;
        }
        
        body {
            font-family: 'Questrial', sans-serif;
        }
        
        #tree {
            z-index: 10;
        }
        
        #files {
            background-color: #F7F7F7;
            border-radius: 5px;
        }
        
        .filealert {
            margin-bottom: 10px;
            padding: 4px;
        }
        
        .node {
            cursor: pointer;
        }
        
        .node circle {
            fill: none;
            stroke: none;
        }
        
        .node text {
            font: 10px sans-serif;
        }
        
        .link {
            fill: none;
            stroke: #ccc;
            stroke-width: 1.5px;
        }
    </style>

</head>

<body>

    <div class="container-fluid">
        <div class="row">
            <div class="col-md-12">
                <h1>ubuntu:12.04 --> ubuntu:12.04 Tree</h1>
            </div>
        </div>
        <div class="row">
            <div class="col-md-9" id="tree">
                <!-- Visualization tree will be appended here-->
            </div>
            <div class="col-md-3" id="files">
                <h3>Files</h3>
                <div id="filelist">
                    <!-- Files will be shown here-->
                </div>
            </div>
        </div>
    </div>
    <!--end container-->

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
<script>

var files = [];
d3.json("data.json", function(error, root) {
  if (error) throw error;

        var margin = {
                top: 20,
                right: 120,
                bottom: 20,
                left: 120
            },
            width = 960 - margin.right - margin.left,
            height = 800 - margin.top - margin.bottom;

        var i = 0,
            duration = 750,
            root;

        var tree = d3.layout.tree()
            .size([height, width]);

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

        var svg = d3.select("#tree").append("svg")
            .attr("width", width + margin.right + margin.left)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        root.x0 = height / 2;
        root.y0 = 0;

        function collapse(d) {
            if (d.children) {
                d._children = d.children;
                d._children.forEach(collapse);
                d.children = null;
            }
        }

        root.children.forEach(collapse);
        update(root);

        // Add base files to file viewer
        var fileList = files[0]
        if (fileList != null) {
            $.each(fileList, function(e, i) {
                $("#filelist").append('<div class="alert alert-info filealert">' + i + '</div>');
            })
        } else {
            $("#filelist").append('<div class="alert alert-warning filealert">NO FILES</div>');
        }

        d3.select(self.frameElement).style("height", "800px");

        function update(source) {

            // Compute the new tree layout.
            var nodes = tree.nodes(root).reverse(),
                links = tree.links(nodes);

            // Normalize for fixed-depth.
            nodes.forEach(function(d) {
                d.y = d.depth * 180;
            });

            // Update the nodes…
            var node = svg.selectAll("g.node")
                .data(nodes, function(d) {
                    return d.id || (d.id = ++i);
                });

            // Enter any new nodes at the parent's previous position.
            var nodeEnter = node.enter().append("g")
                .attr("class", "node")
                .attr("transform", function(d) {
                    return "translate(" + source.y0 + "," + source.x0 + ")";
                })
                .on("click", click)
                .on("mouseover", showFiles);

            nodeEnter.append("image")
                .attr("x", "-8px")
                .attr("y", "-8px")
                .attr("width", "24px")
                .attr("height", "24px")
                .attr("xlink:href", function(d) {
                    if (d._children != null) {
                        if (d._children.length > 0) {
                            return "https://github.com/vsoch/singularity-python/raw/v2.5/singularity/views/static/img/folder-blue.png";
                        } else {
                            return "https://github.com/vsoch/singularity-python/raw/v2.5/singularity/views/static/img/folder.png";
                        }
                    }
                });

            nodeEnter.append("circle")
                .attr("r", 1e-6)
                .style("fill", function(d) {
                    return d._children ? "transparent" : "lightsteelblue";
                });

            nodeEnter.append("text")
                .attr("x", function(d) {
                    return d.children || d._children ? -10 : 10;
                })
                .attr("dy", ".35em")
                .attr("text-anchor", function(d) {
                    return d.children || d._children ? "end" : "start";
                })
                .text(function(d) {
                    return d.name
                })
                .style("fill-opacity", 1e-6);

            // Transition nodes to their new position.
            var nodeUpdate = node.transition()
                .duration(duration)
                .attr("transform", function(d) {
                    return "translate(" + d.y + "," + d.x + ")";
                });

            nodeUpdate.select("circle")
                .attr("r", 4.5)
                .style("fill", function(d) {
                    return d._children ? "transparent" : "lightsteelblue";
                });

            nodeUpdate.select("text")
                .style("fill-opacity", 1);

            // Transition exiting nodes to the parent's new position.
            var nodeExit = node.exit().transition()
                .duration(duration)
                .attr("transform", function(d) {
                    return "translate(" + source.y + "," + source.x + ")";
                })
                .remove();

            nodeExit.select("circle")
                .attr("r", 1e-6);

            nodeExit.select("text")
                .style("fill-opacity", 1e-6);

            // Update the links…
            var link = svg.selectAll("path.link")
                .data(links, function(d) {
                    return d.target.id;
                })


            // Enter any new links at the parent's previous position.
            link.enter().insert("path", "g")
                .attr("style", function(d) {
                    console.log(d);
                    if (d.target.id==1) {
                        return "stroke:#ccc";
                    } 
                    if (d.target.labels=='added') {
                        return "stroke:#469e30";
                    } 
                    if (d.target.labels == 'removed') {
                        return "stroke:#9e4a52";
                   } 
                })
                .attr("class", "link")
                .attr("d", function(d) {
                    var o = {
                        x: source.x0,
                        y: source.y0
                    };
                    return diagonal({
                        source: o,
                        target: o
                    });
                });

            // Transition links to their new position.
            link.transition()
                .duration(duration)
                .attr("d", diagonal);

            // Transition exiting nodes to the parent's new position.
            link.exit().transition()
                .duration(duration)
                .attr("d", function(d) {
                    var o = {
                        x: source.x,
                        y: source.y
                    };
                    return diagonal({
                        source: o,
                        target: o
                    });
                })
                .remove();

            // Stash the old positions for transition.
            nodes.forEach(function(d) {
                d.x0 = d.x;
                d.y0 = d.y;
            });

        }

        // Toggle children on click.
        function click(d) {
            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update(d);
        }

        // Show files on mouseover
        function showFiles(d) {
            var fileList = files[d.id]
            $("#filelist").text("");
            if (fileList != null) {
                $.each(fileList, function(e, i) {
                    $("#filelist").append('<div class="alert alert-info filealert">' + i + '</div>');
                })
            } else {
                $("#filelist").append('<div class="alert alert-warning filealert">NO FILES</div>');
            }
        }
});
    </script>
</body>

</html>
