替换svg元素

时间:2015-05-29 04:38:18

标签: javascript svg d3.js

我使用D3渲染可折叠树。



(function () {

    Ext.define("d3.widgets.Treeview", {
        extend: 'Ext.Panel',
        alias: 'widget.d3_treeview',
        tree: '',
        svg: '',
        duration: 1000,
        diagonal: '',
        i: 0,
        me: null, 


        constructor: function (config) {
            console.log('1) Tree View Constructor called');
            this.callParent([config]);
            console.log("Treeview - constructor FINISH");
            me = this;
        },

        initComponent: function () {
            console.log('2) Tree View initComponent called');
            this.on('afterRender', function(){
                this.loadScript(this.onD3Loaded, this);
            }, this);
            this.callParent(arguments);
        },

      /*  afterRender: function () {
            console.log('4) Tree View afterRender called');
            this.loadScript(this.onD3Loaded, this);
            return this.callParent(arguments);
        }, */

        loadScript: function (callback, scope) {
            console.log('5) loadScript called');
            Ext.Loader.injectScriptElement('http://d3js.org/d3.v3.js', this.onLoad, this.onError, this);
            console.log('Treeview - D3 script loaded ');

        },

        onError: function () {
            console.log('Treeview On Error');
        },

        onLoad1: function () {
            console.log('Treeview On onLoad1');
        },

        onD3Loaded: function () {
            console.log('Treeview onD3Loaded - D3 script load callback');
        },


        onLoad: function () {

            console.log('Tree View Store --------------------------- ');
           var data = [{ "name": "Orders",     "parent": ""},
              { "name": "Order-No: ON57677",     "parent": "Orders"},
              { "name": "Vehicle-No: VN33255",     "parent": "Order-No: ON57677"},
              { "name": "Make: BMW",     "parent": "Vehicle-No: VN33255"},
              { "name": "Model: Z4",     "parent": "Vehicle-No: VN33255"},
              { "name": "VIN: 52465236",     "parent": "Vehicle-No: VN33255"},
              { "name": "Vehicle-No: VN22345",     "parent": "Order-No: ON57677"},
              { "name": "Make: Chevrolet",     "parent": "Vehicle-No: VN22345"},
              { "name": "Model: SS 454",     "parent": "Vehicle-No: VN22345"},
              { "name": "VIN: 32659852",     "parent": "Vehicle-No: VN22345"},
              { "name": "Vehicle-No: VN11234",     "parent": "Order-No: ON57677"},
              { "name": "Make: Ford",     "parent": "Vehicle-No: VN11234"},
              { "name": "Model: Fiesta",     "parent": "Vehicle-No: VN11234"},
              { "name": "VIN: 45218569",     "parent": "Vehicle-No: VN11234"}];


            var dataMap = data.reduce(function (map, node) {
                map[node.name] = node;
                return map;
            }, {});
            console.log('dataMap --' + dataMap);

            var treeData = [];
            data.forEach(function (node) {
                // add to parent
                var parent = dataMap[node.parent];
                if (parent) {
                    // create child array if it doesn't exist
                    (parent.children || (parent.children = []))
                    // add node to child array
                    .push(node);
                } else {
                    // parent is null or missing
                    treeData.push(node);
                }
            });
            console.log('treeData --' + treeData);
            // ************** Generate the tree diagram  *****************
            var margin = {
                top: 20,
                right: 120,
                bottom: 20,
                left: 120
            },
            width = 960 - margin.right - margin.left,
                height = 500 - margin.top - margin.bottom;

        //    var i = 0;
            i=0;
            // var duration = 1000;
            duration = 1000;
            //	var tree = d3.layout.tree()
            tree = d3.layout.tree()
                .size([height, width]);

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

            d3.select("#treesvg").remove();
            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 + ")")
                .attr("id","treesvg");

            root = treeData[0];

            this.update(root);

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


        },
        update: function (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", function (d) {
                if (d.children) {
                    d._children = d.children;
                    d.children = null;
                } else {
                    d.children = d._children;
                    d._children = null;
                }
                me.update(d);
            });

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

            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 ? "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.
        /*	click: function(d) {
	  if (d.children) {
		d._children = d.children;
		d.children = null;
	  } else {
		d.children = d._children;
		d._children = null;
	  }
	  update(d);
	},
*/
        onRender: function (ct, position) {
            console.log('3) onRender called ');
            this.callParent(arguments);
        },


        setValue: function (value) {
            console.log('Set Value called');
            this.callParent(arguments)
        },

        getValue: function () {
            console.log('Get Value called');
            return '';
        },



    });

})();

Ext.create('d3.widgets.Treeview', {
    renderTo : Ext.getBody()
});

.node circle {
    fill: #fff;
    stroke: steelblue;
    stroke-width: 3px;
}
.node text {
    font: 12px sans-serif;
}
.link {
    fill: none;
    stroke: #ccc;
    stroke-width: 2px;
}

<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="http://cdn.sencha.com/ext/gpl/4.2.0/ext-all.js" charset="utf-8"></script>


<body>
    <div id="tree"></div>
</body>
&#13;
&#13;
&#13;

这个D3树在Ext JS应用程序中呈现。根据用户选择的订单号,显示树的相关部分。例如,如果&#39;订单号:ON31225&#39;然后选择&#39; Order-No:ON31225&#39;并显示了它的相关项目。

当用户第一次选择订单时,一切都按预期工作。源中还有一个svg元素。

Tree for 1st Order

目标是当用户点击第二个订单时,图表会刷新并显示新订单号。

但是,现在,它最终会创建另一个svg元素并继续显示旧图。

When 2nd Order is selected

我需要一种方法来删除旧的svg元素并用新的svg元素替换它,这样每当用户选择OrderNumer时,就会显示该Order的树。

有人可以帮忙吗?

谢谢

1 个答案:

答案 0 :(得分:2)

替换此代码:

       d3.select("#treesvg").remove();
       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 + ")")
            .attr("id","treesvg");

以下内容:

       svg = d3.select("#tree").selectAll("svg")
            .data([treedata]);

       svg.enter()
            .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 + ")")
            .attr("id","treesvg");