Frage

I am refactoring the d3.layout.pack graph example here into a reusable module. However, the root node is no longer in the center - I couldn't find the culprit.

Here is a 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);

Could you please check what's wrong?

War es hilfreich?

Lösung

The problem in your code is that you're appending a g element that is correctly translated, but you're appending everything else to the top level svg, which is not translated. To make it work, you can simply reassign svg with the top level g, i.e.

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

Complete jsfiddle here.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top