2015-05-29 148 views
2

我使用D3渲染可折叠的树。替换svg元素

(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; 
 
      // \t var tree = d3.layout.tree() 
 
      tree = d3.layout.tree() 
 
       .size([height, width]); 
 

 
      // \t 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. 
 
     /* \t click: function(d) { 
 
\t if (d.children) { 
 
\t \t d._children = d.children; 
 
\t \t d.children = null; 
 
\t } else { 
 
\t \t d.children = d._children; 
 
\t \t d._children = null; 
 
\t } 
 
\t update(d); 
 
\t }, 
 
*/ 
 
     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>

这D3树的Ext JS的应用程序中呈现。根据用户选择的订单号,显示树的相关部分。例如,如果选择了“订货号:ON31225”,则会显示“订货号:ON31225”,并显示相关项目。

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

Tree for 1st Order

的目标是,当用户点击一个第二顺序上,该图是刷新,并与新的顺序号显示。

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

When 2nd Order is selected

我需要一种方法来删除旧的SVG元素,并用新的SVG元素替换,这样,每当用户选择OrderNumer,则显示的树该订单。

有人可以帮忙吗?

谢谢

+0

更新的代码首先删除SVG元素,然后添加它。但是,我仍然可以在Ext JS应用程序中看到两个svg元素 – kayasa

回答

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");