如何在 d3.layout.pack 图形中居中根节点圆圈

How to center root node circle in a d3.layout.pack graph?

本文关键字:中居 根节点 图形 pack d3 layout      更新时间:2023-09-26

我正在将这里的d3.layout.pack图形示例重构为可重用的模块。但是,根节点不再位于中心 - 我找不到罪魁祸首。

这是该应用程序的jsfiddle演示:

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

你能检查一下有什么问题吗?

代码中的问题是,您正在附加一个正确翻译的g元素,但您将其他所有内容附加到未翻译的顶级svg。要使其工作,您只需使用顶级g重新分配svg,即

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

在这里完成 jsfiddle。