2013-10-19 29 views
3

我正在將d3.layout.pack圖形示例here重構爲可重用模塊。但是,根節點不在中心 - 我找不到罪魁禍首。如何在d3.layout.pack圖中居中根節點圓?

這裏是一個的jsfiddle demo of the app

d3.visio.clustering = function module(){ 
var width = 700,//default width 
    height= 500;//default height   
var svg; 
//takes a DOM container or an array of DOM containers 
function exports(_selection){ 
    console.log(_selection); 
    _selection.each(function(_data){ 
     var r = Math.min(width, height) - 10; 

     var x = d3.scale.linear().range([0, r]), 
      y = d3.scale.linear().range([0, r]), 
      node, 
      root; 


     var pack = d3.layout.pack() 
      .size([r, r]) 
      .value(function(d) { return d.size; }); 

     //if the svg element is already defined, don't define it again 
     if(!svg){ 
      svg = d3.select(this).append("svg:svg"); 
     } 

     svg.attr("width", width) 
      .attr("height", height) 
      .append("svg:g") 
      .attr("transform", "translate(" + (width - r)/2 + "," + (height - r)/2 + ")"); 

     node = root = _data; 

     var nodes = pack.nodes(root); 

     svg.selectAll("circle") 
      .data(nodes) 
      .enter().append("svg:circle") 
      .attr("class", function(d) { return d.children ? "parent" : "child"; }) 
      .attr("cx", function(d) { return d.x; }) 
      .attr("cy", function(d) { return d.y; }) 
      .attr("r", function(d) { return d.r; }) 
      .on("click", function(d) { return zoom(node == d ? root : d); }); 

      svg.selectAll("text") 
      .data(nodes) 
      .enter().append("svg:text") 
      .attr("class", function(d) { return d.children ? "parent" : "child"; }) 
      .attr("x", function(d) { return d.x; }) 
       .attr("y", function(d) { return d.y; }) 
       .attr("dy", ".35em") 
       .attr("text-anchor", "middle") 
       .style("opacity", function(d) { return d.r > 20 ? 1 : 0; }) 
       .text(function(d) { return d.name; }); 

      d3.select(window).on("click", function() { zoom(root); }); 

      function zoom(d, i) { 
       var k = r/d.r/2; 
       x.domain([d.x - d.r, d.x + d.r]); 
       y.domain([d.y - d.r, d.y + d.r]); 

       var t = svg.transition() 
        .duration(d3.event.altKey ? 7500 : 750); 

       t.selectAll("circle") 
        .attr("cx", function(d) { return x(d.x); }) 
        .attr("cy", function(d) { return y(d.y); }) 
        .attr("r", function(d) { return k * d.r; }); 

       t.selectAll("text") 
        .attr("x", function(d) { return x(d.x); }) 
        .attr("y", function(d) { return y(d.y); }) 
        .style("opacity", function(d) { return k * d.r > 20 ? 1 : 0; }); 

       node = d; 
       d3.event.stopPropagation(); 
     } 

    }); 
} 

//getter and setter for property width 
exports.width = function(_x){ 
    if(!arguments.length) return width; 
    width = parseInt(_x); 
    return this;//allow method chaining 
} 

//getter and setter for property height 
exports.height = function(_x){ 
    if(!arguments.length) return height; 
    height = parseInt(_x); 
    return this;//allow method chaining 
} 

//getter and setter for property radius = r 
exports.radius = function(_x){ 
    if(!arguments.length) return r; 
    r = parseInt(_x); 
    return this//allow method chaining 
} 

return exports; 
    }; 

    var cluster = d3.visio.clustering() 
     .width(document.getElementById("vis").offsetWidth) 
     .height(document.getElementById("vis").offsetHeight); 

d3.select('#vis') 
    .datum(data) 
    .call(cluster); 

能否請您檢查出了什麼問題?

+0

不確定你的意思。你只是想要在容器中心的大圓圈?您正在附加一個翻譯過的'g'元素,但不使用它 - 只需將其分配給'svg'(http://jsfiddle.net/zau7J/3/)。 –

+0

是的,這正是我所看到的,我看不到問題。謝謝。你能否提出你的答案,我會接受它。再次感謝。 – MedAli

回答

3

在你的代碼的問題是,要追加一個g元素被翻譯正確,但要追加一切以頂級svg,不翻譯。要使其工作,你可以簡單地重新分配svg與頂級g,即

svg = svg.append("g").attr("transform", "translate(" + ... + ")"); 

完整的jsfiddle here