Загрузка изображения до загрузки внешних данных json для складного дерева -d3.js

Я использую пример складного дерева d3.js. Мне удалось загрузить внешние данные json при щелчке узла. Теперь я хочу показать изображение предварительной загрузки до тех пор, пока данные json не будут получены с сервера рядом с соответствующим узлом, где я щелкнул.

Я добавил тег div во все узлы и имел img src для gif во всех добавленных тегах div. Я не мог добиться решения.

Ниже мой пример кода:

<!DOCTYPE html>
<html>
<title>Gateways - CollapsibleTree</title>
<meta charset="utf-8">
<style>
    .node {
        cursor: pointer;
    }

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

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

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

    a:hover {
        text-decoration:underline 
    }
</style>
<body>
    <script src="d3.min.js"></script>
    <script src="jquery.min.js"></script>
    <script>
        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("body").append("svg")
            .attr("id", "treeChart")
            .attr("width", width + margin.right + margin.left)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

        d3.json("http://localhost:8080/demo/gateways.json", function(error, flare) {
            root = flare;
            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);
        });

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

        function update(source) {

            $('div#loading1').hide();
            // 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);


            nodeEnter.append("circle")
                .attr("r", 15)
                .style("fill", function(d) {
                    return d._children ? "lightsteelblue" : "#fff";
                });

            nodeEnter.append("svg:image")
                .attr("class", "circle")
                .attr("xlink:href", "logo.png")
                .attr("x", "-8px")
                .attr("y", "-8px")
                .attr("width", "16px")
                .attr("height", "16px");

            var z = 0,
                z2 = 0;

            var spinner = nodeEnter.append("div")
                .attr("top", function(d) {
                    return "15%";
                })
                .attr("left", function(d) {
                    return "50%";
                })
                .attr("width", "16px")
                .attr("height", "16px")
                .attr("position", "absolute")
                .attr("id", function(d) {
                    return "loading" + z++;
                });

            var spinimage = spinner.append("img")
                .attr("src", "loading.GIF")
                .attr("alt", "Processing");

            nodeEnter.append("a")
                .attr("xlink:href", function(d) {
                    return d.url;
                })
                .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 || d.children ? "lightsteelblue" : "#fff";
                });

            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("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) {
            $('div#loading1').show();

            // made a time out to check the preload
            setTimeout(function() {
                $.getJSON("http://localhost:8080/demo/gateways.json", function(addJson) {

                    // on node click get whole json data and parse the data and apppend children of the 
                    //corresponding parent
                    var childObj = getObjects(addJson, 'name', d.name);

                    var len = (childObj[0].children).length;

                    function collapse2(k) {
                        if (k.children) {
                            k._children = k.children;
                            k._children.forEach(collapse2);
                            k.children = null;
                        }
                    }

                    childObj[0].children.forEach(collapse2);

                    var newnodes = tree.nodes(childObj[0].children).reverse();


                    if (d.children) {
                        d._children = newnodes[0];
                        d.children = null;
                    } else {
                        d.children = newnodes[0];
                        d._children = null;
                    }

                    update(d);

                });

                //do something special

            }, 3000);
        }

        function getObjects(obj, key, val) {
            var objects = [];
            for (var i in obj) {
                if (!obj.hasOwnProperty(i)) continue;
                if (typeof obj[i] == 'object') {
                    objects = objects.concat(getObjects(obj[i], key, val));
                } else if (i == key && obj[key] == val) {
                    objects.push(obj);
                }
            }
            return objects;
        }
    </script>
</body>
</html>

person Sakthi Gurunathan    schedule 22.04.2015    source источник


Ответы (1)


Вы должны использовать тег SVG foreignObject, чтобы добавить содержимое, отличное от SVG, в svg. Вот пример кода

svg.append("foreignObject")
     .attr("width", 100)
     .attr("height", 100)
     .append("xhtml:div")
     .style("color", "red")
     .html("Object in SVG");

Подробнее о посторонних объектах читайте здесь

person Gilsha    schedule 22.04.2015
comment
Большое спасибо :) теперь он работает нормально :) можете ли вы помочь мне с этим вопросом stackoverflow.com/questions/29739838/ - person Sakthi Gurunathan; 23.04.2015
comment
Гилша Не могли бы вы помочь мне с этой проблемой? stackoverflow.com/questions/30593455/ - person Sakthi Gurunathan; 02.06.2015